CheckedTextView disappears when scroll in ListView

左心房为你撑大大i 提交于 2020-01-16 18:17:47

问题


I have custom ListView. I'm using array adapter to fill my ListViews rows. It worked perfectly. When I select the ListView row, my checkedtextview become visible. After scrolling my checked situation disapper. How can i remember my checks ?

Thanks in helpings.

Here my Adapter

package test.cbsmobil.ibb;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.TextView;

import java.util.ArrayList;


public class ListViewItemsAdapter extends ArrayAdapter<Item> {

private Context context;
private ArrayList<Item> items;
private LayoutInflater vi;
private int resLayout;
private CheckedTextView ctv;
private int selectedIndex;


public ListViewItemsAdapter(Context context, ArrayList<Item> items) {
    super(context, 0, items);
    this.context = context;
    this.items = items;
    vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    selectedIndex = -1;

}




@Override
public long getItemId(int position) {

    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;


    final Item i = items.get(position);
    if (i != null) {
        if (i.isSection()) {
            ListViewItemsSection si = (ListViewItemsSection) i;
            v = vi.inflate(R.layout.list_item_section, null);

            v.setOnClickListener(null);
            v.setOnLongClickListener(null);
            v.setLongClickable(false);

            final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text);
            sectionView.setText(si.getTitle());
        } else {

            ListViewItems ei = (ListViewItems) i;
            v = vi.inflate(R.layout.list_item_entry,null);

            final TextView title = (TextView) v.findViewById(R.id.list_item_entry_title);

            if (title != null)
                title.setText(ei.title);

        }
    }

    return v;

}


 }

Here is my MainActivity; Let me explain this activitys code block. layerlist is my ListView. I use choice mode multiple for multiple selection in ListView.

layerlist.setAdapter(adapter);
    layerlist.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);

    layerlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if(!items.get(position).isSection()){


                    ListViewItems item = (ListViewItems) items.get(position);
                    //adapter.setSelectedIndex(position);
                    Log.d("ListView", "Position " + item.toString());
                    //View v = layerlist.getChildAt(position);
                    View v = getViewByPosition(position,layerlist);
                    CheckedTextView ctv = (CheckedTextView) v.findViewById(R.id.ctv);



                    if (!ctv.isChecked()) {
                        ctv.setChecked(true);
                        Log.d("Checked", "Açıldı" + " " + ctv.isChecked());

                    } else {
                        ctv.setChecked(false);
                        Log.d("Checked", "Kapandı" + " " + ctv.isChecked());
                    }


           }
        }
    });



    return rootView;
}

private View getViewByPosition(int pos, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;

    if (pos < firstListItemPosition || pos > lastListItemPosition ) {
        return listView.getAdapter().getView(pos, null, listView);
    } else {
        final int childIndex = pos - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}

回答1:


You should use use the "view holder" design pattern as described by developer.android.com and explained with details on this post.

The most important here is:

  1. Create the ViewHolder class;
  2. Store the ViewHolder instance in a tag if the convertView is null;
  3. Restore the ViewHolder instance from a tag if it is not.

That is my Adapter's code:

package br.com.inovant.pm;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;

import java.util.List;

public class ContactsAdapter extends ArrayAdapter<CheckedContact>{

    public ContactsAdapter(Context context, List<CheckedContact> contacts) {
        super(context, 0, contacts);
    }

    static class ViewHolder {
        protected CheckedTextView checkedTextView;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(android.R.layout.select_dialog_multichoice, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.checkedTextView = (CheckedTextView) convertView.findViewById(android.R.id.text1);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        final CheckedContact checkedContact = getItem(position);

        final CheckedTextView checkedTextView = viewHolder.checkedTextView;
        checkedTextView.setText(checkedContact.getContact().getDisplayName());
        checkedTextView.setChecked(checkedContact.isChecked());
        return convertView;
    }

    @Override
    public long getItemId(int position) {
        return getItem(position).getContact().getId().hashCode();
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }
}



回答2:


I was got same problem so, i had used following methods in my custom adapter, i got solution.

Add following methods inside your ListViewItemsAdapter:

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

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {

        return getCount();
    }

Try it, you will also get solution.




回答3:


Android's ListView recycles all its individual views, that is, when a list item is scrolled off of the screen its view is recycled to be used by the one that just scrolled into the visible screen area. Now when an older list item is scrolled back into view it gets some other recycled view to draw itself in. Because of this the checkmark is lost or any data that was changed / updated, for that matter.

The solution to this is you save your changes in the list item, in your case - ListViewItems. Say you have a flag boolean isChecked = false in the class definition of ListViewItems and in the onItemClick where you call the setChecked method, set isChecked = true This will help you persist the check mark.

Hope it helps.



来源:https://stackoverflow.com/questions/28714738/checkedtextview-disappears-when-scroll-in-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!