聊天 ListView
通常的 ListView 的每一项都具有相同的布局,在聊天界面,会展示至少两种布局,既收的的消息和自己发送的消息。
我们通过修改 ListView 的 Adapter 可以达到拥有两个布局的效果。
在定义 BaseAdapter 的时候,需要去重写它的 getView()方法,这个方法就是用来获取布局的,那么只需要在获取布局的时候,判断一下该获取哪一种布局就可以了。而且 ListView 在设计的时候就已经考虑到了这种情况,所以它提供了两个方法,代码如下:
@Override
public int getItemViewType(int position){
return type;
}
@Override
public int getViewTypeConut(){
return number;
}
ChatItemListViewAdapter 的代码
public class ChatItemListViewAdapter extends BaseAdapter {
private List<ChatItemListViewBean> mData;
private LayoutInflater mInflater;
public ChatItemListViewAdapter(Context context, List<ChatItemListViewBean> data){
this.mData = data;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
ChatItemListViewBean bean = mData.get(position);
return bean.getType();
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
if(getItemViewType(position) == 0){//in
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.chat_item_itemin,null);
holder.icon = (ImageView) convertView.findViewById(R.id.icon_in);
holder.text = (TextView) convertView.findViewById(R.id.text_in);
}else if(getItemViewType(position) == 1){//out
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.chat_item_itemout,null);
holder.icon = (ImageView) convertView.findViewById(R.id.icon_out);
holder.text = (TextView) convertView.findViewById(R.id.text_out);
}
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
//设置视图数据
holder.icon.setImageBitmap(mData.get(position).getIcon());
holder.text.setText(mData.get(position).getText());
Log.d("TAG",mData.get(position).getText());
return convertView;
}
public final class ViewHolder{
public ImageView icon;
public TextView text;
}
}
getItemViewType()方法用来返回第 position 个 Item 是何种类型,而 getViewTypeCount()方法用来返回不同布局的总数。通过这两个方法,再结合 getView()方法,就可以轻松的设计出上面的聊天布局了
首先实现两个布局————chat_item_itemin 和 chat_item_itemout。布局大同小异,只是方向上有区别,显示聊天信息内容的 TextView 使用了 9patch 的图片。这种图片格式是 Android 中用来拉伸图片的,在某些方向上拉伸却不会失真,形变的图片。由于 in 和 out 界面内容只是方向上的区别。
同时,为了封装下聊天的内容,便于在 Adapter 中获取数据信息,我们封装了一个 Bean 来保存聊天信息,代码如下:
public class ChatItemListViewBean{
private int type;
private String text;
private Bitmap icon;
public ChatItemListViewBean(){
}
public int getType(){
return type;
}
public void setType(int type){
this.type = type;
}
public String getText(){
return text;
}
public void setText(String text){
this.text = text;
}
public Bitmap getIcon(){
return icon;
}
public void setIcon(Bitmap icon){
this.icon = icon;
}
}
下面是布局文件
接收到的消息的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|left">
<ImageView
android:id="@+id/icon_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/text_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/chatitem_in_bg"
android:gravity="center"
android:textSize="20sp"/>
</LinearLayout>
发送出去的消息的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|right">
<TextView
android:id="@+id/text_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/chatitem_out_bg"
android:gravity="center"
android:textSize="20sp"/>
<ImageView
android:id="@+id/icon_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
Activity
public class ChatActivity extends AppCompatActivity {
private ListView mListView;
private ChatItemListViewAdapter mAdapter;
private List<ChatItemListViewBean> mData;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_item_main);
mListView = (ListView) findViewById(R.id.listView_chat);
ChatItemListViewBean bean1 = new ChatItemListViewBean();
bean1.setText("hello i am wang");
bean1.setType(0);//in
bean1.setIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
ChatItemListViewBean bean2 = new ChatItemListViewBean();
bean2.setText("i am gu ");
bean2.setType(1);
bean2.setIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
ChatItemListViewBean bean3 = new ChatItemListViewBean();
bean3.setText("hello i am wang");
bean3.setType(0);//in
bean3.setIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
ChatItemListViewBean bean4 = new ChatItemListViewBean();
bean4.setText("i am gu ");
bean4.setType(1);
bean4.setIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
ChatItemListViewBean bean5 = new ChatItemListViewBean();
bean5.setText("hello i am wang");
bean5.setType(0);//in
bean5.setIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
mData = new ArrayList<>();
mData.add(bean1);
mData.add(bean2);
mData.add(bean3);
mData.add(bean4);
mData.add(bean5);
mAdapter = new ChatItemListViewAdapter(this,mData);
mListView.setAdapter(mAdapter);
}
}