制作Nine-Patch图片

说明:一种被特殊处理过的图片,指定哪些区域可以被拉伸,哪些区域不可以。
从android Studio2.3开始,不再单独提供draw9patch.bat文件,要生成Nine-Patch图片文件,则在res/drawable目录下添加.png格式的图片,并且将其命名改成bubble_right.9.png形式。


双击打开图片拖拉点限定拉伸区域。

在layout文件中写入如下句子测试拉伸效果:

android:background="@drawable/bubble_right"

添加库依赖

添加RecyclerView的库依赖的参考链接
RecyclerView用法参考
在SDK manager中添加库:

常见问题解决

1、若出现依赖包冲突问题:

All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 27.1.1, 25.3.0. Examples include com.android.support:animated-vector-drawable:27.1.1 and com.android.support:design:25.3.0 less... (Ctrl+F1)
There are some combinations of libraries, or tools and libraries, that are incompatible, or can lead to bugs. One such incompatibility is compiling with a version of the Android support libraries that is not the latest version (or in particular, a version lower than your targetSdkVersion.)

按提示加入

//noinspection GradleCompatible

2、若出现Configuration ‘compile’ is obsolete and has been replaced with ‘implementation’ and ‘api’.的问题是因为有些配置过时,其解决方式如下:
compile 改成implementation
androidTestCompile改成androidTestImplementation
testCompile 改成testImplementation

3、若出现Failed to resolve: com.android.support:recyclerview-v7:28.0.0,提示migrate to androidX libraries问题:

这是因为添加了不存在的依赖
在build gradle中发现此时依赖中的编译版本和配置中的依赖版本不同:

修改其中的三句话重新编译即可

    compileSdkVersion 28targetSdkVersion 28

4、若出现闪退问题
教程上recyclerview写法如下,一直会出现闪退问题

<android.support.v7.widget.RecyclerViewandroid:id="@+id/msg_recycler_view"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />

如下修改代码,问题解决:

<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/msg_recycler_view"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/>

编写聊天界面

chat.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#d8e0e8"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/msg_recycler_view"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:divider="#0000"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><EditTextandroid:id="@+id/input_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:hint="Type something here"android:maxLines="2" /><Buttonandroid:id="@+id/send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Send" /></LinearLayout></LinearLayout>

msg_item.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="wrap_content"android:orientation="vertical"android:padding="10dp"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:id="@+id/head_left"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="left"android:src="@drawable/portrait1"/><LinearLayoutandroid:id="@+id/left_layout"android:layout_height="wrap_content"android:layout_width="wrap_content"android:layout_gravity="left"android:background="@drawable/bubble_left"><TextViewandroid:id="@+id/left_msg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="10dp"android:textColor="#fff"/></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="right"android:orientation="horizontal"><LinearLayoutandroid:id="@+id/right_layout"android:layout_height="wrap_content"android:layout_width="wrap_content"android:layout_gravity="right"android:background="@drawable/bubble_right"><TextViewandroid:id="@+id/right_msg"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="10dp"/></LinearLayout><ImageViewandroid:id="@+id/head_right"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/portrait2"/></LinearLayout></LinearLayout>

Msg类

package com.example.wechat;public class Msg {//收到的消息public static final int TYPE_RECEIVED = 0;//发送的消息public static final int TYPE_SEND=1;private String content;private int type;public Msg(String content,int type){this.content=content;this.type=type;}public String getContent(){return content;}public int getType(){return type;}
}

MsgAdapter类

package com.example.wechat;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;import java.util.List;public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {private List<Msg> mMsgList;static class ViewHolder extends RecyclerView.ViewHolder{LinearLayout leftLayout;LinearLayout rightLayout;TextView leftMsg;TextView rightMsg;ImageView protrait1;ImageView protrait2;public ViewHolder(View view){super(view);leftLayout=(LinearLayout)view.findViewById(R.id.left_layout);rightLayout=(LinearLayout)view.findViewById(R.id.right_layout);leftMsg=(TextView)view.findViewById(R.id.left_msg);rightMsg=(TextView)view.findViewById(R.id.right_msg);protrait1=(ImageView)view.findViewById(R.id.head_right);protrait2=(ImageView)view.findViewById(R.id.head_left);}}public MsgAdapter(List<Msg> msgList){mMsgList=msgList;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){//onCreateViewHolder()用于创建ViewHolder实例View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item,parent,false);return new ViewHolder(view);//把加载出来的布局传到构造函数中,再返回}@Overridepublic void onBindViewHolder(ViewHolder Holder,int position){//onBindViewHolder()用于对RecyclerView子项的数据进行赋值,会在每个子项被滚动到屏幕内的时候执行Msg msg=mMsgList.get(position);if(msg.getType()==Msg.TYPE_RECEIVED){//增加对消息类的判断,如果这条消息是收到的,显示左边布局,是发出的,显示右边布局Holder.leftLayout.setVisibility(View.VISIBLE);Holder.protrait2.setVisibility(View.VISIBLE);Holder.rightLayout.setVisibility(View.GONE);Holder.protrait1.setVisibility(View.GONE);Holder.leftMsg.setText(msg.getContent());}else if(msg.getType()==Msg.TYPE_SEND) {Holder.rightLayout.setVisibility(View.VISIBLE);Holder.protrait1.setVisibility(View.VISIBLE);Holder.leftLayout.setVisibility(View.GONE);Holder.protrait2.setVisibility(View.GONE);Holder.rightMsg.setText(msg.getContent());}}@Overridepublic int getItemCount(){return mMsgList.size();}
}

Main类

package com.example.wechat;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;import java.util.ArrayList;
import java.util.List;public class Main extends AppCompatActivity {private List<Msg> msgList=new ArrayList<>();private EditText inputText;private Button send;private RecyclerView msgRecyclerView;private MsgAdapter adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.chat);//初始化消息数据initMsgs();inputText=(EditText)findViewById(R.id.input_text);send=(Button)findViewById(R.id.send);msgRecyclerView=(RecyclerView)findViewById(R.id.msg_recycler_view);//LinearLayoutLayout即线性布局,创建对象后把它设置到RecyclerView当中LinearLayoutManager layoutManager=new LinearLayoutManager(this);msgRecyclerView.setLayoutManager(layoutManager);//创建MsgAdapter的实例并将数据传入到MsgAdapter的构造函数中adapter=new MsgAdapter(msgList);msgRecyclerView.setAdapter(adapter);//发送按钮点击事件send.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View v){//获取EditText中的内容String content=inputText.getText().toString();//内容不为空则创建一个新的Msg对象,并把它添加到msgList列表中if(!"".equals(content)){Msg msg=new Msg(content,Msg.TYPE_SEND);msgList.add(msg);//调用适配器的notifyItemInserted()用于通知列表有新的数据插入,这样新增的一条消息才能在RecyclerView中显示adapter.notifyItemInserted(msgList.size()-1);//调用scrollToPosition()方法将显示的数据定位到最后一行,以保证可以看到最后发出的一条消息msgRecyclerView.scrollToPosition(msgList.size()-1);//调用EditText的setText()方法将输入的内容清空inputText.setText("");}}});}private void initMsgs(){Msg msg1=new Msg("Hello guy.",Msg.TYPE_RECEIVED);msgList.add(msg1);Msg msg2=new Msg("Hello.Who is that?",Msg.TYPE_SEND);msgList.add(msg2);Msg msg3=new Msg("This is Tom!",Msg.TYPE_RECEIVED);msgList.add(msg3);}
}

效果演示

书小宅之android——聊天界面的实现相关推荐

  1. Android 聊天界面对话

    转载请注明出处:http://blog.csdn.net/htwhtw123/article/details/77510010 实现Android 聊天界面对话 ,可以设计成接受到的消息在左显示,发送 ...

  2. 微信小程序-模仿绘制聊天界面

    参考文章 1.小程序模仿微信聊天界面 2.微信小程序实现仿微信聊天界面(各种细节处理) 3.微信小程序之页面中关于聊天框三角形的制作和使用 4.仿微信聊天记录时间显示 5.微信小程序-同时获取麦克风. ...

  3. 书小宅之网页设计——用之有道

    网页标题title:title定义的标题仅是在浏览器标题栏中显示的信息.title作为属性用来定义提示文本. 网页内容的标题hi:一般一个网页应该只有一个一级标题(主标题),也就是说网页内容应该只用依 ...

  4. Android 聊天界面背景图片不顶上去内容顶上去解决方法

    Android 聊天界面背景图片被输入法 字数398  阅读923  评论0  喜欢14 相信做过android开发的都知道,当界面中有editText的时候,输入法可能导致把当前界面整个给顶上去,这 ...

  5. android聊天界面与功能,【android】聊天界面的制作-简易版实现

    看完了第一行代码第三章,改进了一些基本功能,下面就听小弟一一道来: 也参考了很多别人的代码,但是总觉得一些功能可以比较轻松的实现就不绕那么多弯子,就用最基础的码代码实现一样的功能:(1)整体布局代码一 ...

  6. 融云android聊天界面,Android 融云IM集成以及使用详解(一)

    Android 融云IM集成以及使用详解(一) 集成 1.具体的集成步骤就不在详细介绍,我们只说干货,附上融云IM官方文档地址,里面有更为详细的集成介绍 https://www.rongcloud.c ...

  7. Android聊天界面中图片大小的合理缩小算法

    应用场景 我们知道在聊天界面中,发送显示图片是不可缺少的一部分,这个时候就会面临对于图片显示控件的缩小处理.当然如果是简单的给ImageView设置一个固定的值的话,这篇文章就没有意义了.我们要做的就 ...

  8. android仿抖音直播间聊天,Uni-App直播小视频|仿微信聊天界面|uniapp仿抖音

    U直播是一个基于Nvue+vue+uniapp技术开发的仿抖音小视频.陌陌直播的项目.小视频及直播页面均实现了类似抖音上下滑动切换效果,还有点赞.评论.商品等功能展示. 运行效果: 技术实现:编辑器+ ...

  9. android聊天界面对话气泡_你在和脚本谈恋爱(自动化在IM聊天中的应用)

    谢谢打开这篇文章的每个你 测开之分层自动化(Python)招生简章 Python自动化测试报告美化 在python中进行数据驱动测试 太嚣张了!他竟用Python绕过了"验证码" ...

最新文章

  1. 程序员面试拼多多,来看看这些面试题你掌握的有多少呢?
  2. c语言可移植性较差吗,c陷阱与缺陷--可移植性缺陷
  3. 虚拟机ubuntu19.04下设置idea快捷键
  4. mac安装mysql遇到的坑
  5. 关于CNN的权重共享,CNN到底学到了什么?
  6. ruby mysql 占位符_ruby操作常用数据库
  7. cognos的HTMl显示,cognos利用html项目和提示元素结合
  8. 如何带领好一个团队,管理的五条实用建议告诉你
  9. excel求回归直线方程的公式_如何用excel快速求线性回归方程?
  10. 电路设计_STM8S003F3P6 AWUADC使用小结
  11. 2016 安全行业全景图——By 安全牛
  12. python数据分析简历_帮粉丝推荐简历|Python数据分析师
  13. 线上问题:java.sql.SQLException: connection holder is null
  14. 组装台式机后进入PE,检测不到硬盘的解决方法
  15. CC2530(SPI)驱动FLASH芯片W25Qxx
  16. APP测试基本流程以及APP测试要点梳理,成功入职就靠它了
  17. VBA快速入门学习笔记
  18. webScoket即时聊天,用户不在线时消息暂存,上线立马收到
  19. 【转载】P2P系统频现安全漏洞 技术短板将致行业洗牌
  20. Nginx + VFP FastCGI开发说明

热门文章

  1. matlab读取xlsx文件,将大Excel(xlsx)文件加载到matlab中
  2. CVE-2014-6321 schannel堆溢出漏洞分析
  3. 项目总结(二) 网格化管理系统问题总结
  4. png格式图片 转 icns格式图标
  5. 计算机通信机房消防要求,信息机房对环境有什么要求
  6. 02 【uni-app起步】
  7. 一文掌握项目甘特图的使用方法
  8. 写了一个简单的画板 箭头比较难搞 虚线 虚直线 实线 实直线 椭圆 圆 正方形
  9. layui 怎么设置点击图片放大_layui图片如何放大
  10. 扇贝编程可以用c语言吗,扇贝编程手机版下载_扇贝编程app下载 v1.1.41 - 87G手游网...