Лучший способ предоставить пользовательский вид для выбранного элемента списка
Цель: иметь полностью настраиваемый макет для выбранного элемента, учитывая, что одновременно может быть выбран только один элемент.
Я не хочу привлекать getViewTypeCount
/getItemViewType
для выбора, так как они уже используются в этом адаптере для различных целей.
Одним из очевидных вариантов является раздувание пользовательского макета для обозначения выбранного элемента путем изменения адаптера на что-то вроде:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
...
// initialize convertView, holder, regular stuff
// Now, the questionable part:
if (position == mSelectedPosition) {
// use custom layout to indicate highlight/selection
convertView = inflater.inflate(R.layout.custom_selection_layout, parent, false);
} else {
// clear up selection
// also convertView could be recycled view and be of unexpected type
}
}
Это не должно быть слишком плохо с точки зрения производительности, так как выбирается / раздувается только один элемент, но проблема в том, что convertedView
может быть двух разных типов, и необходимы дополнительные приведения / проверки.
Этот подход не одобряется?
Другой вариант может быть следующим: объединить выбранную / невыбранную версию макета в item_layout
и один из них скрыт / показан в адаптере динамически в зависимости от if (position == mSelectedPosition)
состояние.Это хорошая идея?
В конечном счете, что было бы правильным способом сделать это?
Спасибо
1 ответ
Я бы пошел на первый подход. Ваш пользовательский макет должен применяться только к одному представлению во всем списке, поэтому единственное, что вам нужно сделать, - это избежать повторного использования такого представления. Я использую этот подход для загрузки разделителей в определенных точках списка и не вижу проблем с производительностью.
С другой стороны, иметь - скажем так - как макеты в одном, так и изменять видимость, мне кажется не лучшим вариантом, так как ваш держатель вида станет довольно большим (вам нужно иметь ссылку на все виды внутри, я думаю) благо всего один ребенок во всем списке. Все переработанные, не отобранные виды будут каждый раз сталкиваться с проверкой положения, что было бы ненужным для большинства (все, кроме одного) случаев.
Что касается идентификации представления после его повторного использования, возможен также подход с использованием тегов.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (position == mSelectedPosition) {
convertView = inflater.inflate(R.layout.custom_selection_layout, parent, false);
//here you upload convertView without the ViewHolder pattern, by using findViewById();
//it's legit IMO because it gets called just once for the whole list.
convertView.setTag("SELECTED_VIEW");
return convertView;
}
ViewHolder holder;
if (convertView == null || convertView.getTag("SELECTED_VIEW")) {
//this convertView is not good. We inflate the regular layout
convertView = inflater.inflate( ... );
}
//regular stuff
...
}