3

Я новичок в android, Я работаю над проектом, и на моей странице новостей, я пытаюсь включить модульный канал RecyclerView, который показывает вопрос с различными формами ответов, varrying в соответствии с Тип вопроса. То, как я это делал до сих пор, - это использовать включенные и поворачивать формы, когда это необходимо. недавно, так как я добавил больше модулей, приложение начало замедляться значительно, поэтому я пытаюсь реализовать ViewStubs.Есть ли способ использовать ViewStub внутри RecyclerView?

Это мой RecyclerView адаптер:

public class ReQuestionAdapter extends RecyclerView.Adapter<FeedItem> { 
private ArrayList<Question> myQuestions; 
public ReQuestionAdapter(Context context, ArrayList<Question> questions) { 
    myQuestions = questions ; 
} 

@Override 
public FeedItem onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.list_item_re_question, parent, false); 
    return new FeedItem(view); 
} 

@Override 
public void onBindViewHolder(FeedItem holder, int position) { 
    Question q = myQuestions.get(position); 
    holder.bindQuestion(q); 
} 

@Override 
public int getItemViewType(int position) { 
    return 0; 
} 

@Override 
public int getItemCount() { 
    return myQuestions.size(); 
} 
} 

И это класс ViewHolder для адаптера:

public class FeedItem extends RecyclerView.ViewHolder{ 
private Question mQuestion; 
public TextView tvName; 
public TextView tvTime; 
public TextView tvContent; 
public ProfilePictureView profilePictureView; 
public ViewStub moduleView; 
private int moduleType; 

public FeedItem(View itemView) { 
    super(itemView); 

} 

public void bindQuestion(Question question) { 
    mQuestion = question; 
    tvTime = (TextView) itemView.findViewById(R.id.li_q_date); 
    tvContent = (TextView) itemView.findViewById(R.id.li_q_content); 
    moduleView = (ViewStub) itemView.findViewById(R.id.module_viewstub); 
    tvTime.setText(TimeHandler.When(mQuestion.publish_time)); 
    tvContent.setText(mQuestion.content); 
    moduleType = question.type; 
     switch (moduleType) { 
      case Question.TYPE_YN: 
       moduleView.setLayoutResource(R.layout.module_yes_no); 
       moduleView.inflate(); 
       break; 
      case Question.TYPE_CUSTOM: 
       moduleView.setLayoutResource(R.layout.module_custom); 
       moduleView.inflate(); 
       break; 
      default: 
       break; 
     } 
    } 
} 

Теперь проблема в том, что ViewStub, который содержит определенное расположение, не может быть вызванный новым, причина в том, что он удаляется из представления hirarchy, как только он покидает экран, симптомы: При прокрутке RecyclerView первые элементы списка, которые заполняют экран, работают идеально, но другие когда предыдущий выход из экрана вызывает привязку FeedItem для приведения NullPointerException. (Он не может найти его в макете списка).

Я ищу решение, эффективное как ViewStubs, или способ заставить их работать должным образом, поскольку у меня появилось много модулей и их раздувание в каждом элементе, так как невидимый сделает мое приложение медленным.

ответ

3

В вашем методе bindQuestion() вы ссылаетесь на два разных макета для раздувания, поэтому в сущности у вас есть два разных вида.

просмотров адаптера есть эффективный способ, как справиться с этим построено прямо.

Start переопределив getItemViewType(). Когда элемент в position получает module_yes_no макета, вернуть 0. Когда он получает module_custom макета, вернуть 1.

Тогда в onCreateViewHolder(), когда параметр viewType является 0, надуть list_item_re_question вид в комплекте с module_yes_no макетом. Когда viewType == 1, надуйте версию вида module_custom.

Теперь, когда у вас есть вид в onBindViewHolder(), он будет уже иметь правильное подзапрос, поэтому вы приступаете к заполнению этого вида по мере необходимости. Используя getItemViewType(), RecyclerView работает с вами, чтобы переработать точный вид, который вам нужен.

Вы даже можете иметь два FeedItem подклассы, один для module_yes_no и один для module_custom, поэтому в onBindViewHolder(), вы просто проверить класс ViewHolder и ветви соответственно.

Это должно помочь улучшить производительность вашего приложения.

+0

Thx alot, так что я получаю это, используя два разных класса FeedItem, recyclerview будет знать сам, какие части сохранить, а какие разные? или он будет создавать 2 циклических вида, повторяющихся в соответствии с запросом? –

+1

Два класса FeedItem предназначены только для вашей выгоды. 'RecyclerView' знает, какой вид переработать для вас в силу того, что вы переопределяете' getItemViewType() '. Итак, предположим, что пункт 20 - yes_no.Если вы настроили 'getItemViewType()' для возврата 0 для элементов yes_no, тогда, когда пользователь прокручивается до пункта 20, 'RecyclerView' вызывает ваш' getItemViewType() 'с позицией == 20. Он получает 0 и говорит:« О посмотрите, у меня есть вид типа для утилизации прямо здесь »и передает это представление' onBindViewHolder() '. Имеют смысл? –

+0

Тогда, если 'RecyclerView' не имеет вида, доступного для повторного использования, он вызывает' onCreateViewHolder() 'с' viewType' == 0, чтобы вы знали, какой тип представления для раздувания и какой тип создателя вида создавать. –