【问题标题】:How to call getFragmentManager on Recycler.Adapter?如何在 Recycler.Adapter 上调用 getFragmentManager?
【发布时间】:2015-06-16 11:58:28
【问题描述】:

我正在将我的应用程序的 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 并在其中添加 Fragment。有没有比这更好的方法,比如发送广播或任何其他方法。

【问题讨论】:

  • 冒泡事件到 Recycler.Adapter(现在它在持有者中)并为它设置一些监听器(例如创建 addapter 的片段) - 如何做到这一点?它在这里被描述了很多次
  • @Selvin 我知道如何在活动或片段中调用 FragmentManager,但它在适配器中给了我错误

标签: android android-fragments


【解决方案1】:

您只需要在构造函数中传递一个活动上下文。请务必从活动中调用new Adapter(this,...),从片段中调用new Adapter(getActivity(),...)

private Context context;

@Override
public void onClick(View v) {
    FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
}

【讨论】:

  • FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();
【解决方案2】:

添加已批准的答案:如果您仍然收到错误,您可能需要替换此行;

FragmentManager manager = ((Activity)context).getFragmentManager();

有了这个

FragmentManager manager = ((AppCompatActivity)context).getSupportFragmentManager();

对我来说,这是因为我使用的是 support.v4.app.FragmentManager 而不是常规的 fragmentmanager

仍然出现错误?

正如下面的一条评论所指出的,这可能会引发 java.lang.ClassCastException: 并记录 ... cannot be cast to android.support.v7.app.AppCompatActivity(请查看 cmets 了解详细信息)

他们的解决方法是改用这个(我没有测试过,但对他们有用):

((AppCompatActivity)activity).getSupportFragmentManager()

【讨论】:

  • 我遇到了同样的问题。谢谢:)
  • @h8pathak 很高兴它有帮助
  • 谢谢!这对我有帮助。
  • java.lang.ClassCastException: com.skypoint.cmdroyal.extra.AppControllerVolley 无法转换为 android.support.v7.app.AppCompatActivity 我遇到了这个问题。我想从回收站项目中打开它。所以这行代码在一个适配器类中。
  • 这行得通。 ((AppCompatActivity)activity).getSupportFragmentManager()
【解决方案3】:

确保将 context 传递给 ArrayAdapter 或 RecyclerViewAdpater,以便我们可以在 Adapter Class 中获取它。

如果您的 mainActivity 正在扩展 Activity,请使用:

 FragmentManager fragmentManager = ((Activity)context).getFragmentManager();

如果您的 mainActivity 正在扩展 AppCompatActivity,则使用:

FragmentManager fragmentManager = ((AppCompatActivity)context).getSupportFragmentManager();

【讨论】:

    【解决方案4】:

    最好的选择可能是让 Fragment 实例化 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】:

            在 kotlin 中,您可以使用以下代码:

                val fm : FragmentManager= (context as AppCompatActivity).supportFragmentManager
            

            【讨论】:

            • 不鼓励使用纯代码的答案。考虑添加说明您的代码解决问题的原因和方式。
            【解决方案9】:

            您可以在创建 viewholder 时传递 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...
                    }
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2018-11-11
              • 2018-05-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多