简体   繁体   English

自定义ListView复选框选择

[英]Custom ListView checkbox selection

I am trying to check the checkbox of my custom listView items. 我正在尝试检查自定义listView项的checkbox

I am trying by using view.setOnClickListener on my custom listview Adapter. 我正在尝试在自定义列表视图适配器上使用view.setOnClickListener

When I am selecting one item of the listView item, another item is also getting selected down of the list. 当我选择listView项中的一项时,另一项也在列表的下方被选中。

My getView code 我的getView代码

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

    if (view == null){
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        view = inflater.inflate(row, parent, false);

        holder = new ViewHolder();

        holder.studentName = (TextView) view.findViewById(R.id.studentName);
        holder.id = (TextView) view.findViewById(R.id.studentID);
        holder.checkBox = (CheckBox) view.findViewById(R.id.checkBox);
        view.setTag(holder.checkBox);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!holder.checkBox.isChecked() && view!=null) {
                    holder.checkBox.setChecked(true);
                    presentStudent.add(data.get(position));
                    Toast.makeText(context, "added " + data.get(position).getName(), Toast.LENGTH_SHORT).show();
                }
                else {
                    holder.checkBox.setChecked(false);
                    presentStudent.remove(data.get(position));
                    Toast.makeText(context, "removed " + data.get(position).getName(), Toast.LENGTH_SHORT).show();
                }



            }
        });

        view.setTag(holder);

    } else {
        holder = (ViewHolder) view.getTag();
    }

    if((data == null) || ((position+1) > data.size()))
        return view;

    studentData = data.get(position);



    if ((holder.studentName != null) && null != studentData.getName()
            && studentData.getName().trim().length() > 0 )
        holder.studentName.setText(Html.fromHtml(studentData.getName()));

    if ((holder.id != null) && null != studentData.getAcademicId()
            && studentData.getAcademicId().trim().length() > 0 )
        holder.id.setText(Html.fromHtml(studentData.getAcademicId()));


    return view;
}

Here is my Layout code: 这是我的布局代码:

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


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <TextView
            android:layout_marginBottom="10dp"
            android:text="ID: 20151057010 (057)"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/studentID"
            android:layout_alignBottom="@+id/checkBox"
            android:layout_alignLeft="@+id/studentName"
            android:layout_alignStart="@+id/studentName" />

        <ImageView

            android:layout_width="40dp"
            android:layout_height="40dp"
            android:id="@+id/image"
            android:src="@drawable/student_icon"
            android:layout_marginLeft="14dp"
            android:layout_marginStart="14dp"
            android:layout_centerVertical="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true" />

        <CheckBox
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/checkBox"
            android:layout_below="@+id/studentName"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_marginRight="11dp"
            android:layout_marginEnd="11dp" />

        <TextView
            android:id="@+id/studentName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Sudarshan Mondal"
            android:textSize="20sp"
            android:layout_marginLeft="31dp"
            android:layout_marginStart="31dp"
            android:layout_alignTop="@+id/image"
            android:layout_toRightOf="@+id/image"
            android:layout_toEndOf="@+id/image"
            android:layout_marginTop="10dp"/>
    </RelativeLayout>


   </LinearLayout>

我选择了这个项目 该项目自动被选中

What should I do? 我该怎么办?

It's happening because of default behaviour of listview to reuse inflated view. 之所以发生这种情况,是因为Listview的默认行为可以重用膨胀视图。 Take temporary arraylist to store clicked position and verify the same arraylist whether it is contained that specific position or not inside getView method. 使用临时arraylist来存储单击的位置,并验证相同的arraylist是否包含在getView方法内的特定位置。 Declare arraylist inside your adapter class, Here you go : 在适配器类中声明arraylist,在这里:

ArrayList<String> selectedPosition = new ArrayList<String>();

Now update your getView() method as per below : 现在,按照以下方法更新getView()方法:

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

    if (view == null){
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        view = inflater.inflate(row, parent, false);

        holder = new ViewHolder();

        holder.studentName = (TextView) view.findViewById(R.id.studentName);
        holder.id = (TextView) view.findViewById(R.id.studentID);
        holder.checkBox = (CheckBox) view.findViewById(R.id.checkBox);
        //view.setTag(holder.checkBox); No need to do this

        view.setTag(holder);

    } else {
        holder = (ViewHolder) view.getTag();
    }

    if((data == null) || ((position+1) > data.size()))
        return view;

    studentData = data.get(position);



    if ((holder.studentName != null) && null != studentData.getName()
            && studentData.getName().trim().length() > 0 )
        holder.studentName.setText(Html.fromHtml(studentData.getName()));

    if ((holder.id != null) && null != studentData.getAcademicId()
            && studentData.getAcademicId().trim().length() > 0 )
        holder.id.setText(Html.fromHtml(studentData.getAcademicId()));

      //Added Change here...Check if arraylist contains selectedposition or not?

        if(selectedPosition.contains(String.valueOf(position))){
               holder.checkBox.setChecked(true);
               presentStudent.add(data.get(position));
        }else{
               holder.checkBox.setChecked(false);
               presentStudent.remove(data.get(position));
        }

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


           //Simply store and check selectedPosition

           if(selectedPosition.contains(String.valueOf(position)))
               selectedPosition.remove(String.valueOf(position));
           else
               selectedPosition.add(String.valueOf(position));

           //And then update adapter
           notifyDataSetChanged();

            }
        });


    return view;
}

You have added setTag() twice, surely that is messing up. 您已经两次添加了setTag(),肯定是搞砸了。 While doing setTag() for first time, you are setting tag for checkbox but while doing getTag() you are taking complete holder. 第一次执行setTag()时,您要为复选框设置标签,而执行getTag()时,您将使用完整的holder。

Edit: 编辑:

It reuses your view while scrolling. 它在滚动时重用您的视图。 You will have to implement checkedchangelistener for checkboxes and update the checkbox state: 您将必须为复选框实现checkedchangelistener,并更新复选框状态:

 holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // Maintain checkbox state here, which you need to check inside view.setOnClickListener..
            }
        });

Also post the 'row' layout if above didn't help. 如果上面没有帮助,还可以发布“行”布局。

// Define size as per your list.
     boolean[] itemChecked = new boolean[YourList.size()];


     holder.ck1.setChecked(false);

    // check its already checked..

      if (itemChecked[position])
       holder.ck1.setChecked(true);
      else
       holder.ck1.setChecked(false);

    holder.ck1.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
        // TODO Auto-generated method stub
        if (holder.ck1.isChecked())
         itemChecked[position] = true;
        else
         itemChecked[position] = false;
       }
      });

Try with this 试试这个

private ArrayList<StudentData> selectedUserArrayList = new ArrayList<>(); // Declare globally
public static int i; // Declare globally

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

    if (view == null){
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        view = inflater.inflate(row, parent, false);

        holder = new ViewHolder();

        holder.studentName = (TextView) view.findViewById(R.id.studentName);
        holder.id = (TextView) view.findViewById(R.id.studentID);
        holder.checkBox = (CheckBox) view.findViewById(R.id.checkBox);


        view.setTag(holder);

    } else {
        holder = (ViewHolder) view.getTag();
    }

    if((data == null) || ((position+1) > data.size()))
        return view;

    studentData = data.get(position);


        viewHolder.checkbox.setOnCheckedChangeListener(null);
        viewHolder.checkbox.setChecked(selectedUserArrayList.contains(user));
        viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (isChecked) {
                    i = user.getUserId();
                    selectedUserArrayList.add(user);
                } else {
                    if (i == user.getUserId()) {
                        i = 0;
                    }
                    selectedUserArrayList.remove(user);
                }
            }
        });
    if ((holder.studentName != null) && null != studentData.getName()
            && studentData.getName().trim().length() > 0 )
        holder.studentName.setText(Html.fromHtml(studentData.getName()));

    if ((holder.id != null) && null != studentData.getAcademicId()
            && studentData.getAcademicId().trim().length() > 0 )
        holder.id.setText(Html.fromHtml(studentData.getAcademicId()));


    return view;
}

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

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