简体   繁体   中英

Checkbox geting unchecked after scrolling Custom listview…!

I Create custom listview, and put checkbox in it.
at First I check all checkbox and then I scroll down listview, then checkbox getting Unchecked.
what should I do?
CustomListItem.java

package com.example.customlistviewdemo;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class CustomListItem extends ArrayAdapter<String> {

    private final Activity context;
    private final String[] TitleArray;
    private final String[] SubTitlearray;
    private final String[] TimeArray;
    private final Integer[] MainImageId;


    public CustomListItem(Activity context, String[] TitleArray,
            String[] SubTitlearray, String[] TimeArray, Integer[] MainImageId) {
        super(context, R.layout.list_item, TitleArray);
        this.context = context;
        this.TitleArray = TitleArray;

        this.SubTitlearray = SubTitlearray;
        this.TimeArray = TimeArray;
        this.MainImageId = MainImageId;


    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView = inflater.inflate(R.layout.list_item, null, true);
        ImageView animal, car, environment, map1, warning1, map2, warning2, download, share, plant;
        animal = (ImageView) rowView.findViewById(R.id.imgAnimal);
        car = (ImageView) rowView.findViewById(R.id.imgCar);
        environment = (ImageView) rowView.findViewById(R.id.imgEnvironment);
        plant = (ImageView) rowView.findViewById(R.id.imgPlant);
        map1 = (ImageView) rowView.findViewById(R.id.imgMap);
        warning1 = (ImageView) rowView.findViewById(R.id.imgWarning);
        map2 = (ImageView) rowView.findViewById(R.id.imgMap2);
        warning2 = (ImageView) rowView.findViewById(R.id.imgWarining2);
        download = (ImageView) rowView.findViewById(R.id.imgDownload);
        CheckBox chk = (CheckBox) rowView.findViewById(R.id.checkbox);
        share = (ImageView) rowView.findViewById(R.id.imgShare);

        animal.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "Animal ImageView is Clicked",
                        5000).show();
                // TODO Auto-generated method stub

            }
        });
        car.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "Cars ImageView is Clicked", 5000)
                        .show();
                // TODO Auto-generated method stub

            }
        });
        environment.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(),
                        "environment ImageView is Clicked", 5000).show();
                // TODO Auto-generated method stub

            }
        });
        ------------------------------------------------------------------
                      ...........................SO on............................
                        ..........................................................

        TextView mainTitle = (TextView) rowView.findViewById(R.id.txtMainTitle);
        ImageView mainImage = (ImageView) rowView
                .findViewById(R.id.imgMainImage);

        TextView SubText = (TextView) rowView.findViewById(R.id.txtSubTitle);
        TextView TimeText = (TextView) rowView.findViewById(R.id.txtTimeTitle);

        mainTitle.setText(TitleArray[position]);
        SubText.setText(SubTitlearray[position]);
        TimeText.setText(TimeArray[position]);
        mainImage.setImageResource(MainImageId[position]);

        return rowView;
    }
}


ActivityMain.java

package com.example.customlistviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
    ListView list;
    String[] TitleArray = { "Testing Title1. This is MainTitle",
            "Testing Title2. This is MainTitle",
            "Testing Title3. This is MainTitle",
            "Testing Title4. This is MainTitle",
            "Testing Title5. This is MainTitle",
            "Testing Title6. This is MainTitle" };
    String[] SubTitleArray = { "Reported by Man 1", "Reported by Man 2",
            "Reported by Man 3", "Reported by Man 4", "Reported by Man 5",
            "Reported by Man 6" };

    String[] TimeArray = { "about 1 hour ago", "about 2 hour ago",
            "about 3 hour ago", "about 4 hour ago", "about 5 hour ago",
            "about 6 hour ago" };

    Integer[] MainImageId = { R.drawable.android1, R.drawable.android2,
            R.drawable.android3, R.drawable.android4, R.drawable.android5,
            R.drawable.android6 };



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CustomListItem adapter = new CustomListItem(MainActivity.this,
                TitleArray, SubTitleArray, TimeArray, MainImageId);
        list = (ListView) findViewById(R.id.listView1);
        list.setAdapter(adapter);

    }
}


list_item.xml

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp" >

        <TextView
            android:id="@+id/txtMainTitle"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="This is Sample Text"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="130dp" >

        <LinearLayout
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:paddingRight="15dp" >

            <CheckBox
                android:layout_width="wrap_content"
                android:layout_height="fill_parent" />

            <ImageView
                android:id="@+id/imgMainImage"
                android:layout_width="100dp"
                android:layout_height="fill_parent" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/txtSubTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp"
                android:text="This is Sample Text"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:textSize="16dp" />

            <TextView
                android:id="@+id/txtTimeTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="This is Sample Text"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:textSize="12dp" />

            <HorizontalScrollView
                android:id="@+id/scrollView1"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:scrollbars="none" >

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="8dp"
                    android:layout_marginTop="8dp" >

                    <ImageView
                        android:id="@+id/imgAnimal"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/channel_animal" />

                    <ImageView
                        android:id="@+id/imgCar"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/channel_car" />

                    <ImageView
                        android:id="@+id/imgEnvironment"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/channel_environment" />

                    <ImageView
                        android:id="@+id/imgPlant"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/channel_plant" />

                    <ImageView
                        android:id="@+id/imgMap"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/tab_icon_map" />

                    <ImageView
                        android:id="@+id/imgWarning"
                        android:layout_width="25dp"
                        android:layout_height="25dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/warning_icon" />
                </LinearLayout>
            </HorizontalScrollView>

            <HorizontalScrollView
                android:id="@+id/scrollView2"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:scrollbars="none" >

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

                    <ImageView
                        android:id="@+id/imgMap2"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/tab_icon_map" />

                    <ImageView
                        android:id="@+id/imgWarining2"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/warning_icon" />

                    <ImageView
                        android:id="@+id/imgDownload"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/download_icon" />

                    <ImageView
                        android:id="@+id/imgShare"
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:layout_marginRight="10dp"
                        android:src="@drawable/share_icon" />
                </LinearLayout>
            </HorizontalScrollView>
        </LinearLayout>
    </LinearLayout>

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

        <View
            android:id="@+id/view"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_toRightOf="@+id/text1"
            android:background="#FF9900" />
    </LinearLayout>

</LinearLayout>

Just Modify your adapter class like this architecture i hope it works : the important lines are setting the tag and getting the tag.

public class MyAdapter extends ArrayAdapter<Model> {

    private final List<Model> list;
    private final Activity context;
    boolean checkAll_flag = false;
    boolean checkItem_flag = false;

    public MyAdapter(Activity context, List<Model> list) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
    }

    static class ViewHolder {
        protected TextView text;
        protected CheckBox checkbox;
    }

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

        ViewHolder viewHolder = null;
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            convertView = inflator.inflate(R.layout.row, null);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) convertView.findViewById(R.id.label);
            viewHolder.checkbox = (CheckBox) convertView
                    .findViewById(R.id.check);
            viewHolder.checkbox
                    .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            int getPosition = (Integer) buttonView.getTag(); // Here
                                // we get  the position that we have set for the checkbox using setTag.
                            list.get(getPosition).setSelected(
                                    buttonView.isChecked()); // Set the value of
                                                                // checkbox to
                                                                // maintain its
                                                                // state.
                        }
                    });
            convertView.setTag(viewHolder);
            convertView.setTag(R.id.label, viewHolder.text);
            convertView.setTag(R.id.check, viewHolder.checkbox);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.checkbox.setTag(position); // This line is important.

        viewHolder.text.setText(list.get(position).getName());
        viewHolder.checkbox.setChecked(list.get(position).isSelected());

        return convertView;
    }
}

There is an issue with ListView when you are using CheckBox within ListView is that the Checked state of CheckBox will not maintain by Android because when you Scroll ListView it will generate new View for each row using getView() method and Garbage Collector will remove all above View to make space so CheckBox state will also destroy or garbage by Garbage Collector . You can solve this by following sample:

Main.xml

<relativelayout 
    android:layout_height="match_parent" 
     android:layout_width="match_parent" 
     tools:context=".Main" 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:tools="http://schemas.android.com/tools">

    <listview 
           android:divider="#000" 
           android:dividerheight="0.8dp"
           android:id="@+id/listView1" 
           android:layout_alignparentleft="true" 
           android:layout_alignparenttop="true" 
           android:layout_height="match_parent" 
           android:layout_width="match_parent">
    </listview>

    <button 
           android:id="@+id/button1" 
           android:layout_alignparenttop="true" 
           android:layout_centerhorizontal="true" 
           android:layout_height="wrap_content" 
           android:layout_width="match_parent" 
           android:text="Check Selected">

    </button>
</relativelayout>

list_item.xml

<relativelayout 
      android:layout_height="match_parent" 
      android:layout_width="match_parent" 
      xmlns:android="http://schemas.android.com/apk/res/android">

      <textview 
            android:id="@+id/textView1" 
            android:layout_alignparentleft="true" 
            android:layout_alignparenttop="true"
            android:layout_height="wrap_content" 
            android:layout_marginbottom="10dp" 
            android:layout_margintop="10dp" 
            android:layout_width="wrap_content"  
            android:text="Medium Text" 
            android:textappearance="?android:attr/textAppearanceMedium">
     </textview>

     <checkbox
            android:focusable="false" 
            android:focusableintouchmode="false" 
            android:id="@+id/checkBox1"
            android:layout_alignbaseline="@+id/textView1" 
            android:layout_alignbottom="@+id/textView1" 
            android:layout_alignparentright="true" 
            android:layout_height="wrap_content" 
            android:layout_marginright="16dp" 
            android:layout_width="wrap_content">

    </checkbox>
 </relativelayout>

Main.java

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends Activity implements OnItemClickListener{

 ListView apps;
 PackageManager packageManager;
 ArrayList <String> checkedValue;
 Button bt1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bt1 = (Button) findViewById(R.id.button1);
        apps = (ListView) findViewById(R.id.listView1);
        packageManager = getPackageManager();
  final List <PackageInfo> packageList = packageManager
    .getInstalledPackages(PackageManager.GET_META_DATA); // all apps in the phone
  final List <PackageInfo> packageList1 = packageManager
    .getInstalledPackages(0);

    try {
      packageList1.clear();
      for (int n = 0; n < packageList.size(); n++)
      {

       PackageInfo PackInfo = packageList.get(n);
       if (((PackInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) != true)
        //check weather it is system app or user installed app
       {
        try
        {

          packageList1.add(packageList.get(n)); // add in 2nd list if it is user installed app
           Collections.sort(packageList1,new Comparator <PackageInfo>()
             // this will sort App list on the basis of app name
           {
            public int compare(PackageInfo o1,PackageInfo o2)
            {
             return o1.applicationInfo.loadLabel(getPackageManager()).toString()
               .compareToIgnoreCase(o2.applicationInfo.loadLabel(getPackageManager())
                   .toString());// compare and return sorted packagelist.
            }
           });


        } catch (NullPointerException e) {
         e.printStackTrace();
        }
       }
      }
     } catch (Exception e) {
      e.printStackTrace();
     }
    Listadapter Adapter = new Listadapter(this,packageList1, packageManager);
    apps.setAdapter(Adapter);
    apps.setOnItemClickListener(this);
    bt1.setOnClickListener(new View.OnClickListener() {

     @Override
     public void onClick(View v) {
      // TODO Auto-generated method stub
      Toast.makeText(Main.this,"" + checkedValue,Toast.LENGTH_LONG).show();
     }
    });

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


 @Override
 public void onItemClick(AdapterView arg0, View v, int position, long arg3) {
  // TODO Auto-generated method stub
  CheckBox cb = (CheckBox) v.findViewById(R.id.checkBox1);
  TextView tv = (TextView) v.findViewById(R.id.textView1);
  cb.performClick();
  if (cb.isChecked()) {

   checkedValue.add(tv.getText().toString());
  } else if (!cb.isChecked()) {
   checkedValue.remove(tv.getText().toString());
  }           
 }         
}

Listadapter.java

import java.util.List;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

public class Listadapter extends BaseAdapter{

 List <PackageInfo> packageList;
 Activity context;
 PackageManager packageManager;
 boolean[] itemChecked;

 public Listadapter(Activity context, List <PackageInfo> packageList,
   PackageManager packageManager) {
  super();
  this.context = context;
  this.packageList = packageList;
  this.packageManager = packageManager;
  itemChecked = new boolean[packageList.size()];
 }

 private class ViewHolder {
  TextView apkName;
  CheckBox ck1;
 }

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

 public Object getItem(int position) {
  return packageList.get(position);
 }

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

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

  LayoutInflater inflater = context.getLayoutInflater();

  if (convertView == null) {
   convertView = inflater.inflate(R.layout.list_item, null);
   holder = new ViewHolder();

   holder.apkName = (TextView) convertView
     .findViewById(R.id.textView1);
   holder.ck1 = (CheckBox) convertView
     .findViewById(R.id.checkBox1);

   convertView.setTag(holder);

  } else {

   holder = (ViewHolder) convertView.getTag();
  }

  PackageInfo packageInfo = (PackageInfo) getItem(position);

  Drawable appIcon = packageManager
    .getApplicationIcon(packageInfo.applicationInfo);
  String appName = packageManager.getApplicationLabel(
    packageInfo.applicationInfo).toString();
  appIcon.setBounds(0, 0, 40, 40);
  holder.apkName.setCompoundDrawables(appIcon, null, null, null);
  holder.apkName.setCompoundDrawablePadding(15);
  holder.apkName.setText(appName);
  holder.ck1.setChecked(false);

  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;
   }
  });

  return convertView;

 }      
}

Why you don't use setOnCheckedChangeListener() to keep/hold the checked state for each position item?

Remember to place setChecked() after setOnCheckedChangeListener() , otherwise it will trigger the previous ViewHolder object's setOnCheckedChangeListener() which causes the unchecked problem for the previous item.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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