当我在 Android 上滚动列表视图时未选中复选框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10895763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:21:07  来源:igfitidea点击:

Checkbox unchecked when I scroll listview on Android

androidlistviewcheckboxscroll

提问by Mathew

I am new to Android development. I created a listviewwith a textboxand checkbox.

我是 Android 开发的新手。我创建了listview一个textboxcheckbox

When I check the checkboxand scroll it down to check some other items in the list view, the older ones are unchecked.

当我检查checkbox并向下滚动以检查列表视图中的其他一些项目时,较旧的项目未选中。

How do I avoid this problem in a listview? Please guide me with my code.

我如何在 a 中避免这个问题listview?请用我的代码指导我。

Here is the code:

这是代码:

main.xml:

主文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/TextView01"
        android:layout_height="wrap_content"
        android:text="List of items"
        android:textStyle="normal|bold"
        android:gravity="center_vertical|center_horizontal"
        android:layout_width="fill_parent"/>

    <ListView
        android:id="@+id/ListView01"
        android:layout_height="250px"
        android:layout_width="fill_parent"/>

    <Button
        android:text="Save"
        android:id="@+id/btnSave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>


This is the XML page I used to create dynamic list row:

这是我用来创建动态列表行的 XML 页面:

listview.xml:

列表视图.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:gravity="left|center"
    android:layout_width="wrap_content"
    android:paddingBottom="5px"
    android:paddingTop="5px"
    android:paddingLeft="5px">

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#FFFF00"
        android:text="hi"/>

    <TextView
        android:text="hello"
        android:id="@+id/TextView02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10px"
        android:textColor="#0099CC"/>

    <EditText
        android:id="@+id/txtbox"
        android:layout_width="120px"
        android:layout_height="wrap_content"
        android:textSize="12sp"
        android:layout_x="211px"
        android:layout_y="13px"/>

    <CheckBox
        android:id="@+id/chkbox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>


This is my activity class.

这是我的活动课。

CustomListViewActivity.java:

CustomListViewActivity.java:

public class CustomListViewActivity extends Activity {

    ListView lstView;
    static Context mContext;
    Button btnSave;

    private static class EfficientAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

        public EfficientAdapter(Context context) {
            mInflater = LayoutInflater.from(context);

        }

        public int getCount() {
            return country.length;
        }

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

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHolder holder;
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.listview, parent,
                        false);
                holder = new ViewHolder();
                holder.text = (TextView) convertView
                        .findViewById(R.id.TextView01);
                holder.text2 = (TextView) convertView
                        .findViewById(R.id.TextView02);
                holder.txt = (EditText) convertView.findViewById(R.id.txtbox);
                holder.cbox = (CheckBox) convertView.findViewById(R.id.chkbox1);

                convertView.setTag(holder);
            }
            else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.text.setText(curr[position]);
            holder.text2.setText(country[position]);
            holder.txt.setText("");
            holder.cbox.setChecked(false);

            return convertView;
        }

        public class ViewHolder {
            TextView text;
            TextView text2;
            EditText txt;
            CheckBox cbox;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lstView = (ListView) findViewById(R.id.ListView01);
        lstView.setAdapter(new EfficientAdapter(this));
        btnSave = (Button)findViewById(R.id.btnSave);
        mContext = this;

        btnSave.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // I want to print the text which is in the listview one by one.
                // Later I will insert it in the database.
                //
                //            Toast.makeText(getBaseContext(), "EditText Value, checkbox value and other values", Toast.LENGTH_SHORT).show();
                for (int i = 0; i < lstView.getCount(); i++) {
                    View listOrderView;
                    listOrderView = lstView.getChildAt(i);
                    try{
                        EditText txtAmt = (EditText)listOrderView.findViewById(R.id.txtbox);
                        CheckBox cbValue = (CheckBox)listOrderView.findViewById(R.id.chkbox1);
                        if(cbValue.isChecked()== true){
                            String amt = txtAmt.getText().toString();
                            Toast.makeText(getBaseContext(), "Amount is :"+amt, Toast.LENGTH_SHORT).show();
                        }

                    }
                    catch (Exception e) {
                        // TODO: handle exception
                    }
                }

            }
        });
    }

    private static final String[] country = { "item1", "item2", "item3",
        "item4", "item5", "item6","item7", "item8", "item9",
        "item10", "item11", "item12" };

    private static final String[] curr = { "1", "2", "3", "4", "5", "6","7", "8", "9", "10", "11", "12" };
}

Please help me to solve this problem.

请帮我解决这个问题。

I have referred to this problem in many places. But I could not get proper answer to solve this problem.

我在很多地方都提到过这个问题。但我无法得到正确的答案来解决这个问题。

Please provide me the code to avoid unchecking the checkbox while scrolling up and down.

请提供代码以避免在上下滚动时取消选中复选框。

回答by varotariya vajsi

In the custom listview adapter call setCheckedaftercalling setOnCheckedChangeListener.

在自定义列表视图适配器调用setChecked调用setOnCheckedChangeListener

This way you sever the link to the old listener from the recycled view.

通过这种方式,您可以从回收的视图中切断到旧侦听器的链接。

回答by user6017633

You can use the following adapter code to run a checkbox perfectly in a ListView.

您可以使用以下适配器代码在 ListView 中完美运行复选框。

A detailed demo is here: Listview With Checkbox Android

详细的演示在这里:Listview With Checkbox Android

See the detailed demo link for deep information. It also shows how to send checked information to the next activity.

有关详细信息,请参阅详细演示链接。它还显示了如何将检查的信息发送到下一个活动。

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;


public class CustomAdapter  extends BaseAdapter {

    private Context context;
    public static ArrayList<Model> modelArrayList;

    public CustomAdapter(Context context, ArrayList<Model> modelArrayList) {

        this.context = context;
        this.modelArrayList = modelArrayList;
    }

    @Override
    public int getViewTypeCount() {
        return getCount();
    }

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

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

    @Override
    public Object getItem(int position) {
        return modelArrayList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;

        if (convertView == null) {
            holder = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context
                     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.lv_item, null, true);

            holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb);
            holder.tvAnimal = (TextView) convertView.findViewById(R.id.animal);

            convertView.setTag(holder);
        }
        else {
            // The getTag returns the viewHolder object set as a tag to the view
            holder = (ViewHolder)convertView.getTag();
        }

        holder.checkBox.setText("Checkbox " + position);
        holder.tvAnimal.setText(modelArrayList.get(position).getAnimal());

        holder.checkBox.setChecked(modelArrayList.get(position).getSelected());

        holder.checkBox.setTag(R.integer.btnplusview, convertView);
        holder.checkBox.setTag( position);
        holder.checkBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                View tempview = (View) holder.checkBox.getTag(R.integer.btnplusview);
                TextView tv = (TextView) tempview.findViewById(R.id.animal);
                Integer pos = (Integer)  holder.checkBox.getTag();
                Toast.makeText(context, "Checkbox " + pos + " clicked!", Toast.LENGTH_SHORT).show();

                if (modelArrayList.get(pos).getSelected()){
                    modelArrayList.get(pos).setSelected(false);
                }
                else {
                    modelArrayList.get(pos).setSelected(true);
                }

            }
        });

        return convertView;
    }

    private class ViewHolder {

        protected CheckBox checkBox;
        private TextView tvAnimal;
    }
}

Modelis

Model

public class Model {

    private boolean isSelected;

    private String animal;

    public String getAnimal() {
        return animal;
    }

    public void setAnimal(String animal) {
        this.animal = animal;
    }

    public boolean getSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }
}

回答by Vladimir

In your getView()you have the following line

getView()你有以下行

holder.cbox.setChecked(false);

which sets CheckBox unchecked every time getView()is called (when you scroll your list, for example)

每次getView()调用时都将 CheckBox 设置为未选中状态(例如,当您滚动列表时)

回答by ranjan

Blockquote

块引用

**In Side getView() Method just call like this>>

**在侧 getView() 方法中只需像这样调用>>

check.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton arg0, boolean arg1) 
            {

                if(check.isChecked())
                {
                    //checked
                    chkArray[position]=true;
                }
                else
                {   //uncheck
                  chkArray[position]=false;

                }
            }
        });

//check condition for checkboxes
        if(chkArray.length>0)
        {
            for (int i = 0; i < chkArray.length; i++) 
            {
                if(chkArray[position]!=null && chkArray[position])
                {
                    check.setChecked(true);
                }
            }
        }

回答by Aly Abdelaal

finally i have reached to the solution few hours later that is by

几个小时后,我终于找到了解决方案

  1. add a Boolean variable array class with set and get methods.
  2. add an array to save my selections in it.
  3. use onClickListner.
  1. 添加一个带有 set 和 get 方法的布尔变量数组类。
  2. 添加一个数组以在其中保存我的选择。
  3. 使用 onClickListner。

inside getView method as the following:

在 getView 方法中,如下所示:


if(marray!=null) { //if myarray class object has data
holder.name.setText(marray.getName());
.
.
holder.checkbox.setChecked(marray.isChecked());//get the checkbox state 
}

give the value to the boolean variable in holder.checkbox.setOnClickListener method as:

将值赋予 holder.checkbox.setOnClickListener 方法中的布尔变量,如下所示:


holder.checkbox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (allReport.UserSelection.contains(
Integer.parseInt(marrays.get(position)
.getIdd()))) // check if id selected before
                    {
      marray.setChecked(false);// marray is the object from myArray class
      allReport.UserSelection.remove(new Integer(Integer.parseInt(marrays.get(position).getIdd())));//remove id 


 }else{
       allReport.UserSelection.add(Integer.parseInt
           (marrays.get(position).getIdd()));//save the selection 
            marray.setChecked(true);//save the boolean to true}

that's solve the problem for me i hope that's make any help

这为我解决了问题,我希望这能有所帮助

回答by Bhargav Panchal

Consider:

考虑:

holder.cbox.setChecked(false);

Remove this line. When you scrolled the list view every time, the getView() method is called.

删除此行。每次滚动列表视图时,都会调用 getView() 方法。

回答by Boe-Dev

I also got this problem before. Android does this to save space; only the items you currently see are loaded, and this is what I found out.

我之前也遇到过这个问题。Android 这样做是为了节省空间;仅加载您当前看到的项目,这就是我发现的。

If you are on the bottom on your list, the id 1 is on maybe position 5. I searched on the web and found this out before.

如果您在列表的底部,则 id 1 可能在第 5 位。我在网上搜索过,之前发现了这一点。

But thiswill help you :D

但是,会帮助你:d

回答by Ricky

When we scroll items in listview it restores the value from adapter. That is why the checkbox unchecked. But if we update the adapter with latest value, it will remain checked. For that you need to use setOnClickListener().

当我们在 listview 中滚动项目时,它会从适配器恢复值。这就是未选中复选框的原因。但是,如果我们使用最新值更新适配器,它将保持选中状态。为此,您需要使用 setOnClickListener()。

All you need to do is update your adapter on checkbox click.You can refer to this linkto get an idea

您需要做的就是在复选框单击时更新您的适配器。您可以参考此链接以获得想法