CustomAdapter - CheckedTextView
У меня проблема с "запоминанием" состояний флажков в CheckTextView. Теперь, когда я нажимаю, он меняет состояние, но на другом CheckBox.
class CustomAdapterSmartwatch extends ArrayAdapter<String> {
static class ViewHolder {
protected CheckedTextView cTextView;
}
ViewHolder holder;
public CustomAdapterSmartwatch(Context context, ArrayList<String> variables) {
super(context,R.layout.row_smartwatch_resources,variables);
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater smartwatchinflater = LayoutInflater.from(getContext());
convertView = smartwatchinflater.inflate(R.layout.row_smartwatch_resources,parent,false);
holder.cTextView = (CheckedTextView) convertView.findViewById(R.id.row_smartwatch_checked);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.cTextView.setText(getItem(position));
holder.cTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.cTextView.isChecked()) {
holder.cTextView.setChecked(false);
} else {
holder.cTextView.setChecked(true);
}
}
});
return convertView;
}
}
Сейчас я пытаюсь разобраться с использованием Holder, но я слышал, что можно использовать SparseBooleanArray. Может кто-нибудь объяснить, как заставить это работать?
РЕДАКТИРОВАТЬ 1 Хорошо, у меня есть ListView, который контролируется CustomAdapter. Этот адаптер содержит только 1 элемент (CheckedTextView). Проблема в том, что после прокрутки эти флажки не запоминают их состояние. Я видел ваш ответ с объяснением, но теперь после нажатия любого "CheckedTextView" состояние их флажка не меняется.
РЕДАКТИРОВАТЬ 2
@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater smartwatchinflater = LayoutInflater.from(getContext());
convertView = smartwatchinflater.inflate(R.layout.row_smartwatch_resources,parent,false);
holder.cTextView = (CheckedTextView) convertView.findViewById(R.id.row_smartwatch_checked);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.cTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("MainActivity","Position = " + position);
CheckedTextView checkedText = (CheckedTextView) v;
checkedState.put(position, !checkedText.isChecked());
Log.d("MainActivity","State = " + checkedState.get(position));
}
});
holder.cTextView.setText(getItem(position));
holder.cTextView.setChecked(checkedState.get(position));
return convertView;
}
РЕДАКТИРОВАТЬ 3
class CustomAdapterSmartwatch extends ArrayAdapter<String> {
public SparseBooleanArray checkedState = new SparseBooleanArray();
private CheckedTextView cTextView;
public CustomAdapterSmartwatch(Context context, ArrayList<String> variables) {
super(context,R.layout.row_smartwatch_resources,variables);
}
@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater smartwatchinflater = LayoutInflater.from(getContext());
convertView = smartwatchinflater.inflate(R.layout.row_smartwatch_resources,parent,false);
cTextView = (CheckedTextView) convertView.findViewById(R.id.row_smartwatch_checked);
cTextView.setText(getItem(position));
cTextView.setChecked(checkedState.get(position));
cTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("MainActivity","Position = " + position);
CheckedTextView checkedText = (CheckedTextView) v;
checkedText.toggle();
if (checkedText.isChecked())
checkedState.put(position,true);
else
checkedState.delete(position);
Log.d("MainActivity","State = " + checkedState.get(position));
}
});
return convertView;
}
}
3 ответа
Вы должны сохранять логический флаг для каждого CheckTextView. Это может быть массив, список или SparseBooleanArray. Выбранная вами структура данных должна быть областью вашего адаптера:
class CustomAdapterSmartwatch extends ArrayAdapter<String> {
private SparseBooleanArray checkedState = new SparseBooleanArray();
// ...
}
Вы не хотите помещать его в держатель, потому что держатель удаляется только из видимых рядов. С другой стороны, вы хотите сохранить проверенное состояние для каждой строки, видимой или нет.
Теперь вы устанавливаете сохраненное проверенное состояние, когда пользователь нажимает на CheckedTextView
:
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// ...
holder.cTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckedTextView checkedText = (CheckedTextView)v;
checkedState.put(position, checkedText.isChecked());
}
});
}
И вы восстанавливаете проверенное состояние всякий раз, когда вы раздуваете представление или повторно используете его из держателя:
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// ...
holder.cTextView.setText(getItem(position));
holder.cTextView.setChecked(checkedState.get(position));
// ...
}
Вы можете просто использовать представление в самом методе onClick().
holder.cTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(v instanceOf CheckedTextView) {
CheckedTextView c = (CheckedTextView) v;
c.setChecked(!c.isChecked());
}
}
});
Замените ваш код следующим обновлением:
class CustomAdapterSmartwatch extends ArrayAdapter<CustomAdapterSmartwatch.MyPojo> {
class MyPojo {
boolean checked;
String data;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
static class ViewHolder {
protected CheckedTextView cTextView;
}
ViewHolder holder;
public CustomAdapterSmartwatch(Context context, ArrayList<MyPojo> variables) {
super(context, R.layout.row_smartwatch_resources, variables);
}
@Nullable
@Override
public MyPojo getItem(int position) {
return super.getItem(position);
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater smartwatchinflater = LayoutInflater.from(getContext());
convertView = smartwatchinflater.inflate(R.layout.row_smartwatch_resources,parent,false);
holder.cTextView = (CheckedTextView) convertView.findViewById(R.id.row_smartwatch_checked);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final MyPojo item = getItem(position);
holder.cTextView.setText(item.getData());
holder.cTextView.setChecked(item.isChecked());
holder.cTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean nextStatus = !item.isChecked();
item.setChecked(nextStatus);
holder.cTextView.setChecked(nextStatus);
}
});
return convertView;
}
}