ListView的多套布局

本文介绍如何为Android ListView创建自定义适配器以支持多种布局,并详细解释了BaseAdapter的实现方法,包括getViewTypeCount和getItemViewType的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看看效果图,手画的哈有点丑嘿嘿

这里写图片描述

大概就是这个样式,我就拿两种布局的为例,掌握住重点,多少都没有问题嘿嘿!

1、简单的理解就是有几种不同的布局就要有几个相应的xml文件,所以先上布局文件喽:

layout_item_type1:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="70dp"
        android:lines="2"
        android:textSize="18sp"
        android:layout_marginLeft="6dp"
        android:text="标题"

        />

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_marginTop="4dp"
        android:layout_marginLeft="6dp"
        android:text="2016-8-1"/>

    <ImageView
        android:id="@+id/image_left"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentRight="true"
        android:src="@mipmap/ic_launcher"/>

</RelativeLayout>

layout_item_type2:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:lines="2"
        android:text="afdgadafergadgf"
        android:layout_marginLeft="6dp"
        android:layout_marginRight="6dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center">
        <ImageView
            android:id="@+id/image1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_marginLeft="6dp"
            android:layout_marginRight="6dp"
            android:src="@mipmap/huli"/>

        <ImageView
            android:id="@+id/image2"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_marginLeft="6dp"
            android:layout_marginRight="6dp"
            android:src="@mipmap/huli"/>

        <ImageView
            android:id="@+id/image3"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_marginLeft="6dp"
            android:layout_marginRight="6dp"
            android:src="@mipmap/huli"/>

    </LinearLayout>

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="6dp"
        android:text="dfgs"/>

</LinearLayout>

2、提到ListView就会想到适配器,这里当然要自定义了,我这里用来内部类

现在来说明几点:

1)继承BaseAdapter一定要实现四个方法,要实现多种布局,还需要实现两个方法分别是getViewTypeCount()和getItemViewType();

getViewTypeCount():返回的是一共有多少种不同的布局

getItemViewType():取得不同的布局返回的是int型的,该处必须注意,返回值必须从0开始,否则会报数组越界的异常,看源码就可以知道了。

2)注意我这种adapter的方式,这种写法有很多的好处的,我也是从工作中学到的

 private class ListViewAdapter extends BaseAdapter {

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

        @Override
        public Object getItem(int i) {
            return mList.get(i);
        }

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

        //注意返回的类型必须从0开始,否则会报数组越界的异常
        @Override
        public int getItemViewType(int position) {
            if ("type1".equals(mList.get(position).get("type"))) {
                return 0;
            } else {
                return 1;
            }
        }

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

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {

            TypeOneViewHolder holderOne ;
            TypeTwoViewHolder holderTwo;
            if(getItemViewType(i)==0){
                if(view == null){
                    holderOne = new TypeOneViewHolder(ListViewTypeActivity.this);
                }else{
                    holderOne = (TypeOneViewHolder) view;
                }

                holderOne.setContentView(i);
                //返回的是holder不是view
                return holderOne;
            }else{
                if(view == null){
                    holderTwo = new TypeTwoViewHolder(ListViewTypeActivity.this);
                }else{
                    holderTwo = (TypeTwoViewHolder) view;
                }

                holderTwo.setContentView(i);
                return holderTwo;
            }

        }
        //holder要继承LinearLayout
        private class TypeOneViewHolder extends LinearLayout{

            TextView title;
            TextView time;
            ImageView image;
            public TypeOneViewHolder(Context context) {
                super(context);

                //必须使用this不能用null否则会报异常的
               View.inflate(context,R.layout.layout_item_type1,this);
                title = (TextView) findViewById(R.id.title);
                time = (TextView) findViewById(R.id.time);
                image = (ImageView) findViewById(R.id.image_left);
            }

            public void setContentView(int position){

                String title_str = mList.get(position).get("title").toString();
                title.setText(title_str);
                time.setText(mList.get(position).get("time").toString());
                image.setImageResource(Integer.parseInt(mList.get(position).get("image").toString()));
            }


        }

        private class TypeTwoViewHolder extends LinearLayout{

            TextView title;
            TextView time;
            ImageView image1;
            ImageView image2;
            ImageView image3;
            public TypeTwoViewHolder(Context context) {
                super(context);
                View.inflate(context, R.layout.layout_item_type2, this);
                title = (TextView) findViewById(R.id.title);
                time = (TextView) findViewById(R.id.time);
                image1 = (ImageView) findViewById(R.id.image1);
                image2 = (ImageView) findViewById(R.id.image2);
                image3 = (ImageView) findViewById(R.id.image3);
            }

            public void setContentView(int position){
                title.setText(mList.get(position).get("title").toString());
                time.setText(mList.get(position).get("time").toString());
                int image[] = (int[]) mList.get(position).get("image");
                image1.setImageResource(image[0]);
                image2.setImageResource(image[1]);
                image3.setImageResource(image[2]);
            }
        }
    }

3、剩下就没有什么了

mListView = (ListView) findViewById(R.id.listview);
//我这里是模拟的数据
initDatas();
adapter = new ListViewAdapter();
mListView.setAdapter(adapter);


private void initDatas() {
        mList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            if (i % 3 == 0) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "type2");
                map.put("title", "标题" + i);
                map.put("time", "2016-8-1 08:30:" + i);
                int image[] = {R.mipmap.huli, R.mipmap.ic_launcher, R.mipmap.huli};
                map.put("image", image);
                mList.add(map);
            } else {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "type1");
                map.put("title", "标题" + i);
                map.put("time", "2016-8-1 08:30:" + i);
                map.put("image", R.mipmap.huli);
                mList.add(map);
            }
        }

有这些就OK了,我自己测试过了

在真正开发时数据往往都是来自网络的,所给的图片都是网址,这时要注意加载图片是访问网络的哦所以要放在异步里,我一般用picasso来处理,因为只用一句代码,有好的办法欢迎留言^_^。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值