2016-10-17 6 views
1

Я привел пример кода для реализации RecyclerView, но попытался перенести его для работы в дочернем фрагменте в моем приложении.Android | ViewHolder

Код в разделе «Создание списков - примеры» Creating Lists and Cards

Я бегу в проблемы с моим адаптером ..

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' должен быть LinearLayout моего 'my_text_view'?

«ViewHolder» должен стать классом с свойством mTextView, равным TextView из моего xml.

Я просто не вижу, как я перехожу из v = LinearLayout, в TextView?

Кому-нибудь нравится объяснять этому noob ??

+0

Да, этот пример немного не работает. Просто измените конструктор 'ViewHolder', чтобы взять' View v' и использовать '(TextView) v.findViewById (R.id.t_title)', чтобы получить «TextView». –

ответ

3

Этот пример не очень хорош. Похоже, два разных проекта объединились. Это должно быть что-то вроде этого:

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, поэтому единственной гарантией, которую вы должны иметь, является то, что это ViewGroup (т. Е. Не может быть RecyclerView, поэтому вы не должны строить адаптер с этим допущением). Реально, это будет в значительной степени всегда RecyclerView.

Параметр int viewType должен сообщить вам, какой вид вы строите.Это определяется, если вы переопределяете метод адаптера getItemViewType(). Вам не нужно беспокоиться об этом, если у вас есть только один вид View.

Для ViewHolder это в основном кэширование различных видов просмотров в вашем макете. Это могут быть ImageView, TextView и т. Д. Они будут постоянно перерабатываться, поскольку пользователь прокручивает, чтобы вы не всегда создавали их. Таким образом, вам нужно обновить представления только с текущей информацией. В этом случае есть только title. ViewHolder, пройденный в bindViewHolder, будет там, где происходит фактическое обновление. Это называется все время, поэтому нет необходимости инициализировать представления в onCreateViewHolder. Просто нужно их создать.

+0

Большое спасибо, и за все дополнительное объяснение, которое вы предоставили, делает все намного яснее. Прекрасный ответ. Просто идет, чтобы показать, как вы никогда не должны предполагать, что примеры верны независимо от источника. Кредит Майку также за листинг (TextView). – Esby

Смежные вопросы