【Android】ListView--显示多种类型内容

原创 2015年11月19日 10:42:31

先看效果图:

整个布局其实只是一个listview,图中标记的三个黄色块的内容是三种不同的item显示类型。其实道理也很简单,就是在Adapter的geiView中根据当前item的显示类型来匹配对应的布局文件就可以了。Adapter自身提供了getItemViewType和getViewTypeCount来帮助我们实现这种效果,顾名思义,getItemViewType用于获取某个item的类型,而getViewTypeCount用于获取总的类型数。


主布局中只有一个listview,如activity_main.xml:

    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.ydz.test027_listview_mutiltype.MainActivity" >

    <ListView
        android:id="@+id/listview_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</RelativeLayout>


然后为三种Item显示类型提供布局(item_left,item_center,item_right),由于此处只是用于简单的功能演示,所以头像图片资源就直接写死了:

item_left.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:paddingBottom="5dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="5dp" >

    <ImageView
        android:id="@+id/item_left_portrait"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/portrait_left" />

    <TextView
        android:id="@+id/item_left_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/item_left_portrait"
        android:background="@drawable/content_bg_left" />

</RelativeLayout>


item_center.xml:

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

    <TextView
        android:id="@+id/item_center_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="10sp" />

</LinearLayout>


item_right.xml:

<?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"
    android:orientation="horizontal"
    android:paddingBottom="5dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="5dp" >

    <ImageView
        android:id="@+id/item_right_portrait"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/portrait_right" />

    <TextView
        android:id="@+id/item_right_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/item_right_portrait"
        android:background="@drawable/content_bg_right" />

</RelativeLayout>


为方便数据的统一管理,使用Item的数据类,ListViewItem.java:

package com.ydz.test027_listview_mutiltype;

/**
 * listview条目信息
 */
public class ListViewItem {

    /**
     * 类型列表
     */
    public static enum ITEM_TYPE {
        TYPE_LEFT, TYPE_RIGHT, TYPE_CENTER
    };

    /**
     * 类型
     */
    private ITEM_TYPE mType;
    /**
     * 内容
     */
    private String mContent;

    public ListViewItem(ITEM_TYPE tType, String tContent) {
        mType = tType;
        mContent = tContent;
    }

    public ITEM_TYPE getType() {
        return mType;
    }

    public String getContent() {
        return mContent;
    }

    public void setType(ITEM_TYPE tType) {
        mType = tType;
    }

    public void setContent(String tContent) {
        mContent = tContent;
    }
}


接下来是核心的Adapter类,注意重写的部分函数。由于此处item的布局都很简单,所以用了单一的ViewHolder来处理,如果不同类型的item差异较大的话,也可以考虑提供不同的ViewHolder来处理,当然这种方式并不人性化,比如有100种类型,估计就得提供100种ViewHolder,这显然是不科学的。记得看过一篇文章是开发一种适配能力很强的ViewHolder,后续再跟进学习一下。MutilTypeAdapter.java:

package com.ydz.test027_listview_mutiltype;

import java.util.ArrayList;
import java.util.HashMap;

import com.ydz.test027_listview_mutiltype.ListViewItem.ITEM_TYPE;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

/**
 * 适配器
 */
public class MutilTypeAdapter extends BaseAdapter {

    private ArrayList<ListViewItem> mList;
    private LayoutInflater mInflater;

    public MutilTypeAdapter(Context tContext, ArrayList<ListViewItem> tList) {
        mInflater = LayoutInflater.from(tContext);
        mList = tList;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int tType = getItemViewType(position);
        ViewHolder tHolder = null;

        if (convertView == null) {
            if (tType == ITEM_TYPE.TYPE_CENTER.ordinal()) {
                convertView = mInflater.inflate(R.layout.item_center, parent, false);
            } else if (tType == ITEM_TYPE.TYPE_LEFT.ordinal()) {
                convertView = mInflater.inflate(R.layout.item_left, parent, false);
            } else if (tType == ITEM_TYPE.TYPE_RIGHT.ordinal()) {
                convertView = mInflater.inflate(R.layout.item_right, parent, false);
            }
            tHolder = new ViewHolder();
            convertView.setTag(tHolder);
        } else {
            tHolder = (ViewHolder) convertView.getTag();
        }

        if (tType == ITEM_TYPE.TYPE_CENTER.ordinal()) {
            tHolder.getViewById(convertView, R.id.item_center_content).setText(
                    mList.get(position).getContent());
        } else if (tType == ITEM_TYPE.TYPE_LEFT.ordinal()) {
            tHolder.getViewById(convertView, R.id.item_left_content).setText(
                    mList.get(position).getContent());
        } else if (tType == ITEM_TYPE.TYPE_RIGHT.ordinal()) {
            tHolder.getViewById(convertView, R.id.item_right_content).setText(
                    mList.get(position).getContent());
        }

        return convertView;
    }

    /**
     * 获得某个条目的类型
     */
    @Override
    public int getItemViewType(int position) {
        return mList.get(position).getType().ordinal();
    }

    /**
     * 获得类型总数
     */
    @Override
    public int getViewTypeCount() {
        return ListViewItem.ITEM_TYPE.values().length;
    }

    private class ViewHolder {
        HashMap<Integer, TextView> mMap = new HashMap<Integer, TextView>();

        public TextView getViewById(View tParent, int tID) {
            TextView tView = mMap.get(Integer.valueOf(tID));
            if (tView == null) {
                tView = (TextView) tParent.findViewById(tID);
                mMap.put(Integer.valueOf(tID), tView);
            }
            return tView;
        }
    }
}

最后是我们的主Activity,这里用了比较“硬”的方式来初始化数据。MainActivity.java:

package com.ydz.test027_listview_mutiltype;

import java.util.ArrayList;

import com.ydz.test027_listview_mutiltype.ListViewItem.ITEM_TYPE;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {

    private ListView mListViewContent;
    private MutilTypeAdapter mAdapter;
    private ArrayList<ListViewItem> mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListViewContent = (ListView) findViewById(R.id.listview_content);

        // 初始化数据
        mList = new ArrayList<ListViewItem>();
        for (int index = 0; index < 7; index++) {
            mList.add(new ListViewItem(ITEM_TYPE.TYPE_CENTER, "2015-10-01 : 00:30"));
            mList.add(new ListViewItem(ITEM_TYPE.TYPE_LEFT, "你好,吃饭没?"));
            mList.add(new ListViewItem(ITEM_TYPE.TYPE_RIGHT, "吃了面条..."));
            mList.add(new ListViewItem(ITEM_TYPE.TYPE_CENTER, "2015-10-01 : 00:35"));
            mList.add(new ListViewItem(ITEM_TYPE.TYPE_LEFT, "最近,著名篮球记者萨姆-阿米科走访了多位联盟高层,"
                    + "请他们谈论对湖人以及科比现状的看法。湖人现在只有2胜9负,而科比在此前对活塞的比赛中打了将近37分钟,"
                    + "赛后称自己起身困难,因而他也缺席了上一场对太阳的比赛,而湖人遭遇惨败。"));
            mList.add(new ListViewItem(ITEM_TYPE.TYPE_RIGHT, "但这位高层同时也表示,只要有人愿意继续给科比合同,"
                    + "他不退役也没有问题。“一方面,我觉得他仍然能够在一些有机会冲冠的球队做出贡献,但那绝对不是湖人。但另一方面,"
                    + "我也很钦佩他说自己绝不会为湖人以外的球队效力,他对管理层真的很忠诚。"));
        }

        mAdapter = new MutilTypeAdapter(MainActivity.this, mList);
        mListViewContent.setAdapter(mAdapter);
    }
}







调用系统的图库和系统相机完成获取头像功能 包括popupWindow的使用

忙着做项目,废话不多说,至于注释和代码解释什么的以后再补 public class MyInfoActivity extends Activity { public final stati...

Android自定义控件之日历控件

Android自定义控件之日历控件三月份学习android,至今也有半年有余,中间也做过两个项目,但是依然感觉自己做的应用不是很有新意,比不上应用市场上那些应用如此绚丽。所以自己仍需继续努力。学习至今...

android图文混排与多种类型listView的混搭的item的demo,getItemViewType()和getViewTypeCount()的使用

工作中经常遇到一个listView里面的item是不同样式的,以前考虑的是在getView实现不同的样式,那样的话效率应该低,也没有那么方便,下面就把最近新学到的东西整理下。就是图文混排的一个list...

Android之ListView包含多种类型的Item

一般情况下,ListView中的Item的类型的都是相同的,即每个Item的布局都调用的同一个XML。但是我们现在的需求需要ListView包含多种类型,需要如何实现呢? 是的,就是覆写Adapte...
  • my9074
  • my9074
  • 2015年03月24日 11:23
  • 1543

listview多种类型条目显示

listview多种类型条目显示 标签: androidlistview 2016-05-29 23:51 122人阅读 评论(0) 收藏 举报 版权声明...

listview多种类型条目显示

一、整个布局是一个listview实线的,而listview里面是嵌套了三种不同展示类型的item,平常只显示一种listview条目,我们会用到常用的四个方法,但是显示不同种类型item的时候,还需...

listview里面的item的多种view模式(多种类型的item)

如果只是简单的实现单一的item,就只要重写下面的四个方法: int getCount():返回数据源中数据项的总数量                  Object getItem(int posi...

Android Drawable多种类型了解

本帖最后由 ivanhxy 于 2013-3-9 11:44 编辑 Android把可绘制的对象抽象为Drawable,不同的图形图像资源就代表着不同的drawable类型。Android Fram...

一个RecyclerView列表显示多种类型的Item

一个列表中Item的显示可能有多种类型,比如Item的界面有多个类型,或者Item的数据有多个类型。 以下自定义了一个Adapter的框架结构,代码简洁,只需稍作修改就可以使用。 /** * 一...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Android】ListView--显示多种类型内容
举报原因:
原因补充:

(最多只允许输入30个字)