Подтвердить что ты не робот

Как вызвать 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 или любой другой метод.

4b9b3361

Ответ 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...
        }
    }