fragmentManager и RecyclerView
Логично ли передавать fragmentManager в RecyclerView для "переключения" фрагментов? Возникнут ли утечки памяти? Если нелогично, опишите пример реализации.
Ответы (1 шт):
Автор решения: Sergei Buvaka
→ Ссылка
RecyclerView не должен знать ничего о сущностях которые находятся за его пределами. Так вы нарушаете "Принцип единой ответственности".
Задача RecyclerView - рисовать список. И единственные сущности о которых он должен знать - это модели которые отображают состояние вашего Item-а.
- Если вы добавите туда FragmentManager - то вы больше не сможете использовать ваш RecyclerView в сущностях где нет FragmentManager.
- Если вы захотите переиспользовать это адаптер в другом месте и там к примеру по клику должна будет открываться активити, то ваш адаптер будет знать о FragmentManager, который ему будет совершенно не нужен.
- Ну а если в самом адаптере будет жестко зашита логика клика, то вы в принципе не сможете изменить поведение клика для разных кейсов.
Решение
Создаете интерфейс вроде такого:
interface OnItemClickListener {
void onItemClick(item: YourModelClass)
}
В активити:
class SomeActivity extends AppCompatActivity implements OnItemClickListener {
// другие методы активити
@Override
void onItemClick(item: YourModelClass) {
// ваша логика по клику на элемент списка. Здесь вы можете свободно использовать ваш FragmentManager
}
}
В адаптере:
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private List<YourModelClass> items;
private OnItemClickListener clickListener;
MyRecyclerViewAdapter(List<YourModelClass> items, OnItemClickListener clickListener) {
this.items = items;
this.clickListener = clickListener;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.onItemClick(items.get(position));
}
});
}
// другие методы адаптера
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ViewHolder(View itemView) {
super(itemView);
}
}