akshayt23
akshayt23

Reputation: 2933

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 :

  1. Define the click listener inside the view holder class itself.
  2. Define the click listener in 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.

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

Upvotes: 4

Views: 6731

Answers (3)

Priyansh Kedia
Priyansh Kedia

Reputation: 180

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.

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. 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.

Whenever your RecyclerView is created, the base class assigns the context of the recyclerView to the variable named context. This context can now be accessed by using the getContext() method in the base class.

Upvotes: 0

Diego Ven&#226;ncio
Diego Ven&#226;ncio

Reputation: 6007

Try using the reference of the Activity.

ActivityOne.this.startActivity(intent);

If that doesn't work, then know that startActivity is a method of any 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:

Upvotes: 0

Bhawna Raheja
Bhawna Raheja

Reputation: 619

In the view holder constructor we get the object of View class. 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();
   }

}

Upvotes: 9

Related Questions