Пользовательский список, содержащий проверенный вид текста - PullRequest
0 голосов
/ 11 марта 2020

Я реализую пользовательский просмотр списка, содержащий проверенный текстовый просмотр. Мой wi sh состоит в том, чтобы изменить состояние флажка при щелчке, но это не так просто, как я думал. Кроме того, я хотел бы проверить флажки элементов, которые хранятся в базе данных, как это можно сделать? В настоящее время у меня есть действие, которое показывает элементы, обрабатывает щелчок на флажке (не элемент списка!), Но не может изменить статус флажка элементами, хранящимися в базе данных.

Это мой пользовательский элемент списка:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="5dp">

    <CheckedTextView
            android:id="@+id/name"
            android:layout_width="409dp"
            android:layout_height="30dp"
            android:checkMark="?android:attr/listChoiceIndicatorMultiple"
            android:paddingStart="5dp"
            android:textSize="20sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    <TextView
            android:id="@+id/type"
            android:layout_width="409dp"
            android:layout_height="34dp"
            android:paddingStart="5dp"
            android:textSize="18sp"
            android:textStyle="italic"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/name" />

</androidx.constraintlayout.widget.ConstraintLayout>

Это мой адаптер:

public class CustomAdapter extends BaseAdapter
{
    private List<CustomElement> elems;
    private LayoutInflater inflater;

    public HueBulbAdapter(Context ctx, List<CustomElement> elems)
    {
        this.elems = elems;
        inflater = LayoutInflater.from(ctx);
    }

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

    @Override
    public Object getItem(int position)
    {
        return null;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ConstraintLayout result = (ConstraintLayout) inflater.inflate(R.layout.custom_elems, parent, false);
        CheckedTextView name = result.findViewById(R.id.name);
        TextView type = result.findViewById(R.id.type);
        CustomElement elem = elems.get(position);
        name.setText(elem.getName());
        type.setText(elem.getType());
        result.setTag(position);
        toggle(name);
        return result;
    }

    private void toggle(CheckedTextView ctv) {
        ctv.setOnClickListener(v -> {
            ctv.setChecked(!ctv.isChecked());
        });
    }
}

И это моя деятельность:

[...]
elemsView.setOnItemClickListener((parent, view, position, id) ->
        {
            if (!selected.containsKey(elemList.get(position).getName()))
            {
                selected.put(elemList.get(position).getName(), elemList.get(position));
            } else
            {
                selected.remove(elemList.get(position).getName());
            }
        });
[...]

Может быть, я использую неправильные компоненты для достижения своей цели? Любые идеи, как это сделать так или лучше?

Спасибо за вашу помощь!

1 Ответ

1 голос
/ 12 марта 2020

Несколько предложений:

  1. Добавьте логическую переменную в модель CustomElement, чтобы отслеживать, отмечен элемент или нет. Добавьте private boolean isChecked; и сгенерируйте для него метод получения и установки.

  2. В классе адаптера используйте public Object getItem(int position) для возврата элемента в списке, а не null. Измените на return elems.get(position);

  3. В классе адаптера замените toggle(name) на:

    name.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        elem.setChecked(!elem.isChecked());  // toggle
        name.setChecked(elem.isChecked());
      }
    });
    
  4. В вашем классе деятельности для доступа к обновленный список, используйте это:

    for (int i = 0; i < mAdapter.getCount(); i++) {
      CustomElement element = (CustomElement) mAdapter.getItem(i);
      if (element.isChecked()) {...} else {...}
    }
    
  5. Необязательно. Найдите и внедрите ViewHolder Pattern в классе адаптера, чтобы улучшить скорость загрузки элементов ListView.

...