Android 静态ViewHolder和与RecyclerView一起使用时获取上下文

Android 静态ViewHolder和与RecyclerView一起使用时获取上下文,android,onclick,android-recyclerview,Android,Onclick,Android Recyclerview,我正在尝试使用回收器视图和处理点击事件。我读过处理回收器视图项上onClick事件的各种方法,如: 在视图持有者类本身内部定义click侦听器 在onCreateViewHolder()中定义单击侦听器 定义一个接口,然后从那里开始(看起来工作量太大了) 所以我的第一个问题是哪种选择更好? 我目前正在使用第一个方法,如果在视图持有者类本身中定义click侦听器是一种方法,那么当视图持有者类是静态的时,我如何使用适配器中的上下文呢 基本上,我希望有一个静态视图持有者,在单击事件时,打开一个需要上下

我正在尝试使用回收器视图和处理点击事件。我读过处理回收器视图项上onClick事件的各种方法,如:

  • 在视图持有者类本身内部定义click侦听器
  • 在onCreateViewHolder()中定义单击侦听器
  • 定义一个接口,然后从那里开始(看起来工作量太大了)
  • 所以我的第一个问题是哪种选择更好? 我目前正在使用第一个方法,如果在视图持有者类本身中定义click侦听器是一种方法,那么当视图持有者类是静态的时,我如何使用适配器中的上下文呢

    基本上,我希望有一个静态视图持有者,在单击事件时,打开一个需要上下文的新活动

    更新:添加适配器和ViewHolder代码

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    
        private Context mContext;
        private List<Job> jobs;
    
        public MyAdapter(Context context, List<Job> jobs) {
            mContext = context;
            this.jobs = jobs;
        }
    
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View itemLayoutView = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.list_item, viewGroup, false);
    
            itemLayoutView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(mContext, MyActivity.class);
                    mContext.startActivity(intent);
                }
            });
    
            return new ViewHolder(itemLayoutView);
        }
    
        @Override
        public void onBindViewHolder(WorkExperienceAdapter.ViewHolder viewHolder, int i) {
                //bindViewHolder code
            }
        }
    
        @Override
        public int getItemCount() {
            return jobs.size();
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder {
    
            @InjectView(R.id.current)
            TextView mCurrent;
    
            public ViewHolder(View itemView) {
                super(itemView);
                ButterKnife.inject(this, itemView);
            }
        }
    }
    
    公共类MyAdapter扩展了RecyclerView.Adapter{ 私有上下文; 私人名单工作; 公共MyAdapter(上下文、列表作业){ mContext=上下文; 这个.工作=工作; } @凌驾 public MyAdapter.ViewHolder onCreateViewHolder(视图组视图组,int i){ View itemLayoutView=LayoutFlater.from(viewGroup.getContext()) .充气(R.layout.list_项,视图组,假); itemLayoutView.setOnClickListener(新视图.OnClickListener(){ @凌驾 公共void onClick(视图v){ Intent Intent=新的Intent(mContext,MyActivity.class); mContext.startActivity(意图); } }); 返回新的ViewHolder(itemLayoutView); } @凌驾 BindViewHolder上的公共无效(WorkExperienceAdapter.ViewHolder ViewHolder,int i){ //bindViewHolder代码 } } @凌驾 public int getItemCount(){ 返回jobs.size(); } 公共静态类ViewHolder扩展了RecyclerView.ViewHolder{ @注入视图(R.id.current) 文本视图mccurrent; 公共视图持有者(视图项视图){ 超级(项目视图); ButterKnife.inject(这个,itemView); } } }
    在视图持有者构造函数中,我们得到视图类的对象。可以使用该对象获取上下文,如:

    class Holder extends RecyclerView.ViewHolder {
    
        public Holder(View itemView) {
        super(itemView);
        Context context = itemView.getContext();
       }
    
    }
    

    尝试使用活动的引用

    ActivityOne.this.startActivity(intent);
    
    如果这不起作用,那么要知道startActivity是任何上下文的一种方法

    class MessageViewHolderOfFriend extends RecyclerView.ViewHolder {
    
        private final Context context;
    
        public  MessageViewHolderOfFriend(View v) {
            super(v);
            context = v.getContext();
    
            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(context,NewActivityToRun.class);
                    context.startActivity(intent);
                }
            });
    
        }
    

    实现这一点的最佳方法是创建BaseRecyclerView抽象类,并在其中包含一些获取上下文的方法

    例如,基类看起来像这样

    abstract class BaseRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    
    private lateinit var context: Context
    
    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
    
        context = recyclerView.context      
    }
    
        protected fun getContext() = context
    }
    
    现在,只需使用基类中受保护的函数
    getContext()
    ,即可在MyAdapter中使用上下文


    无论何时创建RecyclerView,基类都会将RecyclerView的上下文分配给名为
    context
    的变量。现在可以使用基类中的
    getContext()
    方法访问此
    context

    您的第一个问题,哪种方法更好,将主要产生基于观点的答案,不适合SO格式。是的,但我想知道在比较前两种方法时是否存在性能差异。您好,我实际上尝试了此方法,但不起作用,因为
    itemView.getContext()
    不返回活动上下文,因此不可能使用它启动另一个活动。在onBindViewHolder()方法中设置侦听器怎么样?@user2558050
    itemView.getContext()
    返回一个
    Context
    ,因此使用它调用
    startActivity()
    是的,我确实可以这样做,但我认为应该在
    onCreateViewHolder()上完成
    而不是
    onBindViewHolder()
    ,因为我认为每次在
    onBindViewHolder()
    中重用视图时注册一个新的侦听器可能会影响性能,但我不确定。@pskink我尝试使用
    itemView.getContext()
    返回的
    上下文对象来启动活动,但出现运行时异常,称为
    android.util.AndroidRuntimeException:从活动上下文外部调用startActivity()需要标志_Activity_NEW_TASK标志。这真的是你想要的吗?
    class MyAdapter(): BaseRecyclerViewAdapter() {
        
    }