Android ListView 使用不同对象加载不同布局

   2016-10-31 0
核心提示:因为未知原因,突然想到了关于一个 List 集合里面能否添加不同对象的问题,因为我们平时开发过程中,关于List 的比较常规的写法就是:ListXXX list = new ArrayListXXX();这让我形成了一种 List 里面就只能添加一种类型的对象的潜在想法(或许是 Java 基础不

因为未知原因,突然想到了关于一个 List 集合里面能否添加不同对象的问题,因为我们平时开发过程中,关于List 的比较常规的写法就是:

List<XXX> list = new ArrayList<XXX>();

这让我形成了一种 List 里面就只能添加一种类型的对象的潜在想法(或许是 Java 基础不够扎实)。

所以,我这里用代码确定一下,List 不给定泛型,然后迭代添加两种不同的对象,最后再迭代输出数据,看看是否会有问题,代码如下:

public class MainClass {

    private List list = new ArrayList();

    public static void main(String args[]) {
        MainClass mc = new MainClass();
        mc.initData();

        for (int i = 0; i < 10; i++) {
            Object item = mc.list.get(i);

            if (item instanceof TestOther) {
                TestOther other = (TestOther) item;
                String company = other.getCompany();
                String position = other.getPosition();
                System.out.println("company : " + company + " , position : " + position);
            } else if (item instanceof TestBean1) {
                String name = ((TestBean1) item).getName();
                String like = ((TestBean1) item).getLike();
                System.out.println("name : " + name + " , like : " + like);
            }
        }
    }

    private void initData() {
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                list.add(new TestOther("Ekoo" + i, "Android Developer" + i));
            } else {
                list.add(new TestBean1("Test" + i, "Coding" + i));
            }
        }
    }

}

那么我们的运行结果如下:

company : Ekoo0 , position : Android Developer0
name : Test1 , like : Coding1
company : Ekoo2 , position : Android Developer2
name : Test3 , like : Coding3
company : Ekoo4 , position : Android Developer4
name : Test5 , like : Coding5
company : Ekoo6 , position : Android Developer6
name : Test7 , like : Coding7
company : Ekoo8 , position : Android Developer8
name : Test9 , like : Coding9

这里通过打印数据,确定了 List 中可以添加不同对象。

那么,这个问题明确之后,我想到了在之前的工作中,一直以为 ListView 列表数据中不能存有不同的对象,所有数据都只能在同一个对象中定义。这个时候,我们再去尝试一下,利用 List 中可以添加不同对象去测试一下 ListView 中 加载不同的布局。

首先,创建两个不同的对象 :

public class CompanyBean {
    private String company;
    private String position;
    private String address;

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}


public class UserBean {

    private String name;
    private String age;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

然后,我们在 Activity 中初始化一下模拟数据:

private void initData() {
        for (int i = 0; i < 20; i++) {
            // 这里随机生成 1到10 之间的随机数
            int num = (int) (Math.random() * 10);
            if (num % 2 == 0) {
                UserBean bean1 = new UserBean();
                bean1.setName("name" + i);
                bean1.setAge(num + "");
                bean1.setSex("男");
                list.add(bean1);
            } else {
                CompanyBean bean2 = new CompanyBean();
                bean2.setCompany("HzEkoo" + i);
                bean2.setAddress("Ypsd201-4(" + i + ")");
                bean2.setPosition("Android Developer" + i);
                list.add(bean2);
            }
        }

    }

接下来就是定义 Adapter 了。

private class TestAdapter extends BaseAdapter {

        private Context context;
        private List list;
        private LayoutInflater inflater;

        public TestAdapter(Context context, List list) {
            this.context = context;
            this.list = list;
            inflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return list.size();
        }

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

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

        @Override
        public int getItemViewType(int position) {
            Object item = list.get(position);
            if (item instanceof UserBean) {
                return 0;
            } else if (item instanceof CompanyBean) {
                return 1;
            }
            return -1;
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            Object item = getItem(position);

            int type = getItemViewType(position);

            switch (type) {
                case 0:
                    UserBean userBean = (UserBean) item;
                    if (convertView == null) {
                        convertView = inflater.inflate(R.layout.item_user, parent, false);
                    }
                    TextView tv_name = ViewHolder.get(convertView, R.id.tv_name);
                    TextView tv_age = ViewHolder.get(convertView, R.id.tv_age);
                    TextView tv_sex = ViewHolder.get(convertView, R.id.tv_sex);

                    tv_name.setText(userBean.getName());
                    tv_age.setText(userBean.getAge());
                    tv_sex.setText(userBean.getSex());

                    break;
                case 1:
                    CompanyBean comBean = (CompanyBean) item;
                    if (convertView == null) {
                        convertView = inflater.inflate(R.layout.item_company, parent, false);
                    }
                    TextView tv_company = ViewHolder.get(convertView, R.id.tv_company);
                    TextView tv_position = ViewHolder.get(convertView, R.id.tv_position);

                    tv_company.setText(comBean.getCompany());
                    tv_position.setText(comBean.getPosition());
                    break;
            }

            return convertView;
        }
    }

这个 Adapter 肯定是我最终的调试结果。关于 ViewHolder.get(View , id) 我之前博客 进一步简化你的 ViewHolder 有过介绍。

初期,我的想法是在 getView() 中根据判断 List 对应下标对象的类型 比如:

Object item = list.get(position);
if (item instanceof UserBean) {
    UserBean userBean = (UserBean) item;
     // do something
 } else if (item instanceof CompanyBean) {
     CompanyBean comBean = (CompanyBean) item;
     // do something
 }

这样去判断加载不同的布局,进行数据填充,但是在进行滑动过程中,复用出现了混乱,导致直接闪退。

最终确定选择了使用 getItemViewType() 方法,不过,这个方法在使用的时候也是有个坑,那就是必须要重写getViewTypeCount() 方法,这个以前不怎么用,所以现在才发现这个问题。

最后附上一张效果图:

只是一个简单的测试,有需要源码的朋友,留个地址。

能力有限,欢迎各位指正。

 
标签: ListView
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Android 自定义ListView adapter(zt)
    Android 自定义ListView adapter(zt)
    本文讲实现一个自定义列表的Android程序,程序将实现一个使用自定义的适配器(Adapter)绑定数据,通过contextView.setTag绑定数据有按钮的ListView。系统显示列表(ListView)时,首先会实例化一个适配器,本文将实例化一个自定义的适配器。实现自定义适配器
    12-01 ListView
  • Android ListView 优化之 getView 与 ViewHolder 是如何工作的?
    Android ListView 优化之 getView 与 ViewHolde
    Android中我们经常会用到ListView,然后ListView到底是如何通过ViewHolder去优化的?1.常见的适配器中利用ViewHolder去优化ListView的代码@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (conve
    11-07 ListView
  • listviewd优化---viewHolder的封装
    listviewd优化---viewHolder的封装
    android项目中如果使用listview控件,则在优化上我们一般使用viewHolder保证列表项的布局convertView可以被重用避免多次重新绘制。 一般方法中getView的写法@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder vie
    11-07 安卓开发
  • Android ListView优化之局部刷新(更新)(非notifyDataSetChanged)
    Android ListView优化之局部刷新(更新)(非no
    在Android开发中我们经常会用到listview的数据和界面刷新动作,我们每次可能会用到的都是Adapter.notifyDataSetChanged()方法。这个方法的原理是利用观察者模式对我们的数据源进行监听,当我们的数据源发生变化的时候,会调用Adapter的getView()方法进行整个
    11-04 ListView
  • 基础篇章:关于 React Native 之 ListView 组件的讲解
    基础篇章:关于 React Native 之 ListView 组件
    我们讲完ScrollView组件,其实顺其自然的就应该讲解ListView,对于前段和移动端的开发人员应该非常熟悉这样的控件吧,具体是做什么的,我感觉不用我讲了吧。我们来看看它怎么使用吧。大家好,我是ListView,我是React Native大家族中基础组件中,一个核心组件
  • Android应用性能优化系列视图篇——ListView自适应导致的严重性能问题
    Android应用性能优化系列视图篇——ListView自
    ListView是Android中最常用的视图之一,使用的频率仅仅次于三大基础布局,虽然由于使用性和扩展性等原因备受争议,且尽管后来出现了RecyclerView的替代方案,但是ListView仍然广泛地使用在我们的项目中。自从ListView出道至今,已经不知道衍生出了多少问题,
  • android中listview的一些样式设置
    在 Android中,ListView是最常用的一个控件,在做UI设计的时候,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性 android:background=”@drawable/bg”,不过不要高兴地太早,当你这么做以后,发
    10-13 ListView
  • React Native填坑之旅--ListView篇
    列表显示数据,基本什么应用都是必须。笔者写作的时候RN版本是0.34。今天就来从浅到深的看看React Native的ListView怎么使用。首先是使用写死的数据,之后会使用网络请求的数据在界面中显示。最后加上一个ActivityIndicator,网络请求的过程中显示Loading图标
  • RecyclerView、ListView 实现单选列表的优雅之路.
    RecyclerView、ListView 实现单选列表的优雅之
    一 概述: 这篇文章需求来源还是比较简单的,但做的 优雅 仍有值得挖掘的地方。 需求来源:一个类似饿了么这种 电商优惠券的选择界面 : 其实就是 一个普通的列表,实现了 单选 功能,效果如图:(不要怪图渣了,我撸了四五遍,公司录出来的GIF就这么渣。。。
  • [原]判断Listview滑动到了最底部(且最后一个ite
    记录下代码:listView.setOnScrollListener(new AbsListView.OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleIte
    09-14 ListView
点击排行