很简单地listview重写baseadapter,实现不同item采用不同布局,类型转换错误,求指点。

时间:2021-06-08 18:04:46
public class MyAdapter extends BaseAdapter
{

private LayoutInflater mInflater;

public MyAdapter(Context context)
{
this.mInflater = LayoutInflater.from(context);
}

@Override
public int getCount()
{
if(mData==null) return 0;
return mData.size();
}

@Override
public Object getItem(int position)
{
return mData.get(position);

}

@Override
public long getItemId(int position)
{
return position;
}

@SuppressWarnings("null")
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
ViewHolder2 holder2 = null;
View view=null;
View view2=null;
switch (position)
{
case 2:
if (convertView == null)
{
holder2 = new ViewHolder2();
view2 = mInflater.inflate(R.layout.oneline, null,false);
holder2.title2 = (TextView) view2.findViewById(R.id.title2);
view2.setTag(holder2);
convertView=view2;
}
else
{
holder2 = (ViewHolder2) convertView.getTag();
}
holder2.title2.setText((String) mData.get(position)
.get("title"));
break;

default:
if (convertView == null)
{
holder = new ViewHolder();
view = mInflater.inflate(R.layout.twoline, null,false);
holder.title = (TextView) view.findViewById(R.id.title);
holder.info = (TextView) view.findViewById(R.id.info);
view.setTag(holder);
convertView=view;
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText((String) mData.get(position).get("title"));
holder.info.setText((String) mData.get(position).get("info"));
break;
}
return convertView;



//************************************************************

}

}

// 各个布局的控件资源
class ViewHolder
{
public TextView title;
public TextView info;
}

class ViewHolder2
{
public TextView title2;
}

15 个解决方案

#1


提示,不能将viewholder类型转化为viewholder2,定位在holder2=(VIewholder2)convertview.gettag()这一句

#2


用一个viewHolder,不要用两个。

public class MyAdapter extends BaseAdapter {

        private LayoutInflater mInflater;

        public MyAdapter(Context context) {
            this.mInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            if (mData == null) return 0;
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);

        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                switch (position){
                    case 2:
                        convertView = mInflater.inflate(R.layout.oneline, null, false);
                        break;
                    default:
                        convertView = mInflater.inflate(R.layout.twoline, null, false);
                        break;
                }
                convertView.setTag(holder);
            }else {
                holder = (ViewHolder) convertView.getTag();
            }
            switch (position) {
                case 2:
                    holder.title2 = (TextView) convertView.findViewById(R.id.title2);
                    holder.title2.setText((String) mData.get(position).get("title"));
                    break;

                default:
                    holder.title = (TextView) convertView.findViewById(R.id.title);
                    holder.info = (TextView) convertView.findViewById(R.id.info);
                    holder.title.setText((String) mData.get(position).get("title"));
                    holder.info.setText((String) mData.get(position).get("info"));
                    break;
            }
            return convertView;

        }

    }

    // 各个布局的控件资源
    class ViewHolder {
        public TextView title;
        public TextView info;
        public TextView title2;
    }

#3


引用 2 楼 jklwan 的回复:
用一个viewHolder,不要用两个。

public class MyAdapter extends BaseAdapter {

        private LayoutInflater mInflater;

        public MyAdapter(Context context) {
            this.mInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            if (mData == null) return 0;
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);

        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                switch (position){
                    case 2:
                        convertView = mInflater.inflate(R.layout.oneline, null, false);
                        break;
                    default:
                        convertView = mInflater.inflate(R.layout.twoline, null, false);
                        break;
                }
                convertView.setTag(holder);
            }else {
                holder = (ViewHolder) convertView.getTag();
            }
            switch (position) {
                case 2:
                    holder.title2 = (TextView) convertView.findViewById(R.id.title2);
                    holder.title2.setText((String) mData.get(position).get("title"));
                    break;

                default:
                    holder.title = (TextView) convertView.findViewById(R.id.title);
                    holder.info = (TextView) convertView.findViewById(R.id.info);
                    holder.title.setText((String) mData.get(position).get("title"));
                    holder.info.setText((String) mData.get(position).get("info"));
                    break;
            }
            return convertView;

        }

    }

    // 各个布局的控件资源
    class ViewHolder {
        public TextView title;
        public TextView info;
        public TextView title2;
    }

因为我有两个布局类型,所以需要两个viewholder,用两个是可以的,http://www.tuicool.com/articles/6N7jamq

#4


因为listview在滑动时会回收item,当被回收的item的对象是viewholder时,又要被转为viewholder2时,就会报错了

#5


当你position为1的时候convertview已经存了viewholder了,position为2的时候你强转为viewholder2报错了。
你这个只有在position为2的时候使用不同的布局,其他position布局是相同的,完全没必要给positon为2的布局实现复用。position为2的时候不要用convertview就好了。

#6


引用 5 楼 qq_30517057 的回复:
当你position为1的时候convertview已经存了viewholder了,position为2的时候你强转为viewholder2报错了。
你这个只有在position为2的时候使用不同的布局,其他position布局是相同的,完全没必要给positon为2的布局实现复用。position为2的时候不要用convertview就好了。

我对convertview的缓存不是十分了解,所以仿别人做的,你说的很对。其实我只是position为2的时候做个实验。按理这种方法是可以的,感兴趣看这个博客,http://www.tuicool.com/articles/6N7jamq,继续等大神了。

#7


你可以看看baseadapter  中getViewItemType方法,有助于实现不同布局额

#8


因为listview在滑动时会回收item,当被回收的item的对象是viewholder时,又要被转为viewholder2时,就会报错了

#9


试试这样:class ViewHolder2 extends ViewHolder{
    public TextView title2;
}

#10


有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

#11


有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

#12


引用 11 楼 u013147734 的回复:
有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

public class MyAdapter extends BaseAdapter
{
private static final int TYPE_POSITION_DEFAULT =0;
private static final int TYPE_POSITION_2 =1;
private static final int TYPE_MAX_COUNT =2;
private LayoutInflater mInflater;

public MyAdapter(Context context)
{
this.mInflater = LayoutInflater.from(context);
}

@Override
public int getCount()
{
if(mData==null) return 0;
return mData.size();
}

@Override
public Object getItem(int position)
{
return mData.get(position);

}

@Override
public long getItemId(int position)
{
return position;
}
public int getViewTypeCount() {
            return TYPE_MAX_COUNT;
        }
public int getItemViewType(int position) {
            return (position==2) ? TYPE_POSITION_2 : TYPE_POSITION_DEFAULT;
        }

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

if (convertView == null)
{
switch (type)
{

case TYPE_POSITION_2:
holder2 = new ViewHolder2();
view = mInflater.inflate(R.layout.oneline, null);
holder2.title2 = (TextView) view.findViewById(R.id.title2);
view.setTag(holder2);
break;
case TYPE_POSITION_DEFAULT:
holder = new ViewHolder();
view = mInflater.inflate(R.layout.twoline, null);
holder.title = (TextView) view.findViewById(R.id.title);
holder.info = (TextView) view.findViewById(R.id.info);
view.setTag(holder);
}
}
else
{
view = convertView;
switch (type)
{
case TYPE_POSITION_2:
holder2 = (ViewHolder2) view.getTag();

break;
case TYPE_POSITION_DEFAULT:

holder = (ViewHolder) view.getTag();
}
}
// 设置资源
switch (type)
{
case TYPE_POSITION_2:
holder2.title2.setText((String) mData.get(position)
.get("title"));

break;

case TYPE_POSITION_DEFAULT:
holder.title.setText((String) mData.get(position).get("title"));
holder.info.setText((String) mData.get(position).get("info"));
}

return view;



//************************************************************

}

}

#13


引用 11 楼 渐行渐远是否还有一种坚持留在心间的回复:
有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。
新手上路,感谢指点。
心得:我以为那两个函数没什么用,现在明白谷歌写好的,会自动内调,虽然不知道原因,但是目前只需要学会使用,慢慢知所以然。

#14


谷歌原生态的代码要多读,照着用就可以,UI设计关键是以后的性能优化,多看别人总结的博客,敲代码。。。

#15


有c+66吗,急需啊求各位了

#1


提示,不能将viewholder类型转化为viewholder2,定位在holder2=(VIewholder2)convertview.gettag()这一句

#2


用一个viewHolder,不要用两个。

public class MyAdapter extends BaseAdapter {

        private LayoutInflater mInflater;

        public MyAdapter(Context context) {
            this.mInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            if (mData == null) return 0;
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);

        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                switch (position){
                    case 2:
                        convertView = mInflater.inflate(R.layout.oneline, null, false);
                        break;
                    default:
                        convertView = mInflater.inflate(R.layout.twoline, null, false);
                        break;
                }
                convertView.setTag(holder);
            }else {
                holder = (ViewHolder) convertView.getTag();
            }
            switch (position) {
                case 2:
                    holder.title2 = (TextView) convertView.findViewById(R.id.title2);
                    holder.title2.setText((String) mData.get(position).get("title"));
                    break;

                default:
                    holder.title = (TextView) convertView.findViewById(R.id.title);
                    holder.info = (TextView) convertView.findViewById(R.id.info);
                    holder.title.setText((String) mData.get(position).get("title"));
                    holder.info.setText((String) mData.get(position).get("info"));
                    break;
            }
            return convertView;

        }

    }

    // 各个布局的控件资源
    class ViewHolder {
        public TextView title;
        public TextView info;
        public TextView title2;
    }

#3


引用 2 楼 jklwan 的回复:
用一个viewHolder,不要用两个。

public class MyAdapter extends BaseAdapter {

        private LayoutInflater mInflater;

        public MyAdapter(Context context) {
            this.mInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            if (mData == null) return 0;
            return mData.size();
        }

        @Override
        public Object getItem(int position) {
            return mData.get(position);

        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                switch (position){
                    case 2:
                        convertView = mInflater.inflate(R.layout.oneline, null, false);
                        break;
                    default:
                        convertView = mInflater.inflate(R.layout.twoline, null, false);
                        break;
                }
                convertView.setTag(holder);
            }else {
                holder = (ViewHolder) convertView.getTag();
            }
            switch (position) {
                case 2:
                    holder.title2 = (TextView) convertView.findViewById(R.id.title2);
                    holder.title2.setText((String) mData.get(position).get("title"));
                    break;

                default:
                    holder.title = (TextView) convertView.findViewById(R.id.title);
                    holder.info = (TextView) convertView.findViewById(R.id.info);
                    holder.title.setText((String) mData.get(position).get("title"));
                    holder.info.setText((String) mData.get(position).get("info"));
                    break;
            }
            return convertView;

        }

    }

    // 各个布局的控件资源
    class ViewHolder {
        public TextView title;
        public TextView info;
        public TextView title2;
    }

因为我有两个布局类型,所以需要两个viewholder,用两个是可以的,http://www.tuicool.com/articles/6N7jamq

#4


因为listview在滑动时会回收item,当被回收的item的对象是viewholder时,又要被转为viewholder2时,就会报错了

#5


当你position为1的时候convertview已经存了viewholder了,position为2的时候你强转为viewholder2报错了。
你这个只有在position为2的时候使用不同的布局,其他position布局是相同的,完全没必要给positon为2的布局实现复用。position为2的时候不要用convertview就好了。

#6


引用 5 楼 qq_30517057 的回复:
当你position为1的时候convertview已经存了viewholder了,position为2的时候你强转为viewholder2报错了。
你这个只有在position为2的时候使用不同的布局,其他position布局是相同的,完全没必要给positon为2的布局实现复用。position为2的时候不要用convertview就好了。

我对convertview的缓存不是十分了解,所以仿别人做的,你说的很对。其实我只是position为2的时候做个实验。按理这种方法是可以的,感兴趣看这个博客,http://www.tuicool.com/articles/6N7jamq,继续等大神了。

#7


你可以看看baseadapter  中getViewItemType方法,有助于实现不同布局额

#8


因为listview在滑动时会回收item,当被回收的item的对象是viewholder时,又要被转为viewholder2时,就会报错了

#9


试试这样:class ViewHolder2 extends ViewHolder{
    public TextView title2;
}

#10


有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

#11


有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

#12


引用 11 楼 u013147734 的回复:
有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

public class MyAdapter extends BaseAdapter
{
private static final int TYPE_POSITION_DEFAULT =0;
private static final int TYPE_POSITION_2 =1;
private static final int TYPE_MAX_COUNT =2;
private LayoutInflater mInflater;

public MyAdapter(Context context)
{
this.mInflater = LayoutInflater.from(context);
}

@Override
public int getCount()
{
if(mData==null) return 0;
return mData.size();
}

@Override
public Object getItem(int position)
{
return mData.get(position);

}

@Override
public long getItemId(int position)
{
return position;
}
public int getViewTypeCount() {
            return TYPE_MAX_COUNT;
        }
public int getItemViewType(int position) {
            return (position==2) ? TYPE_POSITION_2 : TYPE_POSITION_DEFAULT;
        }

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

if (convertView == null)
{
switch (type)
{

case TYPE_POSITION_2:
holder2 = new ViewHolder2();
view = mInflater.inflate(R.layout.oneline, null);
holder2.title2 = (TextView) view.findViewById(R.id.title2);
view.setTag(holder2);
break;
case TYPE_POSITION_DEFAULT:
holder = new ViewHolder();
view = mInflater.inflate(R.layout.twoline, null);
holder.title = (TextView) view.findViewById(R.id.title);
holder.info = (TextView) view.findViewById(R.id.info);
view.setTag(holder);
}
}
else
{
view = convertView;
switch (type)
{
case TYPE_POSITION_2:
holder2 = (ViewHolder2) view.getTag();

break;
case TYPE_POSITION_DEFAULT:

holder = (ViewHolder) view.getTag();
}
}
// 设置资源
switch (type)
{
case TYPE_POSITION_2:
holder2.title2.setText((String) mData.get(position)
.get("title"));

break;

case TYPE_POSITION_DEFAULT:
holder.title.setText((String) mData.get(position).get("title"));
holder.info.setText((String) mData.get(position).get("info"));
}

return view;



//************************************************************

}

}

#13


引用 11 楼 渐行渐远是否还有一种坚持留在心间的回复:
有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。

有两种布局也不能直接用两个viewholder,对listview复用机制有些了解就明白了。两种布局要在getitemtype里面声明怎么处理position返回的类型,不同类型返回不同的int值就好了,及getitemtypecount里面返回类型总数2。这样getview方法识别出来的convertview类型才会是同类型的,不用担心转化问题了。
新手上路,感谢指点。
心得:我以为那两个函数没什么用,现在明白谷歌写好的,会自动内调,虽然不知道原因,但是目前只需要学会使用,慢慢知所以然。

#14


谷歌原生态的代码要多读,照着用就可以,UI设计关键是以后的性能优化,多看别人总结的博客,敲代码。。。

#15


有c+66吗,急需啊求各位了