Android ListView 聊天界面
本章节我们用 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>
-
在
MainActivity.java
目录下创建一个文件ChatBean.java
package cn.twle.android.listviewchat; class ChatBean { private String name; private String say; private int icon; public ChatBean() {} 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"); } }
-
修改
MainActivity.java
package cn.twle.android.listviewchat; 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); } }
运行如下,爆丑无比