Программно добавить текстовые представления в пользовательский адаптер на getView

Интересно, может ли кто-нибудь помочь мне или просто знает, можно ли это сделать. У меня есть собственный адаптер для ListView, где у меня есть некоторые текстовые представления, которые всегда присутствуют и соответствуют текстовым представлениям в макете xml, который наполняется адаптером для каждой строки. В дополнение к этим текстовым представлениям мне также нужно программно добавить некоторые текстовые представления для каждой строки в ListView. Каждая строка может иметь разное количество текстовых представлений, которые необходимо добавить программно. Когда я это делаю, каждый раз, когда я прокручиваю список вверх и вниз, программно добавленные текстовые представления реплицируются и добавляются к другим в строке, поэтому, если я прокручиваю вверх и вниз несколько раз, у меня просто есть куча повторяющихся текстовых полей в каждый ряд. В методе getView у меня есть следующий код для получения динамической информации и добавления текстовых полей:

    Set recordDeailList = item.getRecordDetailList().keySet();
    Iterator<String> iterator = recordDeailList.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            String value = item.getRecordDetailList().get(key);

            TextView textView = new TextView(RecordsFragment.this.getActivity());
            textView.setText(key + ": " + value);
            textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10.5f);

  );

            container.addView(textView);

        }

Спасибо, что проверили это.


person Jaz    schedule 06.07.2013    source источник


Ответы (1)


Поскольку контейнеры, которые прокручиваются за пределы экрана, кэшируются и используются повторно, вы добавляете еще одно текстовое представление в контейнер каждый раз, когда вызываете метод getView().

Вы можете подсчитать дочерние элементы вашего контейнера, перебрать список и добавить только в том случае, если достигнуто значение childCount.

если количество детей еще не достигнуто, вы считаете остальные (бесполезные текстовые просмотры) и вызываете setVisibility (View.GONE)

таким образом, вы рано или поздно достигнете точки, когда почти все контейнеры имеют одинаковую дочернюю учетную запись, и новые экземпляры не будут добавлены.

некоторый пример кода, который я не тестировал прямо сейчас:

Set recordDeailList = item.getRecordDetailList().keySet();
Iterator<String> iterator = recordDeailList.iterator();
int i = 0;
int childCount = container.getChildCount();
while (iterator.hasNext()) {
    String key = iterator.next();
    String value = item.getRecordDetailList().get(key);

    TextView textView;
    if (i < childCount) {
        //reuse existing textview
        textView = container.getChildAt(i);
    }
    else {
        // create new TextView and add
        textView = new TextView(RecordsFragment.this.getActivity());
        container.addView(textView);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10.5f);
    }
    textView.setText(key + ": " + value);


    i++;
}
while(i < childCount) {
    //hide useless children
    container.getChildAt(i).setVisibility(View.GONE);
    i++
}

редактировать: поскольку вам не нужно каждый раз устанавливать размер текста, я переместил вызов

textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10.5f);

внутри оператора else

person Christian R.    schedule 06.07.2013
comment
Спасибо, Кристиан, я надеялся уйти от счетчика детских просмотров, но похоже, что это наиболее вероятное решение. Кажется, что-то вроде вложенных списков невозможно. Не был уверен, есть ли способ избежать вызова getview каждый раз, когда отображается список, или есть ли способ эффективно сохранить список в памяти. Спасибо - person Jaz; 06.07.2013
comment
@Jaz, как вы сказали, вложенный список Google указал мне на этот вопрос: stackoverflow.com/questions /3135112/android-nested-listview и ExpandableListAdapter с ExpandableListView - возможно, вы сможете сделать это таким образом, и я отредактирую свой ответ - person Christian R.; 07.07.2013
comment
Кристиан, я сделал что-то похожее на решение, найденное по предоставленной вами ссылке. Вместо того, чтобы раздувать макет для строки, я добавил макет и один раз, а затем перебрал записи и добавил их в макет. Перед циклом я вызываю removeAllViews() для представления linearLayout, которое содержит все программно добавленные представления. Кажется, работает нормально. Спасибо за помощь. - person Jaz; 09.07.2013
comment
нет проблем, пока вы не раздуваете свои строки при каждом вызове getView() и вместо этого используете кэшированные/объединенные строки, все должно быть в порядке - person Christian R.; 09.07.2013