#android #android-fragments #android-recyclerview
#Android #android-фрагменты #android-recyclerview
Вопрос:
Я взял пример кода для реализации RecyclerView, но пытаюсь перенести его для работы в дочернем фрагменте в моем приложении.
Код находится в разделе «Создание списков — примеры» для создания списков и карточек
У меня возникли проблемы с моим адаптером..
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = v;
}
}
> @Override
> public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
> int viewType) {
> View v = LayoutInflater.from(parent.getContext())
> .inflate(R.layout.my_text_view, parent, false);
> ViewHolder vh = new ViewHolder(v);
> return vh;
> }
Во-первых, он не строится, жалуясь на то, что я вызываю конструктор ViewHolder с представлением, когда конструктор ожидает TextView.
Глядя на код, я согласен!
Но это официальный пример, поэтому он должен быть правильным?
Итак, что отличается от моей версии по сравнению с примером? Две вещи, о которых я могу думать…
1) макет my_text_view не приведен в примере, поэтому я сделал свой собственный. Я все сделал правильно?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@ id/t_title"
android:title="title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
2)
Я вызываю адаптер из своего дочернего фрагмента, и пример не был написан с учетом фрагментов.
Я, вероятно, откусил больше, чем могу понять.
Тем не менее, насколько я понимаю, я работаю над этим. «Родитель», входящий в мой onCreateViewHolder, является моим RecyclerView?
‘v’ должно быть линейным описанием моего ‘my_text_view’?
‘ViewHolder’ должен в конечном итоге быть классом со свойством mTextView, равным TextView из моего xml.
Я просто не понимаю, как перейти от v= LinearLayout к TextView??
Кто-нибудь хотел бы помочь объяснить этому новичку??
Комментарии:
1. Да, этот пример немного не соответствует действительности. Просто измените свой
ViewHolder
конструктор на takeView v
и используйте(TextView) v.findViewById(R.id.t_title)
, чтобы получитьTextView
.
Ответ №1:
Этот пример не очень хорош. Похоже, что два разных проекта объединены вместе. Это должно быть что-то вроде этого:
public class MyAdapter extends RecyclerView.Adapter {
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.t_title);
}
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
}
Чтобы объяснить этот сегмент:
onCreateViewHolder
это метод, который будет вызываться в любое время RecyclerView
, когда необходимо создать новый тип ViewHolder. Это может быть вызвано только дюжину или около того раз, чтобы получить достаточное количество просмотров для покрытия экрана, или это может быть вызвано довольно много раз, если у вас много типов просмотра.
Параметром parent
в этом случае будет параметр RecyclerView
, который его сопровождает. Почему бы просто не сделать это RecycerView
? Потому что дизайнеры Google решили, что это должна быть ViewGroup. Кроме того, это Adapter
шаблон, поэтому единственная гарантия, которую вы должны иметь, это то, что это a ViewGroup
(т. Е. Может не быть RecyclerView, поэтому вам не следует создавать адаптер с таким предположением). Реально, это почти всегда будет RecyclerView
хотя.
Параметр int viewType
должен указывать, какой вид представления вы создаете. Это определяется, если вы переопределяете getItemViewType()
метод адаптера. Вам не нужно беспокоиться об этом, если у вас есть только один тип представления.
Для ViewHolder
, это в основном для кэширования различных типов представлений в вашем макете. Это могут быть ImageView
, TextView
, и т.д. Они будут постоянно «перерабатываться» по мере прокрутки пользователем, поэтому вы не всегда их создаете. Таким образом, вам нужно только обновить представления с текущей информацией. В этом случае есть только title
. Переданный ViewHolder bindViewHolder
будет местом, где происходит фактическое обновление. Это вызывается постоянно, поэтому нет необходимости инициализировать представления onCreateViewHolder
. Просто нужно их создать.
Комментарии:
1. Большое спасибо, и за все дополнительные объяснения, которые вы предоставили, это делает все намного понятнее. Прекрасный ответ. Просто показывает, как вы никогда не должны предполагать, что примеры верны независимо от источника. Майку также следует отдать должное за приведение (TextView).