Автоматический вызов checkbox onCheckedChange при прокрутке списка?
У меня проблема с списком, в элементе списка которого есть флажок. Когда я устанавливаю флажок и список прокрутки, когда-нибудь происходит автоматический вызов oncheckedchange, а значение флажка изменяется!
Или, когда мой список содержит более 9 или 10 элементов, тогда, когда я проверял элемент 1, проверяется пункт 8 или 9???
Кто-нибудь может сказать мне, что я исправить эту ошибку?
Спасибо заранее!
list_item.xml
<ImageView
android:layout_alignParentLeft="true"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_centerVertical="true"
android:scaleType="fitCenter"
android:id="@+id/image_view"
android:src="@drawable/icon" />
<TextView android:layout_toRightOf="@id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dip"
android:id="@+id/text_view"
android:lines="1"
android:textSize="20sp"
android:textColor="@color/white" />
<TextView android:layout_toRightOf="@id/image_view"
android:layout_below="@id/text_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dip"
android:id="@+id/text_view2"
android:textSize="14sp"
android:lines="1"
android:textColor="@color/white" />
и вот вид адаптера:
public View getView(int position, View convertView, ViewGroup parent) {
Log.e(TAG, "getView");
ViewHolder mViewHolder;
if (convertView == null) {
Log.e(TAG, "Inflater is inflating...");
convertView = mInflater.inflate(R.layout.custom_list_app, null);
mViewHolder = new ViewHolder();
mViewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.checkbox);
mViewHolder.remove = convertView.findViewById(R.id.music_info);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
Log.e(TAG, "Position: " + position + " CheckBox: " + mViewHolder.checkbox.isChecked());
}
mViewHolder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton cb, boolean flag) {
// TODO Auto-generated method stub
if (flag) {
Log.d(TAG, "Checkbox checked");
} else {
Log.d(TAG, "Checkbox un-checked");
}
}
});
return convertView;
}
Ответы
Ответ 1
ListView
перерабатывает классы представления: вам нужно явно указать, проверяется ли CheckBox в классе getView
. Поэтому добавьте чек, например
/**
* Ensure no other setOnCheckedChangeListener is attached before you manually
* change its state.
*/
mViewHolder.checkbox.setOnCheckedChangeListener(null);
if(shouldBeChecked) mViewHolder.checkbox.setChecked(true);
else mViewHolder.checkbox.setChecked(false);
прежде чем вы вызовете setOnCheckedChangeListener
.
Ответ 2
holder.cBox.setOnCheckedChangeListener(null);
holder.cBox.setChecked(list.get(position).isChecked());
holder.tvName.setText(item.getName());
holder.cBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if (isChecked)
{
list.get(position).setChecked(true);
}
else
{
list.get(position).setChecked(false);
}
}
});
В списке элемент имеет атрибут, чтобы установить, отмечен ли элемент или нет. Вы можете использовать это, чтобы установить элемент, если он установлен, и сначала вы должны установить
cBox.setOnCheckedChangeListener(null);
cBox.setChecked(list.get(position).isChecked());
Затем установите реальный new OnCheckedChangeListener()
Надеюсь, мой ответ будет полезен для вас и для тех, кто смотрит на эту страницу, или у вас проблемы со списками, которые имеют флажки элементов.
Ответ 3
Я не уверен, что это аккуратный способ. Но приведенный ниже код решил мою проблему. Даже в приведенном ниже коде функция setOnCheckChangeListener() вызывалась (считывается ложно) при прокрутке списка. Задача состояла в том, чтобы сохранить список элементов, выбранных пользователем. Поэтому, когда есть триггер, я сначала ссылаюсь на свой список и добавляю элемент только в том случае, если он еще не присутствовал в списке, иначе я игнорирую обратный вызов.
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
MenuViewHolder menuViewHolder = null;
MenuView item = getItem(position);
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(R.layout.food_menu_list_layout, null);
TextView textView = ((TextView) convertView.findViewById(R.id.menu_item_entry));
TextView price = (TextView) convertView.findViewById(R.id.price);
CheckBox ordered = (CheckBox) convertView.findViewById(R.id.checkBox);
menuViewHolder = new MenuViewHolder(textView, price, ordered);
menuViewHolder.dishName.setText(menuViewList.get(position).getItemname());
menuViewHolder.price.setText("$" + menuViewList.get(position).getPrice());
menuViewHolder.ordered.setChecked(menuViewList.get(position).isSelected());
menuViewHolder.ordered.setOnCheckedChangeListener(null);
menuViewHolder.ordered.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
MenuView checkedItem = menuViewList.get(position);
if (buttonView.isChecked()) {
//add item only if not already added
if (!checkedItem.isSelected()) {
MainActivity.menuViews.add(checkedItem);
checkedItem.setSelected(buttonView.isChecked());
}
} else {
//remove only if already added
if (checkedItem.isSelected()){
MainActivity.menuViews.remove(checkedItem);
checkedItem.setSelected(buttonView.isChecked());
}
}
((MainActivity) context).displayCurrentSelectionAmt();
}
});
return convertView;
}
Ответ 4
Большинство из них слишком вовлечены (но они действительно работают). Все, что вы пытаетесь сделать, это остановить событие .setChecked от стрельбы, если просмотр загружается и установить статус проверки. Итак, установите локальную переменную класса isLoading, установите ее в true в начале getView и установите для нее значение false в конце getView. Затем в прослушивателе кликов установите флажок isLoading
boolean isLoading;
public View getView(int position, View convertView, ViewGroup parent){
isLoading = true;
...do your initialization here
isLoading = false;
return convertView;
}
checkview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton pckView, boolean pisChecked) {
if(! isLoading) {
...do your things when the check is actually clicked
}
}
});
Ответ 5
OnClickListener работает для меня с той же проблемой, и я могу отправить данные в другую деятельность.
holder.cks.setOnClickListener(новый View.OnClickListener() {
@Override
public void onClick(View v) {
final boolean isChecked = holder.cks.isChecked();
if (isChecked) {
System.out.println(position + "Checked");
holder.cks.setChecked(true);
positionArray.set(position, true);
DATA2="1";
} else {
System.out.println(position + "unChecked");
holder.cks.setChecked(false);
positionArray.set(position, false);
DATA2 = "0";
}
DATA1=String.valueOf(position+1);
DATA3=map.get(COL5);
DATA4=map.get(COL6);
DATA5=map.get(COL7);
Intent intent = new Intent(activity, updatelicaldata.class);
intent.putExtra("message1", DATA1);
intent.putExtra("message2", DATA2);
intent.putExtra("message3", DATA3);
intent.putExtra("message4", DATA4);
intent.putExtra("message5", DATA5);
System.out.println("ACTIVITY IS START");
activity.startActivity(intent);
}
});