简体   繁体   English

带有复选框的Android ListView在滚动时会松散选中的项目

[英]Android ListView with checkboxes loose checked items when scrolling

I'm facing with one problem, it's about disappearing checked items in listview when I'm scrolling the list and I don't know what to do. 我面临一个问题,这是关于在滚动列表时不知道要在列表视图中选中的项目,我不知道该怎么办。

Here is my code of custom adapter: 这是我的自定义适配器的代码:

public class SPCKontrola extends Activity {
ArrayList<Integer> yourSelectedItems= new ArrayList<Integer>();

@Override
        public void onResume() {
            super.onResume();

            yourSelectedItems.clear();

        }
}

public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;

        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

        public int getCount() {
            return MyArrList.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
            Chk.setTag(MyArrList.get(position).get("RbMjere"));



Chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {               
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if(isChecked){
                            yourSelectedItems.add(position);
                        }else{
                            if(yourSelectedItems.contains(position)){                                               
                                yourSelectedItems.remove((position));                                   
                            }
                        }
                    }
                    });


            return convertView;

        }
}

What should I change or add in code? 我应该更改或添加什么代码? I have found some examples but I can't reuse non of them and implement in my code :/ 我已经找到了一些示例,但是我不能重用它们并在我的代码中实现:/

for this you have to maintain an array variable yourSelectedItems[] for storing the view positions that you have checked..and put a condition like this in your getView() method.. 为此,您必须维护一个数组变量yourSelectedItems[]用于存储已检查的视图位置。并将这样的条件放入getView()方法中。

if(yourSelectedItems.contains((position))){
    check.setChecked(true);
}else{
    check.setChecked(false);
}

you can manage you array by writing this method in your getView() .. 您可以通过在getView()编写此方法来管理数组。

 check.setOnCheckedChangeListener(new OnCheckedChangeListener() {               
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(isChecked){
            yourSelectedItems.add(position);
        }else{
            if(yourSelectedItems.contains(position)){                                               
                yourSelectedItems.remove((position));                                   
            }
        }
    });

尝试使用带有复选框的listview这个示例: http : //lalit3686.blogspot.in/2012/06/today-i-am-going-to-show-how-to-deal.html

To avoid the problems with CheckBoxes in a ListView you can take a Boolean array initialized false in the beginning and then making true the corresponding position in the array where checkbox is checked in the ListView. 为避免ListView中CheckBoxes出现问题,您可以在开始时采用一个初始化为false的布尔数组,然后使该数组在ListView中选中复选框的位置变为true。 This will not cause a trouble in checked state of checkboxes when you move forward and backward in your application or scroll the ListView.You can check sample code here: 在应用程序中前后移动或滚动ListView时,这不会在复选框的选中状态造成麻烦。您可以在此处检查示例代码:

Android checkbox multiselected issue Android复选框多选问题

This happened to me and i solve this wtih, 这发生在我身上,我解决了这个问题,

1.Create a global boolean arraylist and fill it with MyArrList.size() on constructor. 1.创建一个全局布尔数组列表,并在构造函数上填充MyArrList.size()。

2.When you changed checkbox value set arratlist with views index. 2.当您更改复选框值时,设置带有视图索引的arratlist。

3.Change this: 3.更改此:

 CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
 Chk.setTag(MyArrList.get(position).get("RbMjere"));

with this: 有了这个:

 CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
 Chk.setTag(MyArrList.get(position).get("RbMjere"));
 Chk.setChecked(commentTexts.get(position));

change your getview() with this one... 用这个改变你的getview()...

     public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);


             if(yourSelectedItems.contains((position))){
                Chk.setChecked(true);
             }else{
                Chk.setChecked(false);
             }

            Chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {               
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if(isChecked){
                            yourSelectedItems.add(position);
                        }else{
                            if(yourSelectedItems.contains(position)){                                               
                                yourSelectedItems.remove((position));                                   
                            }
                        }
                    }
                    });


            return convertView;

        }

如果您在listView.onItemSelectedListner中使用了getView,您将面临这个问题。listView不会将每个对象都放在不同的视图中,这就是为什么当您调用getView(2)时它将在屏幕上返回列表的第二个对象的视图而不是列表第二个对象的视图 ...您必须使用类中的一些布尔值或复选框自己实现它

I think I get something... Instead of Chk.setOnCheckedChangeListener() I've changed to Chk.setOnClickListener(new OnClickListener() 我想我得到了一些东西...而不是Chk.setOnCheckedChangeListener()我改为Chk.setOnClickListener(new OnClickListener()

public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;


        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

        public int getCount() {
            return MyArrList.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            final CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);


            if(yourSelectedItems.contains((position))){
                Chk.setChecked(true);
             }else{
                Chk.setChecked(false);
             }

            Chk.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    if (Chk.isChecked())
                    {
                         yourSelectedItems.add(position);
                    } else
                    {
                        if(yourSelectedItems.contains(position)){                                               
                            yourSelectedItems.remove((position));                                   
                        }
                    }

                }
            });


            return convertView;
        }

 }

Now it works fine when scrolling up/down. 现在,当向上/向下滚动时,它可以正常工作。 But there is another problem and i'm little bit confused. 但是还有另一个问题,我有点困惑。 When scrolling and randomly check/uncheck items program crashes and these errors I get: 当滚动并随机检查/取消选中项目时,程序崩溃,并且出现以下错误:

FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
at java.util.ArrayList.remove(ArrayList.java:399)
at com.dem.spckontrola.SPCKontrola$SPCMjereAdapter$1.onClick(SPCKontrola.java:830)
at android.view.View.performClick(View.java:4084)
at android.widget.CompoundButton.performClick(CompoundButton.java:100)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method

)

Ok. 好。 I solved this by adding yourSelectedItems.remove(yourSelectedItems.indexOf(position)); 我通过添加 yourSelectedItems.remove(yourSelectedItems.indexOf(position)); 解决了这个问题 yourSelectedItems.remove(yourSelectedItems.indexOf(position));

So now the correct solution is: 所以现在正确的解决方案是:

 public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;


        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

        public int getCount() {
            return MyArrList.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") );

            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));

            final CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);


            if(yourSelectedItems.contains((position))){
                Chk.setChecked(true);
             }else{
                Chk.setChecked(false);
             }

            Chk.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    if (Chk.isChecked())
                    {
                         yourSelectedItems.add(position);
                    } else
                    {
                        if(yourSelectedItems.contains(position)){                                               
                            yourSelectedItems.remove(yourSelectedItems.indexOf(position));                                   
                        }
                    }

                }
            });


            return convertView;
        }

 }

But now I'm facing with new problem: How to get list of all checked and unchecked items where some checkboxes (items) are not visible due to many items in listview which are visible only when scrolling down? 但是现在我遇到了一个新问题:如何获取所有选中和未选中项目的列表,其中某些复选框(项目)不可见,这是由于listview中的许多项目仅在向下滚动时才可见?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM