我正在使用带有部分和部分标题的ListView。下面是不带ViewHolder类的适配器的GetView方法,该方法工作正常,但滚动几次后,将冻结UI并杀死多个设备上的应用程序。@Overridepublic View getView(int position, View v, ViewGroup parent){ //View v = convertView;// = convertView; //System.out.println("getView " + position + " " + convertView); final Item i = items.get(position); if (i != null) { if(i.isSection()) { SectionItem si = (SectionItem)i; v = vi.inflate(R.layout.list_item_section, null); v.setOnClickListener(null); v.setOnLongClickListener(null); v.setLongClickable(false); final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text); sectionView.setTypeface(StaticUtils.sTypeFace(context)); sectionView.setText(si.getTitle()); v.setEnabled(false); } else { EntryItem ei = (EntryItem)i; v = vi.inflate(R.layout.list_item_entry, null); final TextView title = (TextView)v.findViewById(R.id.list_item_entry_title); final ImageView mImg = (ImageView)v.findViewById(R.id.list_item_entry_drawable); mImg.getLayoutParams().height = mIvPrams; mImg.getLayoutParams().width = mIvPrams; title.setTypeface(StaticUtils.sTypeFace(context)); title.setSelected(true); if (title != null) title.setText(ei.title); imageLoader.displayImage(ei.imgUrl, mImg, options, animateFirstListener); } } return v;}现在,我尝试对其实施ViewHolder类以改善冻结问题。下面是我为适配器实现的带有ViewHolder类的代码。但是,当我滚动下面的实现时,ListView变得一团糟。它无法保存其元素的索引。如果我尝试进行更改,则当我从底部滚动到顶部时,有时也会收到NullPointerException。@Overridepublic View getView(final int position, View v, ViewGroup parent){ //View v = null;// = convertView; //System.out.println("getView " + position + " " + convertView); final Item i = items.get(position); if (i != null) { if(i.isSection()) { /*if (convertView == null) { v = (View) vi.inflate(R.layout.list_item_section, null); // Do some initialization } else { v = convertView; }*/ if(v==null) { mHolder = new ViewHolder(); v = vi.inflate(R.layout.list_item_section, null); mHolder.s = (SectionItem)i; mHolder.mSectionView = (TextView) v.findViewById(R.id.list_item_section_text); v.setTag(mHolder); } else { mHolder=(ViewHolder)v.getTag(); //v = convertView; } v.setOnClickListener(null); v.setOnLongClickListener(null); v.setLongClickable(false); //final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text); mHolder.mSectionView.setTypeface(StaticUtils.sTypeFace(context)); mHolder.mSectionView.setText(mHolder.s.getTitle()); v.setEnabled(false); } else { //v = vi.inflate(R.layout.list_item_entry, null); if (v == null) { mHolder = new ViewHolder(); v = (View) vi.inflate(R.layout.list_item_entry, null); mHolder.e = (EntryItem)i; mHolder.mTitle = (TextView)v.findViewById(R.id.list_item_entry_title); mHolder.mImg = (ImageView)v.findViewById(R.id.list_item_entry_drawable); mHolder.mImg.getLayoutParams().height = mIvPrams; mHolder.mImg.getLayoutParams().width = mIvPrams; v.setTag(mHolder); // Do some initialization } else { mHolder=(ViewHolder)v.getTag(); } //mHolder.mTitle.setTypeface(StaticUtils.sTypeFace(context)); //mHolder.mTitle.setSelected(true); if (mHolder.mTitle != null) mHolder.mTitle.setText(mHolder.e.title); imageLoader.displayImage(mHolder.e.imgUrl, mHolder.mImg, options, animateFirstListener); } } return v;}public class ViewHolder{ TextView mSectionView, mTitle; ImageView mImg; EntryItem e; SectionItem s;}我希望找到一个解决方案,该如何改善我的代码并为此适配器编写一个合适的ViewHolder类。 最佳答案 之所以得到NullPointerExceptions,是因为您要夸大两种类型的视图,并且在滚动时Android会重用视图,但是在某些时候,它会为R.layout.list_item_entry带来isSection(),而R.layout.list_item_section评估为true,反之亦然:为isSection()评估为false。您需要做的是在适配器中实现另外两个方法: -getViewTypeCount()这需要返回您要夸大的视图类型的数量。您需要返回2。 -getItemViewType(int position)-根据位置,您需要返回0或1。现在,在适配器中,首先通过调用getItemViewType检测什么是项目视图类型,然后应用当前逻辑。编辑使用基于getView方法的盲目编码将类似于以下内容(我没有检查它的可编译性,但是我确定您会理解我的意思):@Overridepublic int getViewTypeCount() { return 2;}@Overridepublic int getItemViewType(int position) { Item i = items.get(position); if(i.isSection()) { return 0; } return 1;}@Overridepublic View getView(final int position, View v, ViewGroup parent) { final Item i = items.get(position); int itemViewType = getItemViewType(position); ViewHolder viewHolder = null; if (itemViewType == 0) { if (v == null) { viewHolder = new ViewHolder(); v = vi.inflate(R.layout.list_item_section, null); viewHolder.mSectionView = (TextView) v.findViewById(R.id.list_item_section_text); v.setTag(mHolder); } else { viewHolder = (ViewHolder) v.getTag(); } v.setOnClickListener(null); v.setOnLongClickListener(null); v.setLongClickable(false); //final TextView sectionView = (TextView) v.findViewById(R.id.list_item_section_text); viewHolder.mSectionView.setTypeface(StaticUtils.sTypeFace(context)); viewHolder.mSectionView.setText(mHolder.s.getTitle()); v.setEnabled(false); } else { EntryItem e = (EntryItem) i; //v = vi.inflate(R.layout.list_item_entry, null); if (v == null) { viewHolder = new ViewHolder(); v = (View) vi.inflate(R.layout.list_item_entry, null); viewHolder.mTitle = (TextView) v.findViewById(R.id.list_item_entry_title); viewHolder.mImg = (ImageView) v.findViewById(R.id.list_item_entry_drawable); viewHolder.mImg.getLayoutParams().height = mIvPrams; viewHolder.mImg.getLayoutParams().width = mIvPrams; v.setTag(mHolder); // Do some initialization } else { viewHolder = (ViewHolder) v.getTag(); } //mHolder.mTitle.setTypeface(StaticUtils.sTypeFace(context)); //mHolder.mTitle.setSelected(true); if (viewHolder.mTitle != null) viewHolder.mTitle.setText(mHolder.e.title); imageLoader.displayImage(e.imgUrl, viewHolder.mImg, options, animateFirstListener); } return v;}观察:不要将数据模型类保留在Holder类中,因为将在不同位置的其他类似视图中重用Holder,并且您保留在Holder中的数据模型类对该位置将无效。您已经有getItem(position)方法可用。改用它!关于android - Android:尝试为带有节头的ListView编写ViewHolder类时,ListView变得困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21226852/
10-12 01:35