聊天界面的制作(二)——发送消息后ListView左右布局显示

基本功能

1. 自定义标题栏。(标题栏不做任何功能)

2. 有左右发送按钮。(这个只能自己和自己聊天哦,所以有左右发送按钮)

  (1)点击左边按钮发送按钮,在ListView的左侧显示。
  (2)点击右边按钮发送按钮,在ListView的右侧显示。
  
3.有表情发送按钮。

  (1)当点击表情发送按钮时, 弹出表情框,点击想要发送的表情将其添加输入框中。
  (2)当在此点击表情按钮时,表情框收回。
  (3)当表情框处在显示状态时, 点击输入框时,表情框收回。

聊天界面的制作(一)——基本布局的实现
聊天界面的制作(三)——表情列表发送功能
源码下载链接

左右发送显示功能

1. 定义一个点击左边发送按钮时,显示在左边的消息布局。
2. 定义一个点击右边发送按钮时,显示在左边的消息布局。
3. 数据M:定义消息的类ChatMessage。

public class ChatMessage {   
    private int imageViewPerson;//人物头像
    private long textViewTime;//显示的时间
    private String textViewHonour;//人物头衔
    private String textviewName;//人物昵称
    private String textViewInput;//说话内容
    private int type;//信息类型,是在左边显示还是右边显示。

    /*
    定义两个构造器,一个无参,一个传值。
     */
    public ChatMessage() {
    }
    public ChatMessage(int imageViewPerson, long textViewTime, String textViewHonour, String textviewName, String textViewInput) {
        this.imageViewPerson = imageViewPerson;
        this.textViewTime = textViewTime;
        this.textViewHonour = textViewHonour;
        this.textviewName = textviewName;
        this.textViewInput = textViewInput;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getImageViewPerson() {
        return imageViewPerson;
    }

    public void setImageViewPerson(int imageViewPerson) {
        this.imageViewPerson = imageViewPerson;
    }

    public long getTextViewTime() {
        return textViewTime;
    }

    public void setTextViewTime(long textViewTime) {
        this.textViewTime = textViewTime;
    }

    public String getTextViewHonour() {
        return textViewHonour;
    }

    public void setTextViewHonour(String textViewHonour) {
        this.textViewHonour = textViewHonour;
    }

    public String getTextviewName() {
        return textviewName;
    }

    public void setTextviewName(String textviewName) {
        this.textviewName = textviewName;
    }

    public String getTextViewInput() {
        return textViewInput;
    }

    public void setTextViewInput(String textViewInput) {
        this.textViewInput = textViewInput;
    }
}

4. 视图V: 定义一个MessageAdapter.
首先定义左右显示的两个布局,左边信息布局:

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

    <TextView
        android:id="@+id/textview_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_margin="5dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/imageview_person"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/person"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"/>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1">

                <TextView
                    android:id="@+id/textview_honor"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="管理员"
                    android:textSize="15sp"
                    android:textColor="@color/white"
                    android:background="@drawable/textview_honour_background"/>

                <TextView
                    android:id="@+id/textview_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:text="名称" />
            </LinearLayout>

            <TextView
                android:id="@+id/textview_input"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:layout_marginRight="50dp"
                android:text="这是显示的信息"
                android:background="@mipmap/textview_input_left"/>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

这里写图片描述

右边信息布局:

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

    <TextView
        android:id="@+id/textview_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:gravity="center" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="right"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1">

                <TextView
                    android:id="@+id/textview_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:text="名称" />

                <TextView
                    android:id="@+id/textview_honor"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/textview_honour_background"
                    android:text="管理员"
                    android:textColor="@color/white"
                    android:textSize="15sp" />

            </LinearLayout>

            <TextView
                android:id="@+id/textview_input"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="50dp"
                android:layout_marginTop="5dp"
                android:background="@mipmap/textview_input_right"
                android:text="这是显示的信息这是显示的信息这是显示的信息这是显示的信息这是显示的信息这是显示的信息这是显示的信息"
                android:textColor="@color/white" />
        </LinearLayout>

        <ImageView
            android:id="@+id/imageview_person"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:src="@mipmap/person" />
    </LinearLayout>
</LinearLayout>

这里写图片描述

定义Adapter适配器,将数据适配到布局中:

public class MessageAdapter extends BaseAdapter {
    public final static int SEND_LEFT = 0;
    public final static int SEND_RIGHT = 1;
    private LayoutInflater mInflater;
    private List<ChatMessage> mData;
    private Html.ImageGetter mImageGetter;
    private SimpleDateFormat format;

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {

        if (0 == mData.get(position).getType()) {
            return SEND_LEFT;//消息类型在左边
        } else if (1 == mData.get(position).getType()) {
            return SEND_RIGHT;//消息类型在右边
        } else {
            return 0;
        }
    }

    public MessageAdapter(LayoutInflater mInflater, List<ChatMessage> mData, Html.ImageGetter mImageGetter) {
        this.mInflater = mInflater;
        this.mData = mData;
        this.mImageGetter = mImageGetter;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            /*
            通过判断消息类型的不同,加载不同的布局。这里使用到了getItemViewType()方法。
             */
            switch (getItemViewType(position)) {
                case SEND_LEFT:
                    convertView = mInflater.inflate(R.layout.listview_lyaout_left, null);
                    break;
                case SEND_RIGHT:
                    convertView = mInflater.inflate(R.layout.listview_layout_right, null);
                    break;
                default:
                    break;
            }
            viewHolder.imageViewPerson = (ImageView) convertView.findViewById(R.id.imageview_person);
            viewHolder.textViewTime = (TextView) convertView.findViewById(R.id.textview_time);
            viewHolder.textViewHonour = (TextView) convertView.findViewById(R.id.textview_honor);
            viewHolder.textViewName = (TextView) convertView.findViewById(R.id.textview_name);
            viewHolder.textViewInput = (TextView) convertView.findViewById(R.id.textview_input);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        ChatMessage data = mData.get(position);
        //如果不是第一个Item且发送消息的两次时间在1min之内,则不再显示时间;否则显示时间
        if (position != 0) {
            ChatMessage dataBefore = mData.get(position - 1);
            long dateDifference = data.getTextViewTime() - dataBefore.getTextViewTime();
            if (dateDifference < 60000) {
                viewHolder.textViewTime.setVisibility(View.GONE);
            } else {
                format = new SimpleDateFormat("EEE HH:mm:ss");
                String time = format.format(new Date(data.getTextViewTime()));
                viewHolder.textViewTime.setText(time);
            }
        } else {
            format = new SimpleDateFormat("EEE HH:mm:ss");
            String time = format.format(new Date(data.getTextViewTime()));
            viewHolder.textViewTime.setText(time);
        }

        viewHolder.imageViewPerson.setImageResource(data.getImageViewPerson());
        viewHolder.textViewHonour.setText(data.getTextViewHonour());
        viewHolder.textViewName.setText(data.getTextviewName());
        //将受到的数据以富文本的形式显示。
        Spanned spanned = Html.fromHtml(data.getTextViewInput(), mImageGetter, null);
        viewHolder.textViewInput.setText(spanned);
        return convertView;
    }
    class ViewHolder {
        ImageView imageViewPerson;
        TextView textViewHonour;
        TextView textViewName;
        TextView textViewTime;
        TextView textViewInput;
    }
}

这里用到了一个知识点,重写BaseAdapter中的两个方法:
  有时候ListView中每个Item的布局不同,这时需要用到Adapter中的两个方法:
public int getViewTypeCount()返回不同布局类型的数量。
public int getItemViewType(int position)返回当前布局类型。
  因为消息类型的不同,以至于显示的Item布局不同,因此需要在ChatMessage中定义一个int 类型的type,通过type来判断显示的消息类型,从而加载不同的布局。

  1. 在MAinActivity中创建两个方法,初始化ChatMessage数据, 创建自定义Adapter的对象,然后setAdapter()。监听两个不同的发送按钮,分别调用下面两个方法。
    (有些数据定义的是全局变量,在此说明下。)
private void showListViewRight() {
        ChatMessage dataRight = new ChatMessage();
        dataRight.setTextViewTime(System.currentTimeMillis());
        dataRight.setTextViewHonour("营长");
        dataRight.setTextviewName("虫虫");
        /*
        判断发送的消息是否为空,如果为空则弹出提示不允许发送
        */
        if (mEditTextInput.getText().equals("")) {
            Toast.makeText(getApplicationContext(), "发送的消息不能为空!", Toast.LENGTH_SHORT).show();
            return;
        }
        dataRight.setTextViewInput(mEditTextInput.getText());
        dataRight.setType(MessageAdapter.SEND_RIGHT);
        mMessageAdapter.notifyDataSetChanged();
        mData.add(dataRight);
        mListView.setAdapter(mMessageAdapter);
        mListView.setSelection(mData.size() - 1);
        mEditTextInput.setText("");
    }
private void showListViewLeft() {
        ChatMessage dataLeft = new ChatMessage();
        dataLeft.setTextViewTime(System.currentTimeMillis());
        dataLeft.setTextViewHonour("营长");
        dataLeft.setTextviewName("虫虫");
        /*
        判断发送的消息是否为空,如果为空则弹出提示不允许发送
        */
        if (mEditTextInput.getText().equals("")) {
            Toast.makeText(getApplicationContext(), "发送的消息不能为空!", Toast.LENGTH_SHORT).show();
            return;
        }
        //将解析的数据添加到输入框中。
       dataLeft.setTextViewInput(HmEditTextInput.getText());
        dataLeft.setType(MessageAdapter.SEND_LEFT);
        mMessageAdapter.notifyDataSetChanged();
        mData.add(dataLeft);
        mListView.setAdapter(mMessageAdapter);
        mListView.setSelection(mData.size() - 1);
        mEditTextInput.setText("");
    }

这里写图片描述

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小_爽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值