Recyclerview: использование нескольких типов просмотра и настройка видимости для разных макетов
Я использую представление переработчика в приложении чата, теперь, как вы все знаете в чате, у нас есть 2 разных представления.
Вид справа: тот, который вы отправили.
Вид слева: тот, который вы получили.
Теперь мне удалось добиться того, что я хочу, используя один элемент макета, и внутри этого элемента я использовал 2 относительных макета, один макет для правого вида и другой для левого вида.
И чтобы узнать, какой макет показать, я сделал это в onBindViewholder:
onBindViewHolder(){
if(/*I sent the message*/){
right_layout.setVisibility(view.VISIBLE);
left_layout.setVisibility(view.GONE);
}
else {
right_layout.setVisibility(view.GONE);
left_layout.setVisibility(view.VISIBLE);
}
}
У меня нет проблем с использованием вышеуказанного метода. Но мой вопрос заключается в том, почему другие используют ту вещь, которая называется несколькими типами представлений, в которой они используют 2 держателя представлений? Я должен использовать это вместо этого?
2 ответа
Первое: в вашем случае я не уверен, действительно ли необходимо использовать два типа представлений. Типичный RecyclerView
на мобильном телефоне будет отображаться от семи до десяти строк одновременно, и он будет генерировать еще несколько, чтобы иметь возможность плавно прокручивать в случае необходимости. По сравнению с игровым приложением практически ничего не нужно делать с точки зрения пользовательского интерфейса. Но вы спросили, почему кто-то может захотеть использовать несколько типов представлений, так что здесь идет:
Прямо сейчас 50% View
s вы будете раздувать будет установлен GONE
Таким образом, это похоже на непрерывную трату процессорного времени и (что еще хуже на мобильном устройстве) разряжает батарею без необходимости. Используя два типа представлений, вы избегаете этого (в некоторой степени, я полагаю, что определение типа представления требует меньше энергии).
Другая причина - лучшая производительность, которая приводит к лучшему восприятию пользователя: RecyclerView
был разработан для эффективной работы со списками предметов. Сообщая ему, какую строку можно повторно использовать для какой позиции списка, вы наилучшим образом используете его алгоритм повторного использования.
С точки зрения разработчика, я бы придерживался вашего подхода, если разница между этими двумя типами составляет не более двух или трех строк кода. Но есть списки, где разница больше похожа на двадцать строк кода. В этом случае используются разные типы представлений, файлы макетов и ViewHolder
s улучшает читабельность вашего кода.
Да, вы должны реализовать разные ViewHolder
для каждого типа зрения. Это обеспечивает несколько преимуществ, таких как отсутствие необходимости поддерживать соответствующее состояние, упорядочение макетов и, как правило, упрощение рассуждений о том, что в будущем будет добавлена дополнительная функциональность.
Это также легко реализовать:
@Override
public int getItemViewType(int position) {
Message message = messages.get(position);
if (message instanceof ReceivedMessage) {
return VIEWTYPE_RECEIVED;
}
if (message instanceof SentMessage) {
return VIEWTYPE_SENT;
}
return 0;
}
затем:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
switch (viewType) {
case VIEWTYPE_RECEIVED:
View receivedView = inflater.inflate(R.layout.item_received, parent, false);
ReceivedViewHolder receivedViewHolder = new ReceivedViewHolder(receivedView);
return receievedViewHolder;
case VIEWTYPE_SENT:
// ...
}
}
в конце концов:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case VIEWTYPE_RECEIEVED:
// ...
}
}