ListView items change when scrolling

I am filling the list, here is the code:

ArrayAdapter<CharSequence> listAdapter1;
ListView toc;
toc=(ListView)findViewById(R.id.listView1);
listAdapter1=ArrayAdapter.createFromResource(Glossary.this,R.array.arabicalphabet,R.layout.glossarysimplerow);
toc.setAdapter(listAdapter1);

      

I am setting a list selector in the xml file, when clicking on any item in the list, its color changes to blue to show that it is selected. The problem is that when I scroll through the list, the selection will change, for example if I have a list filled out from A to Z. If I select the letter "B" and I scroll many times, I get the letter "M" selected .. . Any help please

+3


source to share


3 answers


yah, I discovered this issue a week ago, the reason is "when you view the listview, the first display item is at position 0", so your change will affect the new item.

My decision:

1). Using ScrollView

with LinearLayout

inside it instead of usingListView

2). Add the array TextView[]

to LinearLayout

.

code:



Markup:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="2dp"
    android:layout_marginRight="2dp"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp">
    <LinearLayout
        android:id="@+id/ll_inflater"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>
</ScrollView>

      

Java:

int prePos = -1;
int sdk = android.os.Build.VERSION.SDK_INT;
LinearLayout ll_inflater = (LinearLayout)findViewById(R.id.ll_inflater);
TextView[] tv_Subs = new TextView[array.size()];//arrary is arrayData
for(int i = 0; i < array.size(); i++){
    tv_Subs[i] = new TextView(getApplication());
    tv_Subs[i].setLines(3);
    tv_Subs[i].setTextColor(getResources().getColor(R.color.sub_color));
    tv_Subs[i].setGravity(Gravity.CENTER);

    if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
        //set default background color
    } else {
        //set default background color
    }

    tv_Subs[i].setText(array.get(i));
    ll_inflater.addView(tv_Subs[i], i, new  ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
    final int finalI = i;
    tv_Subs[i].setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(prePos !=-1){
                 //change background of preposition tv_Subs[prePost] to default color
            }
            //change background color here
            prePos = finalI;
        }
    });
}

      

+1


source


In Android, children AdapterView

like have ListView

caching enabled, so when the user scrolls, items from the screen go out of memory, getView()

called for items to be displayed in the view after scrolling.

View

that is passed in the method getView()

is reused and has the properties previously visible View

in ListView

. This improves performance ListView

, but requires checking all possible conditions and resetting all view properties retrieved from getView()

.

Now the generic ArrayAdapter

one you used has no implementation of changing colors on click, and it has no way to keep a record of the view already clicked. Thus, when scrolling, the results are unexpected.



You can implement your own class Adapter

like below and it will solve your problem:

public class MyAdapter extends ArrayAdapter<String> {
    Context context;
    List<String> lstStrings;
    List<Boolean> isClicked;

    public MyAdapter (Context context, int resource, List<String> lstStrings) {
        super(context, resource, lstStrings);
        this.context = context;
        lstStrings = lstStrings;
        isClicked = new ArrayList<>(Arrays.asList(new Boolean[lstStrings.length]));
        Collections.fill(isClicked, new Boolean(false));
    }   

    @Override
    public int getCount() {
        return lstStrings.size();
    }

    @Override
    public String getItem(int position) {
        return lstStrings.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        if (convertView == null)
            convertView = LayoutInflater.from( context).inflate(R.layout.list_item, null);

        TextView txtTheText = (TextView) convertView.findViewById(R.id.txtTheText);

        txtTheText .setText(lstStrings.get(position));

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isClicked.set(!isClicked.get(position));
            }
        });

        if (isClicked.get(position))
            convertView.setBackgroundColor(Color.argb(255, 255, 0, 0));
        else
            convertView.setBackgroundColor(Color.argb(255, 0, 0, 255));

        return convertView;
    }
}

      

0


source


I have permission. When you click one item, write it down position

. Then override onConfigurationChanged(Configuration newConfig)

and call ListView.setSelection(position)

.

0


source







All Articles