Android 聊天界面编写

首先看一下效果图:


首先使用RecyclerView需要添加依赖

compile 'com.android.support:recyclerview-v7:26.0.+'

布局很简单,在上面是一个RecyclerView。下面是一个水平的LinearLarout其中有两个控件,分别是EditText、Button。

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="0dip"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dip"
        android:orientation="horizontal">
        <EditText
            android:id="@+id/edt_msg"
            android:layout_weight="1"
            android:layout_width="0dip"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/btn_send"
            android:padding="3dip"
            android:layout_width="100dip"
            android:layout_height="50dip"
            android:text="发送"/>
    </LinearLayout>
</LinearLayout>

关键布局是RecyclerView中每一个Item的布局,如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:padding="5dip"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!--用来显示接受到的信息-->
    <LinearLayout
        android:id="@+id/rev_layout"
        android:orientation="horizontal"
        android:gravity="left"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/rev_tv"
            android:background="@drawable/left_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <!--用来显示发送出去信息-->
    <LinearLayout
        android:id="@+id/send_layout"
        android:orientation="horizontal"
        android:gravity="right"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/send_tv"
            android:background="@drawable/right_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

可以看到分别用两个TextView显示发送和接收的消息,接受消息的TextView靠左显示android:gravity="left",发送消息的TextView靠右显示android:gravity="right"。注意两个TextView的背景图片是.9图,因为要保证随着消息内容的增多,背景图可以很自然的拉伸,保证不变型。

我们应该用一个实体类来表示消息如下:

public class MsgEntity {
    //分别代表发送和接受消息的类型
    public static final int SEND_MSG=1;
    public static final int RCV_MSG=2;

    //消息内容
    private String content;
    //消息类型
    private int type;

    public MsgEntity(int type, String content) {
        this.type = type;
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    public int getType() {
        return type;
    }
}

对于RecyclerView需要一个适配器,代码很简单。

public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {

    private List<MsgEntity> mMsg;//消息的实体类集合
    private Context mContext;
    public MsgAdapter(Context context,List<MsgEntity> msg){
        this.mMsg=msg;
        this.mContext=context;
    }
    @Override
    public MsgAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(mContext).inflate(R.layout.msg_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MsgAdapter.ViewHolder holder, int position) {
        MsgEntity msg=mMsg.get(position);
        if (msg.getType()==MsgEntity.RCV_MSG){
            //接受消息:让发送消息有关的控件隐藏
            holder.send_layout.setVisibility(View.GONE);
            holder.rev_layout.setVisibility(View.VISIBLE);
            holder.rev_tv.setText(msg.getContent());
        }
        else if (msg.getType()==MsgEntity.SEND_MSG){
            //发送消息:让接收消息有关的控件隐藏
            holder.rev_layout.setVisibility(View.GONE);
            holder.send_layout.setVisibility(View.VISIBLE);
            holder.send_tv.setText(msg.getContent());
        }
    }

    @Override
    public int getItemCount() {
        return mMsg.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{
        LinearLayout rev_layout;
        LinearLayout send_layout;
        TextView rev_tv;
        TextView send_tv;
        public ViewHolder(View itemView) {
            super(itemView);
            rev_layout=itemView.findViewById(R.id.rev_layout);
            send_layout=itemView.findViewById(R.id.send_layout);
            rev_tv=itemView.findViewById(R.id.rev_tv);
            send_tv=itemView.findViewById(R.id.send_tv);
        }
    }
}

可以看到关键的思想是在我们调用onBindViewHolder()方法绑定数据时,先取出消息,然后根据消息的类型来判断是接受到的消息还是发送出去的。如果是接收到的消息就显示左边的LinearLayout给左边TextView设置数据并隐藏右边的用来显示发送消息的那部分控件。发送时同理。

MainActivity.java

public class MainActivity extends AppCompatActivity{

    private RecyclerView recyclerView;
    private EditText edt_msg;
    private Button btn_send;
    private List<MsgEntity> list;//存放消息实体的集合
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();//初始化控件
        initMsg();//模拟消息

        final MsgAdapter msgAdapter=new MsgAdapter(this,list);
        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(msgAdapter);

        btn_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String send_content=edt_msg.getText().toString().trim();
                if (!TextUtils.isEmpty(send_content)){
                    MsgEntity send_msg=new MsgEntity(MsgEntity.SEND_MSG,send_content);
                    list.add(send_msg);
                    //刷新RecyclerView显示
                    msgAdapter.notifyItemInserted(list.size()-1);

                    //模拟接受消息
                    MsgEntity rcv_msg=new MsgEntity(MsgEntity.RCV_MSG,"我也感觉"+send_content);
                    list.add(rcv_msg);
                    msgAdapter.notifyItemInserted(list.size()-1);
                    //将RecyclerView将显示的数据定位到最后一行
                    recyclerView.scrollToPosition(list.size()-1);

                    edt_msg.setText("");//清空消息输入框
                }

            }
        });
    }

    private void initMsg() {
        list=new ArrayList<MsgEntity>();
        MsgEntity msg1=new MsgEntity(MsgEntity.RCV_MSG,"你好啊!我是张");
        MsgEntity msg2=new MsgEntity(MsgEntity.SEND_MSG,"你也好啊!我是李");
        list.add(msg1);
        list.add(msg2);
    }

    //初始化控件
    private void initView() {
        recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
        edt_msg=(EditText)findViewById(R.id.edt_msg);
        btn_send=(Button)findViewById(R.id.btn_send);
    }
}

猜你喜欢

转载自blog.csdn.net/start_mao/article/details/80878096