Как установить OnClickListener в расширяемый RecycleView - PullRequest
0 голосов
/ 05 октября 2019

Я хочу установить OnClickListeners для элементов из моего расширяемого повторного просмотра. У каждого элемента из повторного просмотра должна быть кнопка (например, https://imgur.com/qlEJCkk: кнопка + для добавления задач и кнопка «x» для каждой задачи, чтобы удалить ее)

Я пытался реализовать ееиз некоторых других примеров onClickListeners, но пока ничего не работает

это АДАПТЕР:

public class ExpandableAdapter extends ExpandableRecyclerViewAdapter<RoutineViewHolder, TaskViewHolder> {
    public ExpandableAdapter(List<? extends ExpandableGroup> groups) {
        super(groups);
    }

    @Override
    public RoutineViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.expandable_recyclerview_routine, parent, false);
        return new RoutineViewHolder(v);
    }

    @Override
    public TaskViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.expandable_recyclerview_task, parent, false);
        return new TaskViewHolder(v);
    }

    @Override
    public void onBindChildViewHolder(TaskViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
        final Tasks tasks = (Tasks) group.getItems().get(childIndex);
        holder.bind(tasks);

    }

    @Override
    public void onBindGroupViewHolder(RoutineViewHolder holder, int flatPosition, ExpandableGroup group) {
        final Routine routine = (Routine) group;
        holder.bind(routine);

    }

RoutineViewHolder:

import com.thoughtbot.expandablerecyclerview.viewholders.GroupViewHolder;

public class RoutineViewHolder extends GroupViewHolder implements View.OnClickListener {
    private TextView mTextView;



    public RoutineViewHolder(View itemView) {
        super(itemView);

        mTextView = itemView.findViewById(R.id.exp_routine);
        itemView.setOnClickListener(this);
    }


    public void bind(Routine routine){
        mTextView.setText(routine.getTitle());
    }


}

TaskViewHolder:

public class TaskViewHolder extends ChildViewHolder {
    private TextView mTextView;
    private CheckBox mCheckBox;
    private Boolean checkVal;

    public TaskViewHolder(View itemView) {
        super(itemView);
        mTextView = itemView.findViewById(R.id.exp_task);
        mCheckBox=itemView.findViewById(R.id.exp_task_checkbox);
    }

    public void bind(Tasks tasks) {
        mTextView.setText(tasks.name);
        checkVal=((tasks.checkBox==1)?Boolean.TRUE:Boolean.FALSE);
        mCheckBox.setChecked(checkVal);
    }
}

как видите, у меня есть 2 ViewHolders: RoutineViewHolder и TaskViewHolder. Я очень смущен тем, где и как я должен установить OnClickListener, так как я хочу, чтобы он вел себя по-разному для «Рутин» и «Задач», потому что у них были бы разные кнопки.

«Задачи» должны иметь кнопку +чтобы добавить задачи под ним, и каждая задача должна иметь кнопку X, чтобы удалить эту конкретную задачу

расширяемый повторный просмотр состоит из еще 2 из этих категорий «Задачи».

Ответы [ 2 ]

1 голос
/ 06 октября 2019

Я бы предпочел решение, в котором я могу прослушивать все эти обратные вызовы с более высокого уровня (например, Activity), где я могу изменять объекты данных и обновлять RecyclerView, чтобы синхронизировать вещи на основе обратных вызовов. (Это в конечном итоге то, что вам нужно, если вы масштабируете это.)

Я реализовал ваш код и немного изменил, чтобы получить ожидаемый результат. Sample result

Для этого решения:

  • Я создал интерфейс для получения обратных вызовов
    • При добавлении нажална Рутине
    • При удалении щелкнул по Задаче
    • При проверке статус изменился на Задаче
  • Сделал мое действие для реализации этого интерфейса и передал его адаптеру.
  • Адаптер передает его ViewHolder
  • ViewHolder будет вызывать требуемую функцию при нажатии.
  • В ответных вызовах:
    • Для ADD: Вы можете знать, какая процедура быланажал
    • Для удаления: вы можете знать ParentRoutine, дочерний индекс задачи и задачи
    • Для проверки изменений: Вы можете знать ParentRoutine, дочерний индекс задачи, задачи и состояние новой проверки.

Код

1. Добавить новый файл ListActionListener.java

Это интерфейс.

public interface ListActionListener {
       // Know add was clicked on given routine
       void onAddTaskClicked(Routine routine);
       // Know delete was clicked on given task.
       void onDeleteTaskClicked(Routine routine, Tasks task, int index);
       // Know checkbox clicked on given task (with new checked status)
       void onTaskCheckChanged(Routine routine, Tasks task, int index, boolean checked);
}

2. Заставьте свою деятельность реализовать этот интерфейс. ExpandableListActivity.java

Это мой пример активности, который вы видите на скриншотах.

public class ExpandableListActivity extends AppCompatActivity implements ListActionListener{
    ExpandableAdapter adapter;
    RecyclerView recyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_expandable_list);
        recyclerView = findViewById(R.id.recyclerView);
        loadList();
    }

    private void loadList() {
        List<Routine> routines = getDummyRoutineList();
        adapter = new ExpandableAdapter(routines, this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
    }

    private List<Routine> getDummyRoutineList() {
        List<Routine> list = new ArrayList<Routine>();
        Tasks rt1 = new Tasks("R1 Tasks1", 1);
        Tasks rt2 = new Tasks("R1 Tasks2", 0);
        Tasks rt3 = new Tasks("R1 Tasks3", 1);
        Tasks rt4 = new Tasks("R1 Tasks4", 0);
        Tasks rt5 = new Tasks("R1 Tasks5", 0);
        List<Tasks> r1Tasks = new ArrayList<>();
        r1Tasks.add(rt1);
        r1Tasks.add(rt2);
        r1Tasks.add(rt3);
        r1Tasks.add(rt4);
        r1Tasks.add(rt5);
        Routine r1 = new Routine("Routine 1", r1Tasks);


        Tasks r2t1 = new Tasks("R2 Tasks1", 1);
        Tasks r2t2 = new Tasks("R2 Tasks2", 0);
        Tasks r2t3 = new Tasks("R2 Tasks3", 1);
        Tasks r2t4 = new Tasks("R2 Tasks4", 0);
        Tasks r2t5 = new Tasks("R2 Tasks5", 1);
        List<Tasks> r2Tasks = new ArrayList<>();
        r2Tasks.add(r2t1);
        r2Tasks.add(r2t2);
        r2Tasks.add(r2t3);
        r2Tasks.add(r2t4);
        r2Tasks.add(r2t5);
        Routine r2 = new Routine("Routine 2", r2Tasks);

        list.add(r1);
        list.add(r2);
        return list;
    }

    @Override
    public void onAddTaskClicked(Routine routine) {
        Toast.makeText(this, "On Add Clicked", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onDeleteTaskClicked(Routine routine, Tasks task, int index) {
        Toast.makeText(this, "On Delete Clicked", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onTaskCheckChanged(Routine routine, Tasks task, int index, boolean checked) {
        Toast.makeText(this, "On Check changed:"+checked, Toast.LENGTH_SHORT).show();
    }
}

3. Добавить кнопку «X» в макет строки задач

Это мой пример XML-файла, ваш XML может выглядеть иначе. Главное, чтобы добавить кнопку Удалить.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="8dp"
    >

    <Button
        android:id="@+id/btn_delete"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="X"
        />

    <CheckBox
        android:id="@+id/exp_task_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        />

    <TextView
        android:id="@+id/exp_task"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/btn_delete"
        android:layout_toRightOf="@+id/exp_task_checkbox"
        />

</RelativeLayout>

4. Добавьте кнопку «+» в файл Routine Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="8dp"
    >

    <Button
        android:id="@+id/btn_add"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="+"
        />

    <TextView
        android:id="@+id/exp_routine"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/btn_delete"
        android:layout_toRightOf="@+id/exp_task_checkbox"
        />

</RelativeLayout>

5. Обновите адаптер, чтобы принять ListActionListener

public class ExpandableAdapter extends ExpandableRecyclerViewAdapter<RoutineViewHolder, TaskViewHolder> {
    ListActionListener listActionListener;
    public ExpandableAdapter(List<? extends ExpandableGroup> groups, ListActionListener listActionListener) {
        super(groups);
        this.listActionListener = listActionListener;
    }

    @Override
    public RoutineViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.expandable_recyclerview_routine, parent, false);
        return new RoutineViewHolder(v);
    }

    @Override
    public TaskViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.expandable_recyclerview_task, parent, false);
        return new TaskViewHolder(v);
    }

    @Override
    public void onBindChildViewHolder(TaskViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
        final Tasks tasks = (Tasks) group.getItems().get(childIndex);
        holder.bind((Routine)group, childIndex, tasks, listActionListener);
    }

    @Override
    public void onBindGroupViewHolder(RoutineViewHolder holder, int flatPosition, ExpandableGroup group) {
        final Routine routine = (Routine) group;
        holder.bind(routine, listActionListener);

    }
}

6. Обновление TaskViewHolder.java

Чтобы принять слушателя и вызвать обратный вызов

public class TaskViewHolder extends ChildViewHolder {
    private TextView mTextView;
    private CheckBox mCheckBox;
    private Boolean checkVal;
    private Button btnDelete;

    public TaskViewHolder(View itemView) {
        super(itemView);
        mTextView = itemView.findViewById(R.id.exp_task);
        mCheckBox=itemView.findViewById(R.id.exp_task_checkbox);
        btnDelete = itemView.findViewById(R.id.btn_delete);

    }

    public void bind(final Routine parentRoutine, final int childIndex, final Tasks tasks, final ListActionListener listActionListener) {
        mTextView.setText(tasks.name);
        checkVal=((tasks.checkBox==1)?Boolean.TRUE:Boolean.FALSE);
        mCheckBox.setChecked(checkVal);
        //add delete button click
        btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                listActionListener.onDeleteTaskClicked(parentRoutine, tasks, childIndex);
            }
        });

        mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
                //to avoid initial call back
                if(checked != checkVal) {
                    listActionListener.onTaskCheckChanged(parentRoutine, tasks, childIndex, checked);
                    checkVal = checked;
                }
            }
        });
    }
}

7. Обновление RoutineViewHolder.java

Чтобы принять слушателя и вызвать обратный вызов.

public class RoutineViewHolder extends GroupViewHolder implements View.OnClickListener {
    private TextView mTextView;
    private Button btnAdd;

    public RoutineViewHolder(View itemView) {
        super(itemView);
        mTextView = itemView.findViewById(R.id.exp_routine);
        btnAdd = itemView.findViewById(R.id.btn_add);
        itemView.setOnClickListener(this);
    }


    public void bind(final Routine routine, final ListActionListener listActionListener) {
        mTextView.setText(routine.getTitle());
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                listActionListener.onAddTaskClicked(routine);
            }
        });
    }
}

Бинго .... Запустите код ... :)

0 голосов
/ 05 октября 2019

Вы пытались вызвать setChildClickListener вашего объекта ExpandableAdapter из вашей деятельности?

Посмотрите на это:

ExpandableAdapter adapter=new ExpandableAdapter(myExpandableGroupList);
adapter.setChildClickListener(new OnCheckChildClickListener() {
@Override
public void onCheckChildCLick(View v, boolean checked, CheckedExpandableGroup group,int childIndex) {

    }
 });

Надеюсь, это поможет вам.

...