2015-03-12 4 views
0

Это мой custom_list.xmlCheckbox внутри ListView пользовательского адаптера

<CheckBox 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/cb" 
    android:layout_marginLeft="16dp" 
    android:layout_gravity="center" 
    android:checked="true" /> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/nameTV" 
    android:layout_gravity="center" 
    android:textSize="22sp" 
    android:padding="16dp" /> 

и это мой CustomAdapter.java

private Context context; 
private ArrayList<String> arrayList; 
private CompoundButton.OnCheckedChangeListener onCheckedChangeListener; 
private boolean[] mItemChecked; 

public CustomAdapter(Context context, ArrayList<String> arrayList, CompoundButton.OnCheckedChangeListener onCheckedChangeListener) { 
    this.context = context; 
    this.arrayList = arrayList; 
    this.onCheckedChangeListener = onCheckedChangeListener; 
    mItemChecked = new boolean[arrayList.size()]; 
    for (int i=0; i<arrayList.size(); i++){ 
     mItemChecked[i] = true; 
    } 
} 

private static class ViewHolder { 
    TextView tv; 
    CheckBox cb; 
} 

@Override 
public int getCount() { 
    return arrayList.size(); 
} 

@Override 
public Object getItem(int position) { 
    return arrayList.get(position); 
} 

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

public boolean itemIsChecked(int position){ 
    return mItemChecked[position]; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    if (convertView == null) { 
     convertView = inflater.inflate(R.layout.custom_list, parent, false); 
     holder = new ViewHolder(); 
     holder.tv = (TextView) convertView.findViewById(R.id.nameTV); 
     holder.cb = (CheckBox) convertView.findViewById(R.id.cb); 
     convertView.setTag(holder); 
    }else{ 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.tv.setText(arrayList.get(position)); 
    holder.cb.setOnCheckedChangeListener(onCheckedChangeListener); 
    return convertView; 
} 

Пока все работает отлично, есть одна проблема: флажки из строк 1, 2, 3 ... привязаны к флажкам из строк 8, 9, 10 ... поэтому, когда я снимаю флажок 1 и прокручивается до флажка 8, он также не установлен, и наоборот. Я думаю, что это связано с держателем вида, который не правильно перерабатывает флажки и использует для строк 1 и 8 тот же флажок. Любые предложения по преодолению этой проблемы?

ответ

-1

convertView в getView ранее использовался View с учетом предыдущих данных! Поэтому вам нужно заполнить свой View правильными данными каждый раз в getView. В вашем коде я не вижу, где вы устанавливаете состояние checkbox. Тебе следует это сделать. Как вы делаете для TextViewholder.tv.setText(arrayList.get(position));

Update

Вот пример кода. Взгляните на getView. Другие вещи, такие как создание исходных данных или структуры данных, упрощаются.

public class CustomAdapter extends BaseAdapter { 

    private List<String> arrayList = new ArrayList<>(30); 
    private boolean[] mItemChecked = new boolean[30]; 
    private Context mContext; 

    public CustomAdapter(Context context) { 
     mContext = context; 
     for (int i = 0; i < 30; i++) { 
      arrayList.add("text: " + i); 
      mItemChecked[i] = false; 
     } 
    } 

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

    @Override 
    public Object getItem(int position) { 
     return arrayList.get(position); 
    } 

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

    public boolean itemIsChecked(int position) { 
     return mItemChecked[position]; 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     final ViewHolder holder; 
     LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     if (convertView == null) { 
      convertView = inflater.inflate(R.layout.list_item, parent, false); 
      holder = new ViewHolder(); 
      holder.tv = (TextView) convertView.findViewById(R.id.nameTV); 
      holder.cb = (CheckBox) convertView.findViewById(R.id.cb); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     holder.tv.setText(arrayList.get(position)); 
     //Important to remove previous listener before calling setChecked 
     holder.cb.setOnCheckedChangeListener(null); 
     holder.cb.setChecked(mItemChecked[position]); 
     holder.cb.setTag(position); 
     holder.cb.setOnCheckedChangeListener(
       new CompoundButton.OnCheckedChangeListener() { 
        @Override 
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
         mItemChecked[position] = isChecked; 
        } 
       }); 
     return convertView; 
    } 

    private class ViewHolder { 
     TextView tv; 
     CheckBox cb; 

    } 
} 

ListView перерабатывает свое мнение в методе getView(). Добавьте эти два метода:

public int getViewTypeCount() {     
    return getCount(); 
} 

@Override 
public int getItemViewType(int position) { 
    return position; 
} 
+0

Yap, вот что я, пожалуй, было проблемой, я просто не мог найти правильный способ сделать это. У вас есть идея, как я могу получить правильное состояние флажка для каждой строки даже после прокрутки строки от представления? – Bimba

+0

@Bimba Добавлен образец кода. Взгляните на 'getView'. Имейте в виду, что другие вещи упрощаются. Вы должны сами выбрать соответствующие структуры данных для хранения данных. – MyDogTom

+0

Большое спасибо брату, он действительно разрешил мою проблему, но с этим возникла еще одна проблема ... Теперь он не сохраняет флажки состояния всякий раз, когда он перерабатывается. Поэтому, если я проверю один из флажков, чем прокрутку вниз, а затем прокрутку назад, он не будет отмечен. – Bimba

Смежные вопросы