Получение контекста android в адаптере
Во многих образцах кода, которые я нашел в Интернете, context
получается в конструкторе адаптера.
Этот контекст используется для получения inflater
для раздувания представлений в методе getView
.
Мой вопрос - зачем беспокоиться о создании контекста в конструкторе, когда его можно легко получить таким образом
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;
}
Также есть причина не использовать вышеописанный метод, потому что до сих пор я не сталкивался с какой-либо проблемой при его использовании.
Ответы
Ответ 1
Получение контекста в конструкторе имеет (по крайней мере) три преимущества:
- Вы делаете это только один раз, не каждый раз,
getView()
вызывается.
- Вы также можете использовать его для других целей, если это необходимо.
- Он также работает, когда
parent
null
.
Однако, если у вас нет проблем с вашим решением, вы можете также придерживаться его.
Ответ 2
Что делать, если кто-то создаст класс, который использует BaseAdapter
для хранения Views где-нибудь (и, возможно, он будет прикреплять их к родительскому позже)? В этом случае parent
может быть null
.
Это не такая уж большая проблема, решите для себя, что лучше.
Например:
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;
}
}
И тогда вы можете делать с этими представлениями все, что хотите:
MockWithAdapter m = new MockWithAdapter(adapter);
ListView lv = new ListView(context);
for(View v : m.mock)
lv.addView(v);
Ответ 3
Вот пример:
@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);
}
}
Вы можете получить контекст view.getContext() in the Holder
Ответ 4
Просто так, как это!
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)
itemView.context.startActivity(intent)
}
}
}
}
Чтобы получить контекст, используйте itemView.context