ListView学习(四)

本文介绍如何为聊天应用设计ListView,通过自定义Adapter支持不同类型的聊天消息布局,包括接收和发送消息的不同显示样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

聊天 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);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值