Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the android context in an adapter

People also ask

What is context in RecyclerView adapter?

Obtaining Context at ViewHolder level means that you do it every time you bind or create a ViewHolder . You duplicate operations. I don't think you need to worry about any memory leak. If your adapter lingers outside your Activity lifespan (which would be weird) then you already have a leak.

Should I pass context to adapter?

there is nothing wrong with passing context to your adapter. You just should keep your adapter responsible for work with views, leaving networking or database operations for your fragment.

Why we use context in adapter?

It also enables access to Android's built-in services, such as those used for layout inflation, keyboard, and finding content providers. In many cases when the "context is required", we simply need to pass in the instance of the current activity.


Obtaining the Context in the constructor has (at least) three advantages:

  1. You only do it once, not every time, getView() is called.
  2. You can use it for other purposes too, when needed.
  3. It also works, when parent is null.

However, if you don't have any problems with your solution, you might as well stick to it.


Here is an example:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    Holder holder;
    if (view == null) {
        view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_job, parent, false);
        holder = new Holder(view, this);
        view.setTag(holder);
    } else {
        holder = (Holder) view.getTag();
    }

    holder.parse(getItem(position), position);
    return view;
}

public class Holder {

    @Bind(R.id.type)
    TextView type;
    @Bind(R.id.date_time)
    TextView dateTime;
    @Bind(R.id.grade)
    TextView grade;

    public Holder(View view) {
        ButterKnife.bind(this, view);
    }

    public void parse(final GetGradeHistoryResponse.GradeHistory item) {
        if (item.grade < 0) {
            grade.setTextColor(App.getInstance()
                    .getResources().getColor(R.color.withdraw_status));
            grade.setText(String.valueOf(item.grade));
        } else {
            grade.setTextColor(App.getInstance()
                    .getResources().getColor(R.color.primary));
            grade.setText("+" + String.valueOf(item.grade));
        }

        type.setText(item.type);
        dateTime.setText(item.datetime);
    }
}

You can get context by view.getContext() in the Holder


Just simple like this!!

class RecentlyAdapter(var data: List<String>) : Adapter<RecentlyAdapter.HomeViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.card_recently_played, parent, false)
    return HomeViewHolder(view)
}

override fun getItemCount(): Int {
    return data.size
}

override fun onBindViewHolder(holder: HomeViewHolder, position: Int) {

}

class HomeViewHolder(itemView: View): ViewHolder(itemView) {
    init {
        itemView.setOnClickListener {
            val intent = Intent(itemView.context, MusicPlayerActivity::class.java)
            var context = itemView.context
            context.startActivity(intent)
        }
    }
}

}

To get context use itemView.context


What if someone will create a class that uses BaseAdapter to store Views somewhere (and, maybe, it will attach them to parent later)? In this case parent may be null.

It's not such a big problem, decide for yourself what is better.

For example:

public class MockWithAdapter{

    private BaseAdapter mAdapter;

    public MockWithAdapter(BaseAdapter adapter){
        mAdapter = adapter;
    }

    public List<View> mock(){
        int size = mAdapter.getCount();
        List<View> views = new ArrayList(size);
        for(int i=0; i<size; i++)
            views.add(mAdapter.getView(i, null, null));

        return views;
    }
}

And then you can do with this views whatever you want:

MockWithAdapter m = new MockWithAdapter(adapter);
ListView lv = new ListView(context);
for(View v : m.mock)
    lv.addView(v);