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.
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.
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:
getView()
is called.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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With