Intereting Posts
Разница между SlidingPaneLayout и NavigationDrawer Подключить приложение Android к базе данных с веб-сайта Виртуальное устройство не может быть удалено Отключение сна при определенной активности Пользовательский ContentProvider – openInputStream (), openOutputStream () Различные имена приложений для разных вариантов сборки? Как отключить RadioGroup до тех пор, пока флажок не установлен Размер растрового изображения превышает Vm бюджетную ошибку android Что происходит за кулисами, когда я выполняю синхронизацию репо? Как реализовать эффекты искажения изображения в Android Как вставлять и воспроизводить видео на YouTube в андроиде Запись строки в файл Можем ли мы изменить изображение ссылки (которое опубликовано приложением Android) на facebook Модернизация 2: Как установить индивидуальные тайм-ауты по конкретным запросам? Как установить язык по умолчанию для Android-приложения?

Создание ViewHolders для ListView с различными макетами элементов

У меня есть ListView с разными макетами для разных элементов. Некоторые элементы являются разделителями. Некоторые элементы разные, потому что они содержат разные данные и т. Д.

Я хочу реализовать ViewHolders, чтобы ускорить процесс getView, но я не совсем уверен, как это сделать. В разных макетах есть разные части данных (что затрудняет именование) и разное количество просмотров, которые я хочу использовать.

Как мне это сделать?

Лучшая идея, которую я могу придумать, – создать общий ViewHolder с элементами X, где X – количество просмотров в макете элементов с наибольшим количеством из них. Для других представлений с небольшим количеством представлений я просто использую подраздел этих переменных в ViewHolder. Так сказать, у меня есть 2 макета, которые я использую для двух разных предметов. У одного есть 3 TextViews, а у другого – 1. Я бы создал ViewHolder с 3 переменными TextView и использовал только один из них для моего другого элемента. Моя проблема в том, что это может стать действительно уродливым и выглядеть очень хаки; Особенно когда макет элемента может иметь много видов для разных типов.

Вот очень простой getView:

@Override public View getView(int position, View convertView, ViewGroup parent) { MyHolder holder; View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.layout_mylistlist_item, parent, false); holder = new MyHolder(); holder.text = (TextView) v.findViewById(R.id.mylist_itemname); v.setTag(holder); } else { holder = (MyHolder)v.getTag(); } MyListItem myItem = m_items.get(position); // set up the list item if (myItem != null) { // set item text if (holder.text != null) { holder.text.setText(myItem.getItemName()); } } // return the created view return v; } 

Предположим, у меня были разные типы макетов строк, я мог бы иметь ViewHolder для каждого типа строки. Но какой тип я бы назвал «держателем» на вершине? Или я могу объявить держатель для каждого типа, а затем использовать его для типа строки, в которой я включен.

Solutions Collecting From Web of "Создание ViewHolders для ListView с различными макетами элементов"

ListView имеет встроенную систему управления типом. В вашем адаптере у вас есть несколько типов элементов, каждый со своим видом и макетом. Переопределяя getItemViewType, чтобы вернуть тип данных заданной позиции, ListView имеет обязательную силу, чтобы передать правильное преобразование для этого типа данных. Затем в вашем методе getView просто проверьте тип данных и используйте оператор switch для обработки каждого типа по-разному.

Каждый тип макета должен иметь свой собственный зритель для определения ясности и удобства обслуживания. Назовите ViewHolders что-то, связанное с каждым типом данных, чтобы все было прямолинейно.

Попытка пересечь все в один ViewHolder просто не стоит усилий.

Изменить пример

 @Override public View getView(int position, View convertView, ViewGroup parent) { int viewType = this.getItemViewType(position); switch(viewType) { case TYPE1: Type1Holder holder1; View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService (Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.layout_mylistlist_item_type_1, parent, false); holder1 = new Type1Holder (); holder1.text = (TextView) v.findViewById(R.id.mylist_itemname); v.setTag(holder1); } else { holder1 = (Type1Holder)v.getTag(); } MyListItem myItem = m_items.get(position); // set up the list item if (myItem != null) { // set item text if (holder1.text != null) { holder1.text.setText(myItem.getItemName()); } } // return the created view return v; case TYPE2: Type2Holder holder2; View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.layout_mylistlist_item_type_2, parent, false); holder2 = new Type2Holder (); holder2.text = (TextView) v.findViewById(R.id.mylist_itemname); holder2.icon = (ImageView) v.findViewById(R.id.mylist_itemicon); v.setTag(holder1); } else { holder2 = (Type2Holder)v.getTag(); } MyListItem myItem = m_items.get(position); // set up the list item if (myItem != null) { // set item text if (holder2.text != null) { holder2.text.setText(myItem.getItemName()); } if(holder2.icon != null) holder2.icon.setDrawable(R.drawable.icon1); } // return the created view return v; default: //Throw exception, unknown data type } } 

Другой пример.

Открытый класс CardArrayAdapter расширяет ArrayAdapter {

 public CardArrayAdapter(Context context) { super(context, R.layout.adapter_card); } @Override public View getView(int position, View view, ViewGroup parent) { final Card card = getItem(position); ViewHolder holder; //if (view != null) { //holder = (ViewHolder) view.getTag(); //} else { Log.d("card.important?", card.name + " = " + Boolean.toString(card.important)); if(card.important) { view = LayoutInflater.from(getContext()).inflate(R.layout.adapter_card_important, parent, false); }else { view = LayoutInflater.from(getContext()).inflate(R.layout.adapter_card, parent, false); } holder = new ViewHolder(view); view.setTag(holder); //} // IMG Picasso.with(getContext()) .load(card.logo) .placeholder(R.drawable.ic_phonebook) .error(R.drawable.ic_phonebook) .fit() .centerCrop() .transform(new CircleTransform()) .into(holder.logo); holder.name.setText(card.name); if(card.important) { holder.category.setVisibility(View.VISIBLE); if (card.category.equals("airline")) { card.category = "airlines"; } int id = getContext().getResources().getIdentifier(card.category, "string", getContext().getPackageName()); holder.category.setText(getContext().getResources().getString(id)); }else { holder.category.setVisibility(View.GONE); } holder.tagline.setText(card.tagline); holder.favorite.setChecked(card.favorite); holder.favorite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { card.favorite = ((CheckBox) v).isChecked(); card.save(); } }); return view; } static class ViewHolder { @InjectView(R.id.logo) ImageView logo; @InjectView(R.id.name) TextView name; @InjectView(R.id.category) TextView category; @InjectView(R.id.tagline) TextView tagline; @InjectView(R.id.favorite) CheckBox favorite; public ViewHolder(View view) { ButterKnife.inject(this, view); } } 

}