简体   繁体   中英

Checkbox gets unchecked when i scroll my custom listview

when i have more items in listview and i select some checkbox and scroll it down to select more checkbox then checkbox which were selected above gets deselect.

Plz help. where i can save checked state and position and when i do refresh list. code given below.

     protected void onCreate(Bundle savedInstanceState) {

     dladapter = new DifferenceListAdapter(this,
                prodCodeArr, prodDescArr, serialBatchArr, expDtArr, qtyArr, serialNo, 0);
        diffeneceLv.setAdapter(dladapter);}

     static class ViewHolder {
    TextView srNotv, prodCodetv, prodDesctv, serialBatchNotv, expDatetv, qtytv;
    CheckBox consCheckBox;
}

     public class DifferenceListAdapter extends BaseAdapter{        
    Context c;
    String[] prodCode, prodDesc, expDate, qty, serialNo, serialBatchNo;
    //TextView srNotv, prodCodetv, prodDesctv, serialBatchNotv, expDatetv, qtytv;
    EditText consumedEt, disputeEt, OTCEt, patientnameEt;
    //final ArrayList<String> chkList = new ArrayList<String>();
    ArrayList<Boolean> chkState;
    //CheckBox consCheckBox;
    private boolean checked = false;
    ViewHolder viewHolder;
    View row;
    int f=0;


public DifferenceListAdapter(Context c, String[] prodCode, String[] prodDesc, String[] serialBatchNo, String[] expDate, String[] qty, String[] serialNo, int f){


        this.c = c;
        this.prodCode= prodCode;
        this.prodDesc= prodDesc;
        this.serialBatchNo= serialBatchNo;
        this.expDate = expDate;
        this.qty=qty;
        this.serialNo= serialNo;
        this.f= f;



        chkState = new ArrayList<Boolean>();

    }

public String[] getChecked(){


    return chkList.toArray(new String[chkList.size()]);
}   

    public int getCount() {
        // TODO Auto-generated method stub
        return prodCode.length;
    }

    public Object getItem(int arg0) {
        // TODO Auto-generated method stub

        return serialBatchNo[arg0];
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }
    public CheckBox getCheckBox() {
        return viewHolder.consCheckBox;
    }

    public void toggleChecked() {
        checked = !checked;

    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        final int p= position;
        //if (convertView == null) {
        viewHolder=new ViewHolder();
        LayoutInflater inflater= (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row= inflater.inflate(R.layout.consumedstockitemrow, null);     
        viewHolder.consCheckBox = (CheckBox) row.findViewById(R.id.conschkbx);
        viewHolder.srNotv=(TextView) row.findViewById(R.id.rowcdiffSrNoTv);
        viewHolder.prodCodetv=(TextView) row.findViewById(R.id.rowcdiffProductCodeTv);
        viewHolder.prodDesctv=(TextView) row.findViewById(R.id.rowcdiffProdDescTv);
        viewHolder.serialBatchNotv=(TextView) row.findViewById(R.id.rowcdiffSerialBatchTv);
        viewHolder.expDatetv=(TextView) row.findViewById(R.id.rowcdiffExpDtTv);
        viewHolder.qtytv=(TextView) row.findViewById(R.id.rowcdiffQtyTv);

        viewHolder.consCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub
                 CheckBox cb = (CheckBox) buttonView;

                    if(cb.isChecked()== true)
                    {


                        if(chkList.contains(serialBatchNo[p]))
                        {

                        }
                        else
                        {
                        chkList.add(serialBatchNo[p]);
                        }

                    }
                    else
                    {

                        if(chkList.contains(serialBatchNo[p]))
                        {
                            chkList.remove(serialBatchNo[p]);
                        }


                    }

            }
        });


        viewHolder.srNotv.setText(String.valueOf(p+1));
        viewHolder.prodCodetv.setText(prodCode[p].toString());
        viewHolder.prodDesctv.setText(prodDesc[p].toString());
        viewHolder.serialBatchNotv.setText(serialBatchNo[p].toString());
        viewHolder.expDatetv.setText(expDate[p].toString());
        viewHolder.qtytv.setText(qty[p].toString());



        return row;
    }

}

i find some workaround solution not the best one but do his job what it do its on checkBox listener if view(CheckBox) not visible anymore its not alowed to change checkbox state so when you scroll its will not uncheck your check box still you need to provide List of position where checkbox was selected and on getView set state of checkbox

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

    if(buttonView.isShown()) // chek if checkbox is visible 
    {
        int position = buttonView.getId();  // get position of check box 
        _selected[position] = buttonView.isChecked(); // set true or false  in list of seleted checkboxes 

    }

}

getView look like this

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

    View view = convertView;
    if (view == null) {
        LayoutInflater inflater = activity.getLayoutInflater();
        view = inflater.inflate(R.layout.layout, null);
        ViewHolder viewHolder = new ViewHolder();
        viewHolder.tv = (TextView) rowView.findViewById(R.id.text);
        viewHolder.cb = (CheckBox) rowView.findViewById(R.id.check_box);
        viewHolder.cb.setOnCheckedChangeListener(this);
        view.setTag(viewHolder);
    }

    ViewHolder holder = (ViewHolder) view.getTag();
    holder.tv.setText("Text");
    holder.cb.setChecked(_selected[position]); //Geting state of check box from array
    holder.cb.setId(position); // set check box ID(position in adapter)

    return view;


}

ViewHolder

class ViewHolder
{
    TextView tv;
    CheckBox cb;

}

Just override getView method of your Adapter:

    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            convertView = inflater.inflate(R.layout.row, parent, false);
            wrapper = new YourWrapper(convertView);
            convertView.setTag(wrapper);
        }
        else
        {
            wrapper = (YourWrapper) convertView.getTag();
        }

        wrapper.getChecker().setOnCheckedChangeListener(
                new OnCheckedChangeListener()
                {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked)
                    {
                        // Get the position that set for the checkbox using setTag.
                        int getPosition = (Integer) buttonView.getTag();
                        // Set the value of checkbox to maintain its state.
                        list.get(getPosition).setCheck(buttonView.isChecked());
                    }
                });
        wrapper.getChecker().setTag(position);
        wrapper.getTags().setText(list.get(position).getTitle());
        wrapper.getChecker().setChecked(list.get(position).getCheck());

        return convertView;
    }

below is the working code I am using for

Showing Check-box in List-view with Array-adapter .

MainActivity.java

package com.rdc.activity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

    private ListView mainListView = null;
    private Planet[] planets = null;
    private ArrayAdapter<Planet> listAdapter = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mainListView = (ListView) findViewById(R.id.mainListView);

        // When item is tapped, toggle checked properties of 
            //   CheckBox and Planet.

        mainListView.setOnItemClickListener(new
                         AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View item,
            int position, long id) {
        Planet planet = listAdapter.getItem(position);
        planet.toggleChecked();
        PlanetViewHolder viewHolder = 
                           (PlanetViewHolder) item
               .getTag();
                viewHolder.getCheckBox()
                     .setChecked(planet.isChecked());
                }
                });

        // Create and populate planets.
        planets = (Planet[]) getLastNonConfigurationInstance();
        if (planets == null) {
            planets = new Planet[] { new Planet("Mercury"),
                    new Planet("Venus"), new Planet("Earth"),
                    new Planet("Mars"), new Planet("Jupiter"),
                    new Planet("Saturn"), new Planet("Uranus"),
                    new Planet("Neptune"), new Planet("Ceres"),
                    new Planet("Pluto"), new Planet("Haumea"),
                    new Planet("Makemake"), new Planet("Eris") };
        }
        ArrayList<Planet> planetList = new ArrayList<Planet>();
        planetList.addAll(Arrays.asList(planets));

        // Set our custom array adapter as the ListView's adapter.
        listAdapter = new PlanetArrayAdapter(this, planetList);
        mainListView.setAdapter(listAdapter);
    }

    /** Holds planet data. */
    private static class Planet {
        private String name = "";
        private boolean checked = false;

        public Planet() {
        }

        public Planet(String name) {
            this.name = name;
        }

        public Planet(String name, boolean checked) {
            this.name = name;
            this.checked = checked;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public boolean isChecked() {
            return checked;
        }

        public void setChecked(boolean checked) {
            this.checked = checked;
        }

        public String toString() {
            return name;
        }

        public void toggleChecked() {
            checked = !checked;
        }
    }

    /** Holds child views for one row. */
    private static class PlanetViewHolder {
        private CheckBox checkBox;
        private TextView textView;

        public PlanetViewHolder() {
        }

        public PlanetViewHolder(TextView textView, CheckBox checkBox) {
            this.checkBox = checkBox;
            this.textView = textView;
        }

        public CheckBox getCheckBox() {
            return checkBox;
        }

        public void setCheckBox(CheckBox checkBox) {
            this.checkBox = checkBox;
        }

        public TextView getTextView() {
            return textView;
        }

        public void setTextView(TextView textView) {
            this.textView = textView;
        }
    }

    /** Custom adapter for displaying an array of Planet objects. */
    private static class PlanetArrayAdapter extends ArrayAdapter<Planet> {

        private LayoutInflater inflater;

        public PlanetArrayAdapter(Context context, List<Planet> planetList) {
            super(context, R.layout.simplerow, R.id.rowTextView, planetList);
            // Cache the LayoutInflate to avoid asking for a new one each time.
            inflater = LayoutInflater.from(context);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Planet planet = (Planet) this.getItem(position);
            CheckBox checkBox;
            TextView textView;

            // Create a new row view
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.simplerow, null);

                textView = (TextView) convertView
                        .findViewById(R.id.rowTextView);
                checkBox = (CheckBox) convertView.findViewById(R.id.CheckBox01);

                convertView.setTag(new PlanetViewHolder(textView, checkBox));

                // If CheckBox is toggled, update the planet it is tagged with.
                checkBox.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        CheckBox cb = (CheckBox) v;
                        Planet planet = (Planet) cb.getTag();
                        planet.setChecked(cb.isChecked());
                    }
                });
            }
            // Re-use existing row view
            else {

                PlanetViewHolder viewHolder = (PlanetViewHolder) convertView
                        .getTag();
                checkBox = viewHolder.getCheckBox();
                textView = viewHolder.getTextView();
            }

            // Tag the CheckBox with the Planet it is displaying, so that we can
            // access the planet in onClick() when the CheckBox is toggled.
            checkBox.setTag(planet);

            // Display planet data
            checkBox.setChecked(planet.isChecked());
            textView.setText(planet.getName());

            return convertView;
        }

    }

    public Object onRetainNonConfigurationInstance() {
        return planets;
    }
}

main.xml (for list view)

<?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">

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/mainListView">
    </ListView>

</LinearLayout>

simplerow.xml (for List view's Row)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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/rowTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:textSize="16sp">
    </TextView>

    <CheckBox
        android:id="@+id/CheckBox01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_alignParentRight="true"
        android:layout_marginRight="6sp"
        android:focusable="false">
    </CheckBox>

</RelativeLayout>

Here is the Result screen ..

在此处输入图片说明

Please let me know if you still have any trouble regarding this!

Here is complete tutorial

无论您要返回到BaseAdapter中的getItem的任何对象,请确保您对每个项目都采用未选中的布尔对象。对于每个选中的项目,您可以将选中的布尔值设置为true ..并在getView中检查是否选中了该项目而不是check复选框。

I have a solution for your problem. In my project, I used custom adapter extends with base adapter, use this code in getview method:

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

        if (convertView == null) {

            LayoutInflater li = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = li.inflate(R.layout.contact_row, null);

        }

        TextView tv_name = (TextView) convertView
                .findViewById(R.id.contactnameid);
        TextView tv_no = (TextView) convertView
                .findViewById(R.id.contactnoid);

        tv_name.setText(names[position]);
        tv_no.setText(numbers[position]);

        final CheckBox ch_bx = (CheckBox) convertView
                .findViewById(R.id.contactchkboxid);

        ch_bx.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub

                CheckBox ch = (CheckBox) v
                        .findViewById(R.id.contactchkboxid);

                if (ch.isChecked()) {
                    itemchecked.set(position, true);
                    Final_SMS_Nos.add(numbers[position]);
                    Log.v("SMS No adding", "" + Final_SMS_Nos);

                } else if (!ch.isChecked()) {
                    itemchecked.set(position, false);
                    Final_SMS_Nos.remove(numbers[position]);
                    Log.v("SMS No deleting", "" + Final_SMS_Nos);
                }

            }
        });

        ch_bx.setChecked(itemchecked.get(position));

        return convertView;

    }

尝试将setChecked()放在setOnCheckedChangeListener()

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