简体   繁体   English

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

[英]Static ViewHolder and getting context when using with RecyclerView

I'm trying to use a recycler view and handle on click event.我正在尝试使用回收器视图并处理单击事件。 I've read various methods of handling onClick event on a recycler view item like :我已经阅读了在回收器视图项上处理 onClick 事件的各种方法,例如:

  1. Define the click listener inside the view holder class itself.在视图持有者类本身中定义点击侦听器。
  2. Define the click listener in onCreateViewHolder().在 onCreateViewHolder() 中定义点击监听器。
  3. Define an interface and then go from there (seems like too much work).定义一个接口,然后从那里开始(似乎工作太多了)。

So my first question is which option is better?所以我的第一个问题是哪个选项更好? I'm currently using the first method and if defining the click listener in the view holder class itself is the way to go, then how do I use the context from the adapter as the view holder class is static.我目前正在使用第一种方法,如果在视图持有者类本身中定义点击侦听器是可行的方法,那么我如何使用来自适配器的上下文,因为视图持有者类是静态的。

Basically, I want to have a static view holder and on click event, open a new Activity for which I need the context.基本上,我想要一个静态视图持有者,并在单击事件时打开一个我需要上下文的新活动。

UPDATE : Adding adapter and ViewHolder code.更新:添加适配器和 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);
        }
    }
}

In the view holder constructor we get the object of View class.在视图持有者构造函数中,我们获得了 View 类的对象。 You can use that object to get the context like:您可以使用该对象来获取上下文,例如:

class Holder extends RecyclerView.ViewHolder {

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

}

Try using the reference of the Activity.尝试使用 Activity 的引用。

ActivityOne.this.startActivity(intent);

If that doesn't work, then know that startActivity is a method of any Context.如果这不起作用,那么就知道 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: 参考:

The best approach that you can use for the same is by creating a BaseRecyclerView abstract class, and including some method to get context in there.您可以使用的最佳方法是创建一个 BaseRecyclerView 抽象类,并在其中包含一些获取上下文的方法。

For example, you base class would look something like this例如,你的基类看起来像这样

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
}

Now your Adapter class would not be extending RecyclerView.Adapter, but would extend BaseRecyclerViewAdapter class.现在您的 Adapter 类不会扩展 RecyclerView.Adapter,而是扩展 BaseRecyclerViewAdapter 类。 This would look something like这看起来像

class MyAdapter(): BaseRecyclerViewAdapter() {
    
}

You can now use context in MyAdapter simply by using getContext() which is a protected function inside the base class.您现在可以通过使用基类中的受保护函数getContext()在 MyAdapter 中使用上下文。

Whenever your RecyclerView is created, the base class assigns the context of the recyclerView to the variable named context .每当您创建 RecyclerView 时,基类都会将 recyclerView 的上下文分配给名为context的变量。 This context can now be accessed by using the getContext() method in the base class.现在可以使用基类中的getContext()方法访问此context

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM