【问题标题】:Static ViewHolder and getting context when using with RecyclerView与 RecyclerView 一起使用时的静态 ViewHolder 和获取上下文
【发布时间】:2016-01-21 07:33:27
【问题描述】:

我正在尝试使用回收站视图并处理点击事件。我已经阅读了在回收站视图项上处理 onClick 事件的各种方法,例如:

  1. 在视图持有者类本身内定义点击监听器。
  2. 在 onCreateViewHolder() 中定义点击监听器。
  3. 定义一个接口,然后从那里开始(似乎工作量太大)。

所以我的第一个问题是哪个选项更好? 我目前使用的是第一种方法,如果在视图持有者类本身中定义点击侦听器是可行的方法,那么我如何使用来自适配器的上下文,因为视图持有者类是静态的。

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

更新:添加适配器和 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);
        }
    }
}

【问题讨论】:

  • 你的第一个问题,哪种方法更好,会产生主要基于意见的答案,不适合 SO 格式。
  • 是的,但我想知道在比较前两种方法时是否有任何性能差异。

标签: android onclick android-recyclerview


【解决方案1】:

在视图持有者构造函数中,我们获得了 View 类的对象。您可以使用该对象来获取上下文,例如:

class Holder extends RecyclerView.ViewHolder {

    public Holder(View itemView) {
    super(itemView);
    Context context = itemView.getContext();
   }

}

【讨论】:

  • 您好,我实际上尝试过这种方法,但它不起作用,因为itemView.getContext() 不返回活动上下文,因此无法使用它启动另一个活动。
  • 在onBindViewHolder()方法中设置监听怎么样?
  • @user2558050 itemView.getContext() 返回一个Context,所以用它来调用startActivity()
  • 是的,我实际上可以这样做,但我认为应该在 onCreateViewHolder() 而不是 onBindViewHolder() 上完成,因为我认为每次在 onBindViewHolder() 中重用视图时注册一个新的侦听器可能会影响性能,但我不确定。
  • @pskink 我尝试使用由itemView.getContext() 返回的Context 对象来启动一个活动,但得到一个运行时异常说android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
【解决方案2】:

尝试使用 Activity 的引用。

ActivityOne.this.startActivity(intent);

如果这不起作用,则知道 startActivity 是任何 Context 的方法。

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);
            }
        });

    }

REF:

【讨论】:

    【解决方案3】:

    您可以使用的最佳方法是创建一个 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
    }
    

    现在您的 Adapter 类不会扩展 RecyclerView.Adapter,但会扩展 BaseRecyclerViewAdapter 类。这看起来像

    class MyAdapter(): BaseRecyclerViewAdapter() {
        
    }
    

    您现在可以在 MyAdapter 中使用上下文,只需使用 getContext(),它是基类中的受保护函数。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 2017-08-11
      • 2015-04-16
      相关资源
      最近更新 更多