[英]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 我发现一些解决方法不是最好的解决方法,但是如果view(CheckBox)不再可见,则它不会在checkBox侦听器上执行其工作,因此不允许更改复选框状态,因此当您滚动其时,也不会取消选中复选框,仍然需要提供选中复选框以及在getView上设置复选框状态的位置列表
@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 getView看起来像这样
@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 ViewHolder
class ViewHolder
{
TextView tv;
CheckBox cb;
}
Just override getView method of your Adapter: 只需重写您的适配器的getView方法:
@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 以下是我正在使用的工作代码
MainActivity.java 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) 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">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/mainListView">
</ListView>
</LinearLayout>
simplerow.xml (for List view's Row) simplerow.xml (用于列表视图的行)
<?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:
在我的项目中,我使用自定义适配器和基本适配器扩展,在getview方法中使用以下代码:
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()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.