0

Wondering if anyone can assist me or just know if this can be done. I have a custom Adapter for a ListView where I have some textviews which are always present and correspond with textviews in an xml layout that is being inflated by the adapter for each row. In addition to these textviews I also need to add some textviews programatically for each row in the ListView. Each row may have a different number of textviews that need to be programatically added. When I do so, each time I scroll up and down the listview, the programatically added textviews are replicated and added to the other ones in the row, so if I scoll up and down a few times I just have a bunch of duplicate textboxes in each row. Within the getView method I have the following code to pull in the dynamic info and add the textboxes:

    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);

        }

Thanks for checking this out.

Jaz
  • 371
  • 1
  • 6
  • 20

1 Answers1

0

Since the containers that scroll out of the screen are cached and reused, you add one more textview to the container each time you call your getView().

You could count the children of your container, iterate over your list and add only, if the childCount was reached

if the childcount wasn't reached yet, you count through the rest (useless textviews) and call setVisibility(View.GONE)

that way you will sooner or later reach a point were almost all containers have the same childcount and no new instances will be added

some sample code, that i didn't test right now:

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++
}

edit: since you don't need to set the textsize everytime,.i moved the call

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

inside the else statement

Christian R.
  • 1,528
  • 9
  • 16
  • Thanks Christian, I was hoping to get away from a counter of child views but looks like that is the most likely solution. Seems anything along the lines of nested listviews is not possible. Wasn't sure if there was a way to keep from calling getview each time the roll is shown or if there was a way to retain the listview in memory efficiently. Thanks – Jaz Jul 06 '13 at 18:46
  • @Jaz as you said "nested listview" google pointed me to this question: http://stackoverflow.com/questions/3135112/android-nested-listview and to the `ExpandableListAdapter` with the `ExpandableListView` - perhaps you can get it done that way and i will edit my answer – Christian R. Jul 06 '13 at 23:23
  • Christian, I did something similar to the solution found on the link you provided. Instead of inflating the layout for row I added the layout and once and then looped through the records and added them to the layout. Before the loop I call removeAllViews() on the linearLayout view which contains all the programatically added views. Seems to work ok. Thanks for the help. – Jaz Jul 08 '13 at 22:46
  • no problem, as long as you don't inflate your rows in every call of getView() and use cached/pooled rows instead, you should be fine – Christian R. Jul 08 '13 at 22:55