【问题标题】:ListView recycling with multiple types of viewsListView 回收与多种类型的视图
【发布时间】:2013-06-14 11:55:38
【问题描述】:

我目前正在开发一个非常简单的 ListView,它最多具有 2 种不同的视图类型。为了使一切顺利,我尝试回收视图。我的代码现在是:

@Override
public int getItemViewType (int position){
    if(mHasBefore&&position==0){
        return TYPE_PAGER;
    }else if(mHasNext&&position==getCount()-1){
        return TYPE_PAGER;
    }else return TYPE_SCORE;
}
@Override
public int getViewTypeCount (){
    return 1+((mHasBefore==true||mHasNext==true)?1:0);
}@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Log.d("outa","View: pos: "+position+ " . "+getItemViewType(position)+" - "+getViewTypeCount());
    if(getItemViewType(position)==TYPE_SCORE)return getScoreView(position,convertView,parent);
    else return getPagerView(position,convertView,parent);
}
protected View getPagerView(int position,View convertView,ViewGroup parent){
    if (convertView == null){
        convertView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.listitem_highscore_pager, null);}}
protected View getScoreView(int position,View convertView,ViewGroup parent){
    if (convertView == null){
        convertView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.listitem_highscore, null);}}

基本上它应该在最后一个项目上显示不同的视图,但它仍然显示默认项目,即使 LogCat 声明它不是 getView() 中的 TYPE_SCORE。因此 convertView 确实提供了一个回收的视图。我做错了什么还是这是正常行为?

【问题讨论】:

标签: android listview


【解决方案1】:

给你:

    private static final int TYPE_PAGER = 0;
    private static final int TYPE_PAGER = 1;
    private static final int VIEW_COUNT = 2;

    private LayoutInflater mInflater = LayoutInflater.from(context);

    @Override
    public int getViewTypeCount (){
            return VIEW_COUNT;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder;
                ViewHolder2 holder2;
                int type = getItemViewType(position);

                if (convertView == null) {
                    holder = new ViewHolder();
                    holder2 = new ViewHolder2();
                    switch(type){
                    case TYPE_SCORE:
                        Log.i(TAG, "ConvertView type1");
                        convertView = mInflater.inflate(R.layout.listitem_highscore, null);
                        convertView.setTag(R.layout.listitem_highscore, holder);
                    break;
                    case TYPE_PAGER:
                        Log.i(TAG, "ConvertView type0");
                        convertView = mInflater.inflate(R.layout.listitem_highscore_pager, null);
                        convertView.setTag(R.layout.listitem_highscore_pager, holder2);
                    break;

                    }
}

                } else{
                    // Get the ViewHolder back to get fast access to the TextViews
                    holder = (ViewHolder) convertView.getTag(R.layout.baseadapter);
                    holder2 = (ViewHolder2)convertView.getTag(R.layout.baseadapter1);
                }


                switch(type){
            case TYPE_SCORE:
               holder.holderText.setText("type1");
            break;
            case TYPE_PAGER:
               holder2.holder2Text.setText("type2");
            break;

            }
    }

视图持有者:

 static class ViewHolder {
      //Place your views here for example:
      TextView holderText;

  }

 static class ViewHolder2{
       TextView holder2Text;
  }

【讨论】:

  • 谢谢。写得很好的例子。
【解决方案2】:

getItemViewType() 必须返回稳定值。 IOW,对于0 中的positiongetItemViewType() 必须始终返回TYPE_PAGER,而不是基于其他一些mHasBefore 值。

如果您希望获得不稳定的值,则每次需要更改值时都需要致电notifyDataSetChanged()。 IOW,如果您将 mHasBefore 从原来的任何位置切换,则需要调用 notifyDataSetChanged(),如果您将 mHasBefore 更改回原来的值,则需要再次调用。

【讨论】:

    【解决方案3】:

    在 ListView 上使用 HeaderView 和 FooterView 怎么样?

    那样,您不必处理多种类型...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 2021-06-01
      • 2016-09-20
      • 2012-09-29
      • 1970-01-01
      • 2015-04-12
      相关资源
      最近更新 更多