添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本章节我们用 ListView 实现一个类似微信聊天布局的页面,另一方面加强下前一章节的可复用 Base Adapter 的认识

仔细看一下你手机上的微信聊天布局,自己发的东西永远在右边,而朋友发的永远在左边

如果用 ListView 来实现,那么就有两种不同风格的 item ,一左一右

Android Adapter 适配器 章节,我们有说过, Adapter 接口定义了两个方法 getItemViewType() getViewTypeCount() 用来返回 View 对应哪个类型和 View 类型的数量

本章我们主要就是重写这两个方法,来获取左右两边不同的 View

创建一个 空的 Android 项目 cn.twle.android.ListViewChart

下载 /static/i/android/it_language_icon.zip 解压并把所有的图片拖到 res/drawable 目录

新建一个包 cn.twle.android.common 然后下载 /static/i/android/MsAdapter.java 放到该目录下

修改 activity_main.xml 添加一个列表

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

接下来添加两种类型的列表项,在 res/layout 目录下新建一个文件 chat_left.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="horizontal"
    android:padding="5dp">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:layout_weight="1" 
        android:src="@drawable/scala" />
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="6"
        android:text="Scala"
        android:textSize="20sp" />
</LinearLayout>

接下来添加两种类型的列表项,在 res/layout 目录下新建一个文件 chat_right.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="horizontal"
    android:padding="5dp">
    <TextView
        android:id="@+id/name"
        android:gravity="right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="6"
        android:text="Kotlin"
        android:textSize="20sp" />
    <ImageView
        android:id="@+id/icon"
        android:layout_weight="1"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:src="@drawable/kotlin" />
</LinearLayout>
    public ChatBean(String name,int icon,String say) {
        this.name = name;
        this.say  = say;
        this.icon = icon;
    public int getIcon() {
        return icon;
    public void setIcon(int icon) {
        this.icon = icon;
    public String getName() {
        return  name;
    public String getSay() {
        return  say;
    public void setName(String name) {
        this.name = name;
    public void setSay(String say) {
        this.say = say;
    public Boolean isMe() {
        return name.toLowerCase().equals("kotlin");
import cn.twle.android.common.MsAdapter;
import android.content.Context;
import android.util.Log;
import android.view.ViewGroup;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.view.View;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
    private ListView listview_chat;
    private ArrayList<ChatBean> mData = null;
    private MsAdapter chatAdapter = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //数据准备:
        mData = new ArrayList<ChatBean>();
        mData.add(new ChatBean("Kotlin", R.drawable.kotlin,"Kotlin"));
        mData.add(new ChatBean("Swift",  R.drawable.swift,"Swift"));
        mData.add(new ChatBean("Kotlin", R.drawable.kotlin,"Kotlin"));
        mData.add(new ChatBean("Scala", R.drawable.scala,"Scala"));
        mData.add(new ChatBean("TypeScript", R.drawable.typescript,"TypeScript"));
        listview_chat = (ListView) findViewById(R.id.listview_chat);
        chatAdapter = new MsAdapter<ChatBean>(mData,R.layout.chat_left){
            //定义两个类别标志
            private static final int TYPE_LEFT = 0;
            private static final int TYPE_RIGHT = 1;
            //多布局的核心,通过这个判断类别
            @Override
            public int getItemViewType(int position) {
                ChatBean chat = (ChatBean)mData.get(position);
                if (chat.isMe()) {
                    return TYPE_RIGHT;
                return TYPE_LEFT;
            // 类别数目
            @Override
            public int getViewTypeCount() {
                return 2;
            public View getView(int position, View convertView, ViewGroup parent) {
                int t = getItemViewType(position);
                Log.d("T",String.valueOf(t));
                int ly = R.layout.chat_left;
                ViewHolder holder;
                switch (t) {
                    case TYPE_LEFT:
                        ly = R.layout.chat_left;
                        holder = ViewHolder.bind(parent.getContext(), convertView, parent, ly
                                , position);
                        break;
                    default:
                        ly = R.layout.chat_right;
                        Log.d("","in right");
                        holder = ViewHolder.bind(parent.getContext(), convertView, parent, ly
                                , position);
                        break;
                bindView(holder, getItem(position));
                return holder.getItemView();
            @Override
            public void bindView(ViewHolder holder, ChatBean obj)
                holder.setImageResource(R.id.icon,obj.getIcon());
                holder.setText(R.id.name,obj.getName());
        listview_chat.setAdapter(chatAdapter);