Getting the android context in an adapter

AndroidAndroid AdapterAndroid Context

Android Problem Overview


In many of the code samples that I find on the internet the context is obtained in the constructor of an adapter.

This context is used to get an inflater to inflate the views in getView method.

My Question is why bother getting the context in the constructor when it can easily be obtained like so

        LayoutInflater inflater;
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if(inflater == null){
            Context context = parent.getContext();
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            }
            ...
            ...
            
            return convertView;
        }

Also is there any reason not to use the above method because it till now I have not faced any problem in using it .

Android Solutions


Solution 1 - Android

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.

Solution 2 - Android

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

Solution 3 - Android

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

Solution 4 - Android

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

Solution 5 - Android

Yes but if you need any activity reference like for example dialog alert you cannot use context reference , therefore constructor should receive activity reference from calling Activity/Fragment

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGautamView Question on Stackoverflow
Solution 1 - AndroidRidcullyView Answer on Stackoverflow
Solution 2 - AndroidwyxView Answer on Stackoverflow
Solution 3 - AndroidExel StaderlinView Answer on Stackoverflow
Solution 4 - AndroidDmitry ZaytsevView Answer on Stackoverflow
Solution 5 - AndroidPrakash ReddyView Answer on Stackoverflow