【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);
    }
}







android之优雅书写多类型Adapter

android之优雅书写多类型Adapter
  • zhongwn
  • zhongwn
  • 2017年01月21日 15:54
  • 632

Android--listview多种类型item

1、原理分析                  Adapter对于ListView是非常重要的,它处于listView和数据源的中间,负责为ListView创建具体的视图。之前提到过ListVie...
  • ccc20134
  • ccc20134
  • 2015年08月19日 18:04
  • 4292

ListView--内容不显示

1.ListView所在布局 2.ListView所做操作 @Override protected void onMeasure(int widthMeasureSpec, i...
  • qq_16265721
  • qq_16265721
  • 2016年09月02日 12:57
  • 178

ListView滑动菜单

项目中使用到了listview中item滑动效果,找了几个,最后发个一个很不错的Swipemenulistview,记录下来,以备后用 github上的一个开源库,非常好用,git地址:https:/...
  • leokelly001
  • leokelly001
  • 2015年04月26日 16:53
  • 1460

listview多种类型条目显示

一、整个布局是一个listview实线的,而listview里面是嵌套了三种不同展示类型的item,平常只显示一种listview条目,我们会用到常用的四个方法,但是显示不同种类型item的时候,还需...
  • Android_my
  • Android_my
  • 2016年05月29日 23:51
  • 6624

mr分类输出(MultipleOutputs)

原始数据:[INFO]127.0.0.1 2016-04-14 09:06:33 vi 200 [DEBUG]127.0.0.1 2016-04-13 09:06:40 rm 200 [FETAL...
  • HANLIPENGHANLIPENG
  • HANLIPENGHANLIPENG
  • 2016年10月10日 22:30
  • 310

ListView显示多种类型的条目

ListView显示多种类型的条目
  • u010375364
  • u010375364
  • 2016年07月17日 10:51
  • 1566

分窗口与多视图

        首先要创建一个单文档SDI应用程序,注意要在“用户界面功能”页面上选择“拆分窗口”的复选框,此时应用程序生成向导已经在Mainfrm.h中声明了一个变量:CSplitterWnd m_...
  • kybd2006
  • kybd2006
  • 2007年04月24日 18:04
  • 633

几种常见的Android自动化测试框架及其应用

随着Android应用得越来越广,越来越多的公司推出了自己移动应用测试平台。例如,百度的MTC、东软易测云、Testin云测试平台……。由于自己所在项目组就是做终端测试工具的,故抽空了解了下几种常见的...
  • Faly_love
  • Faly_love
  • 2016年05月13日 17:25
  • 2004

Android 4.0 Notification内容过长被截断,无法完整显示

前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net       ...
  • luckkof
  • luckkof
  • 2013年05月22日 17:28
  • 2958
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Android】ListView--显示多种类型内容
举报原因:
原因补充:

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