Getting the android context in an adapter
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 .
Solution 1:
Obtaining the Context in the constructor has (at least) three advantages:
- You only do it once, not every time,
getView()
is called. - You can use it for other purposes too, when needed.
- It also works, when
parent
isnull
.
However, if you don't have any problems with your solution, you might as well stick to it.
Solution 2:
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:
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:
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);