为具有不同项目布局的ListView创buildViewHolders
我有一个不同的布局不同项目的ListView。 有些项目是分隔符。 有些项目是不同的,因为他们拥有不同types的数据等
我想实现ViewHolders来加快getView过程,但我不太清楚如何去做。 不同的布局有不同的数据片段(这使得命名困难)和不同数量的我想使用的视图。
我应该怎么做呢?
我能想出的最好的想法是用X项目创build一个通用的ViewHolder,其中X是项目布局中具有最高数目的视图数量。 对于具有less量视图的其他视图,我将在ViewHolder中使用这些variables的一个子部分。 所以说我有2个布局我用于2个不同的项目。 一个有3个TextViews,另一个有1.我将创build一个ViewHolder与3个TextViewvariables,并只使用其中一个为我的其他项目。 我的问题是,这可以得到真正丑陋的外观,感觉很hacky; 特别是当一个项目布局可能有很多不同types的视图。
这是一个非常基本的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; }
假设我有不同types的行布局,我可以为每种types的行都有一个ViewHolder。 但是,我会宣称“持有者”是什么types? 或者我会为每种types声明一个持有者,然后使用那个行的types。
ListView有一个内置的typespipe理系统。 在您的适配器中,您有几种types的项目,每个项目都有自己的视图和布局。 通过重写getItemViewType来返回给定位置的数据types,ListView可以传递正确的convertview数据types。 然后,在你的getView方法中,简单地检查数据types并使用switch语句以不同的方式处理每个types。
每个布局types都应该有自己的视图,以便命名清晰,易于维护。 将ViewHolders命名为与每个数据types相关的东西,以保持一切正常。
尝试将所有内容重叠到一个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); } }
}