Android 滚动自定义ListView时,复选框值会更改
Android 滚动自定义ListView时,复选框值会更改,android,listview,checkbox,Android,Listview,Checkbox,我拥有的内容:带有文本视图和复选框的自定义列表视图。 问题:假设我的屏幕一次只能显示列表中的6项,而其他项不可见。 所以我检查了列表上的第一个元素(位置0处的项目)。我向下滚动查看所有列表,当我在第一个元素(位置0处的项目)向上滚动时,复选框被正确选中。伟大的但现在也有新项目被选中,例如位置8处的项目(因为当我滚动列表时(用于单击),它将成为位置0处的新项目。记住,我的屏幕一次只显示7个元素)。它被检查了,但我从来没有检查过 问题:我如何避免这个问题?我不想让我不点击的复选框改变他们的状态。
我拥有的内容:带有文本视图和复选框的自定义列表视图。
问题:假设我的屏幕一次只能显示列表中的6项,而其他项不可见。 所以我检查了列表上的第一个元素(位置0处的项目)。我向下滚动查看所有列表,当我在第一个元素(位置0处的项目)向上滚动时,复选框被正确选中。伟大的但现在也有新项目被选中,例如位置8处的项目(因为当我滚动列表时(用于单击),它将成为位置0处的新项目。记住,我的屏幕一次只显示7个元素)。它被检查了,但我从来没有检查过
问题:我如何避免这个问题?我不想让我不点击的复选框改变他们的状态。
下面是具有getView函数的listView适配器,我在其中实现了setOnCheckedChangeListener:
public class NewQAAdapterSelectFriends extends BaseAdapter {
private LayoutInflater mInflater;
private Person[] data;
public NewQAAdapterSelectFriends(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setData(Person[] data) {
this.data = data;
}
@Override
public int getCount() {
return data.length;
}
@Override
public Object getItem(int item) {
return data[item];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.nameText.setTag(viewHolder.surnameText);
viewHolder.contactImage.setTag(data[position]);
viewHolder.checkBox.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
Person element = (Person) viewHolder.checkBox.getTag();
if(isChecked){
element.setCheck(buttonView.isChecked());
//data[position].setCheck(true); //this is equivalent to previous line
}
else{
//to-do
}
}
});
viewHolder.checkBox.setTag(data[position]);
} else {
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.nameText.setText(data[position].getName());
holder.surnameText.setText(data[position].getSurname());
holder.contactImage.setImageResource(data[position].getPhotoRes());
holder.contactImage.setScaleType(ScaleType.FIT_XY);
holder.checkBox.setChecked(data[position].isCheck());
return convertView;
}
static class ViewHolder {
TextView nameText;
TextView surnameText;
ImageView contactImage;
CheckBox checkBox;
}
}
谢谢你的回答:) 编辑:根据建议,我更改了getView,如下所示:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
viewHolder=new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.nameText.setTag(viewHolder.surnameText);
viewHolder.contactImage.setTag(data[position]);
viewHolder.checkBox.setChecked(data[position].isCheck());
viewHolder.checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
if(viewHolder.checkBox.isChecked()==true)
data[position].setCheck(true);
else
data[position].setCheck(false);
}
});
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.nameText.setText(data[position].getName());
viewHolder.surnameText.setText(data[position].getSurname());
viewHolder.contactImage.setImageResource(data[position].getPhotoRes());
viewHolder.contactImage.setScaleType(ScaleType.FIT_XY);
viewHolder.checkBox.setChecked(data[position].isCheck());
return convertView;
}
编辑后的情况:现在,如果我检查屏幕上显示的初始项目,然后对列表进行scrool,那么它们的值将正确保存。但是当我滚动列表时,例如,我想检查列表的最后一个树复选框,然后在我滚动之后,它们将被取消勾选…但是为什么
已解决:我用以下代码解决了getView的问题:
public class NewQAAdapterSelectFriends extends BaseAdapter {
private LayoutInflater mInflater;
private Person[] data;
boolean[] checkBoxState;
ViewHolder viewHolder;
public NewQAAdapterSelectFriends(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setData(Person[] data) {
this.data = data;
checkBoxState=new boolean[data.length];
}
@Override
public int getCount() {
return data.length;
}
@Override
public Object getItem(int item) {
return data[item];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
viewHolder=new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.nameText.setText(data[position].getName());
viewHolder.surnameText.setText(data[position].getSurname());
viewHolder.contactImage.setImageResource(data[position].getPhotoRes());
viewHolder.contactImage.setScaleType(ScaleType.FIT_XY);
viewHolder.checkBox.setChecked(checkBoxState[position]);
viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(((CheckBox)v).isChecked()){
checkBoxState[position]=true;
data[position].setCheck(true);
}else{
checkBoxState[position]=false;
data[position].setCheck(false);
}
}
});
return convertView;
}
static class ViewHolder {
TextView nameText;
TextView surnameText;
ImageView contactImage;
CheckBox checkBox;
}
}
我已经看过这个教程来完成我的getView:您没有介绍案例convertView!=null,这是上下滚动时发生的情况。您应该实现一种方法来循环使用convertView(更好),或者忽略它,并在这种情况下返回一个新视图(更糟)。仅当convertView为空时,才设置复选框的标记。这只在第一屏记录中发生。当用户向下滚动时,将回收以前的视图。因此,您的复选框将旧数据项作为其标记 选中的更改侦听器应如下所示:
new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)
{
Person element = (Person) viewHolder.checkBox.getTag();
data[position].setCheck(isChecked);
if(isChecked)
{
// do your stuff
}
else
{
//to-do
}
}
}
检查此代码
public class NewQAAdapterSelectFriends extends BaseAdapter {
private LayoutInflater mInflater;
private Person[] data;
ArrayList<String> checkedItem=new ArrayList<String>();
public NewQAAdapterSelectFriends(Context context) {
mInflater = LayoutInflater.from(context);
}
public void setData(Person[] data) {
this.data = data;
}
@Override
public int getCount() {
return data.length;
}
@Override
public Object getItem(int item) {
return data[item];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_select_friends, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.nameText.setTag(viewHolder.surnameText);
viewHolder.contactImage.setTag(data[position]);
viewHolder.checkBox.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
Person element = (Person) viewHolder.checkBox.getTag();
if(isChecked){
getCheckList(data[position],isChecked);
}
else{
getCheckList(data[position],isChecked);
}
}
});
viewHolder.checkBox.setTag(data[position]);
}
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.nameText.setText(data[position].getName());
holder.surnameText.setText(data[position].getSurname());
holder.contactImage.setImageResource(data[position].getPhotoRes());
holder.contactImage.setScaleType(ScaleType.FIT_XY);
if(checkedItem != null && checkedItem.contains(data[position])){
viewHolder.checkBox.setChecked(true);
}else
{
viewHolder.checkBox.setChecked(false);
}
return convertView;
}
static class ViewHolder {
TextView nameText;
TextView surnameText;
ImageView contactImage;
CheckBox checkBox;
}
public void getCheckList(String value,boolean status){
if(!checkedItem.contains(value) && status)
{
checkedItem.add(value);
}
if(checkedItem.contains(value) && !status)
{
checkedItem.remove(value);
}
}
}
public类newqadapters选择扩展BaseAdapter{
私人停车场;
私人[]数据;
ArrayList checkedItem=新建ArrayList();
公共NewQAAdapterSelectFriends(上下文){
mInflater=LayoutInflater.from(上下文);
}
公共无效设置数据(个人[]数据){
这个数据=数据;
}
@凌驾
public int getCount(){
返回数据长度;
}
@凌驾
公共对象getItem(int项){
返回数据[项目];
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
if(convertView==null){
convertView=mInflater.flate(R.layout.item\u select\u friends,null);
最终ViewHolder ViewHolder=新的ViewHolder();
viewHolder.nameText=(TextView)convertView.findViewById(R.id.personName);
viewHolder.namestext=(TextView)convertView.findViewById(R.id.personSurname);
viewHolder.contactImage=(ImageView)convertView.findViewById(R.id.personImage);
viewHolder.checkBox=(checkBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(viewHolder);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.nameText.setTag(viewHolder.nameText);
viewHolder.contactImage.setTag(数据[位置]);
viewHolder.checkBox.setOnCheckedChangeListener(
新建CompoundButton.OnCheckedChangeListener(){
@凌驾
检查更改后的公共无效(复合按钮视图,布尔值已检查){
Person元素=(Person)viewHolder.checkBox.getTag();
如果(已检查){
getCheckList(数据[位置],已检查);
}
否则{
getCheckList(数据[位置],已检查);
}
}
});
viewHolder.checkBox.setTag(数据[位置]);
}
ViewHolder=(ViewHolder)convertView.getTag();
holder.nameText.setText(数据[position].getName());
holder.namestext.setText(数据[position].getNames());
holder.contactImage.setImageResource(数据[position].getPhotoRes());
holder.contactImage.setScaleType(ScaleType.FIT_XY);
if(checkedItem!=null&&checkedItem.contains(数据[位置]){
viewHolder.checkBox.setChecked(true);
}否则
{
viewHolder.checkBox.setChecked(false);
}
返回视图;
}
静态类视窗夹{
文本视图名称文本;
文本查看文本;
图像视图;
复选框;
}
public void getCheckList(字符串值,布尔状态){
如果(!checkedItem.contains(value)&&status)
{
checkedItem.add(值);
}
if(checkedItem.contains(value)&&!status)
{
checkedItem.remove(值);
}
}
}
检查下面的代码-
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
ViewHolder holder = new ViewHolder();
if(view == null){
view = inflater.inflate(R.layout.list_callcycle_blue, null);
holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container);
holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc);
holder.cb = (CheckBox) view.findViewById(R.id.cb_store);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
final Object data = getItem(position);
holder.lblLabel.setText(data.getDescription());
holder.cb.setTag(position);
holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int position = (Integer) buttonView.getTag();
objects.get(position).setChecked(buttonView.isChecked());
}
});
holder.cb.setChecked(isChecked(position));
return view;
}
请始终记住,在设置数据之前使用changeholder.cb.setOnCheckedChangeListener()
即任何侦听器,在我们的示例中,它是holder.cb.setChecked()
原因:当我们滚动时,listview将回收视图,因此如果在侦听器之前使用setchecked,则它将根据旧侦听器拾取值。如果我们在listener之后设置它,那么它将采用最新的值我解决了我的问题,只是将“setoncheckedchangeStener”更改为“setOnClickListener”
我有一个很好的复选框选择。您可以对ListView行使用
android:state\u activated=“true”
。它不会丢失状态,也不需要大量代码
下面是如何工作
- 在可绘图文件夹中创建
active_row.xml
使用setT
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
CheckBox cbItemChecklist = new CheckBox(context);
holder = new ViewHolder();
holder.cbItemChecklist = cbItemChecklist;
convertView = cbItemChecklist;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ItemChecklist itemChecklist = itensChecklist.get(position);
holder.cbItemChecklist.setText(itemChecklist
.getDescricaoItemChecklist());
holder.cbItemChecklist.setChecked(itemChecklist.isChecked());
holder.cbItemChecklist
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(itemChecklist.isChecked()){
itemChecklist.setChecked(false);
} else {
itemChecklist.setChecked(true);
}
}
});
return convertView;
}
<item android:state_activated="true"
android:drawable="@android:color/darker_gray"/>
</selector>
View v;
LinearLayout yourRowLayout;
for (int i = 0; i < yourListView.getChildCount(); i++) {
v = yourListView.getChildAt(i);
yourRowLayout = (LinearLayout) v.findViewById(R.id. yourRowLayout);
if(yourRowLayout.isActivated()){.... } }
holder.chk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox c = (CheckBox)v.findViewById(R.id.chkID);
Boolean chk = c.isChecked();
Integer pos = (Integer)v.getTag();
itemList.get(pos).setChk(chk);
}
});