2017-02-17 5 views
0

У меня проблема с «запоминанием» состояний флажков в CheckTextView. Теперь, когда я нажимаю, он меняет состояние, но на другой CheckBox.CustomAdapter - CheckedTextView

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; 
} 

}

Теперь я пытаюсь выяснить, с помощью держателя, но я слышал, что можно использовать SparseBooleanArray. Может кто-нибудь объяснить, как заставить его работать?

EDIT 1 Хорошо, у меня есть ListView, который контролируется CustomAdapter. Этот адаптер содержит только 1 элемент (CheckedTextView). Проблема в том, что после прокрутки эти флажки не запоминают их состояние. Я видел ваш ответ с объяснением, но теперь, щелкнув любой «CheckedTextView», состояние их флажка не изменяется.

EDIT 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; 
} 

EDIT 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; 
} 

}

+0

Ваше изменение более подходит как комментарий к моему ответу или как новый вопрос. –

ответ

0

Вы должны держать логический флаг для каждого CheckTextView. Это может быть массив, List или SparseBooleanArray. Структура данных вы выбираете, должен быть полем адаптера:

class CustomAdapterSmartwatch extends ArrayAdapter<String> { 
    private SparseBooleanArray checkedState = new SparseBooleanArray(); 

    // ... 
} 

Вы не хотите, чтобы положить его в держатель, поскольку держатель погашается только FR видимых строк. С другой стороны, вы хотите сохранить проверенное состояние для каждой строки, видимой или нет.

Теперь вы установили хранимую проверили состояние, когда пользователь нажимает на 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)); 

    // ... 
} 
+0

Отметьте мое редактирование (верхний ответ) – Ace

+0

@Ace В настоящее время мой ответ - это «верхний» ответ при загрузке этой страницы. Обратите внимание, что SO переупорядочивает ответы на основе голосов и рандомизирует те, которые связаны. –

+0

Я имел в виду эту должность, где я задал вопрос;) – Ace

-1

Заменить код с следующим обновлением:

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; 
    } 
} 
+0

нет подходящего конструктора найден для ArrayAdapter (контекста, INT, ArrayList ) конструктора ArrayAdapter.ArrayAdapter (контекст, Int, Int) не применяется (аргумент несоответствия; ArrayList не может быть преобразован в Int) конструктор Но ArrayList не может быть изменено. – Ace

+0

Изменение конструктора на 'CustomAdapterSmartwatch (контекст контекста, переменные ArrayList )' –

+0

Пожалуйста, объясните, как ваши изменения кода OP разрешат его проблему. –

-1

Вы можете просто использовать вид в 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()); 
      } 
     } 
    }); 
+0

Нет причин для 'instanceOf', поскольку вы только устанавливаете этот прослушиватель для экземпляров CheckedTextView. Кроме того, CheckedTextView уже отслеживает свое собственное проверенное состояние при нажатии. Нет причин писать код для этого. –