Лучший способ предоставить пользовательский вид для выбранного элемента списка

Цель: иметь полностью настраиваемый макет для выбранного элемента, учитывая, что одновременно может быть выбран только один элемент.

Я не хочу привлекать 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
     ...
}
Другие вопросы по тегам