Как вызвать getFragmentManager на Recycler.Adapter?
Я конвертирую ListView моего приложения в RecyclerView. В ListView было очень легко реализовать OnClickListener, но в RecyclerView мы должны сделать это в адаптере. Я хочу открыть новый фрагмент, когда пользователь нажимает на элемент. Для этого мне нужно вызвать FragmentManager в адаптере, который я не могу сделать.
Это мой код RecyclerAdapter:
public ListItemViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//Call FragmentManager and add Fragment to it.
}
}
Итак, как вызвать FragmentManager и добавить в него фрагменты. Есть ли лучший способ, чем это, например sendBroadcast или любой другой метод.
Ответы
Ответ 1
Вам просто нужен контекст активности, переданный в вашем конструкторе. Обязательно вызовите new Adapter(this,...)
из действий и new Adapter(getActivity(),...)
из фрагментов.
private Context context;
@Override
public void onClick(View v) {
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
}
Ответ 2
Чтобы добавить к утвержденному ответу: если вы все еще получаете ошибку, вам, возможно, придется заменить эту строку;
FragmentManager manager = ((Activity)context).getFragmentManager();
С этим
FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
Для меня это было потому, что я использовал support.v4.app.FragmentManager
вместо обычного fragmentmanager
Все еще получаете ошибку?
Как указано в одном из комментариев ниже, это может ... cannot be cast to android.support.v7.app.AppCompatActivity
исключение java.lang.ClassCastException:
и log ... cannot be cast to android.support.v7.app.AppCompatActivity
(подробнее см. Комментарии).
Их исправление состояло в том, чтобы использовать это вместо этого (я не проверял это, но это работало для них):
((AppCompatActivity)activity).getSupportFragmentManager()
Ответ 3
Обязательно передайте контекст ArrayAdapter или RecyclerViewAdpater, чтобы мы могли получить его внутри класса адаптера.
Если ваша mainActivity расширяет Activity, используйте:
FragmentManager fragmentManager = ((Activity)context).getFragmentManager();
Если ваша mainActivity расширяет AppCompatActivity, используйте:
FragmentManager fragmentManager = ((AppCompatActivity)context).getSupportFragmentManager();
Ответ 4
Лучший вариант, вероятно, заключался бы в том, чтобы фрагмент, создающий RecyclerAdapter для реализации и интерфейса, как это:
public class MyRecyclerAdapter extends Adapter<RecyclerAdapter.ViewHolder> {
private ItemType[] mItems;
private MRAItemClickedListener mListener;
public MyRecyclerAdapter(Context ctx, MRAItemClickedListener listener){
mListener = listener;
...
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
mListener.onItemClicked(mItems[position]);
}
});
}
interface MRAItemClickedListener {
void onItemClicked(ItemType item);
}
}
public class MyFragment ... implements MRAItemClickedListener {
public void onItemClicked(ItemType item){
// do stuff with item
}
}
Ответ 5
Вам просто нужен контекст активности, переданный в вашем конструкторе. Обязательно вызовите новый Adapter(this,...)
из действий и new Adapter(getActivity(),...)
из фрагментов.
private Context context;
@Override
public void onClick(View v) {
FragmentManager manager = ((Activity) context).getFragmentManager();}
Ответ 6
Я знаю, что это слишком поздно для вас, но для всех, кто может это увидеть.
Итак, вместо того, чтобы делать m vai, вы могли передать контекст фрагмента при первом инициализации адаптера.
Итак, в вашем конструкторе для вашего адаптера вы можете добавить такой аргумент
// variable to hold fragment
private Fragment fragment;
public MyCustomAdapter(Fragment fragment)
{
this.fragment = fragment;
}
и в вашем фрагменте вы можете просто инициализировать, как будто это
MyCustomAdapter myAdapter = new MyCustomAdapter(this);
Наконец, вы можете позвонить
Fragment fragment = new myNewFragment();
FragmentManager fragmentManager = context.getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment)
.commit();
чтобы вы могли начать новый фрагмент
Ответ 7
Создание фрагмента менеджера в самой деятельности.
MyActivity.java
FragmentManager fragmentManager = getFragmentManager();
adapter = new CustomAdapter(productsList, fragmentManager);
CustomAdapter.java
CustomAdapter implements MyClickListner{
CustomAdapter(Arraylist<MyProduct>productsList, FragmentManager fragmentManager) {
this.productList = productsList;
this.fragmentManager = fragmentManager;
}
@override
clickFunction(){
Fragment myFragment= new MyFilterFragment();
((MyFilterFragment) myFragment).show(this.fragmentManager,"tag");
}
MyClickListener.java
public interface MyClickListener(){
public clickFunction();
}
Ответ 8
Вы можете передать ссылку FragmentManager при создании зрителя, чтобы ваш класс для Viewholder мог быть следующим.
class ListItemViewHolder {
FragmentManager manager;
public ListItemViewHolder(View itemView,FragmentManager manager) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
itemView.setOnClickListener(this);
this.manager = manager;
}
@Override
public void onClick(View v) {
//Call FragmentManager and add Fragment to it.
manager.beginTransaction...
}
}