本次的代码部分参考郭霖——《第一行代码》,学习recyclervIEw章节后手动编写的。
.9图制作.9图素材是本人用windows附件中的画图工具制作的(就是找不到资源),然后导入AndroID Studio后进行编辑和引用。
气泡聊天背景的制作过程 在很多文章中有介绍,在此就不重复了。这里说一个我遇到的问题,在编辑时勾选了Show Content 和 Show Bad patches选项后,在图片中会报错红色区域。此时把左侧的拉伸区域限制到帧数较高的区域即可具体对比如下:在我编辑的时候,图片中的红框怎么调都不会消失,也没有找到对应解决办法,偶然发现把左侧的黑线区域向下移动一下就可以了。//此处求大佬解释
更改后的图如下:
此时.9图制作的差不多了,可以开始接下来的 *** 作了。
布局代码编写开始编写布局代码,此部分代码因为我迁移到了androIDx,所以引用方式不同。 添加RecyclerVIEw;<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:app="http://schemas.androID.com/apk/res-auto" xmlns:tools="http://schemas.androID.com/tools" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" tools:context=".MainActivity" androID:orIEntation="vertical"> <androIDx.recyclervIEw.Widget.RecyclerVIEw androID:ID="@+ID/msg_vIEw" androID:layout_wIDth="match_parent" androID:layout_height="0dp" androID:layout_weight="1" /> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> <button androID:ID="@+ID/msg_voice" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="S" androID:textSize="20sp"/> <EditText androID:ID="@+ID/msg_edit" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:hint="请输入" androID:maxlines="2"/> <button androID:ID="@+ID/msg_send" androID:layout_wIDth="wrap_content" androID:layout_height="match_parent" androID:text="发送" androID:textSize="20sp" androID:background="#FF03DAC5"/> </linearLayout></linearLayout>
2.再创建一个item布局来装载消息,注意在这一步中我不小心把最外层的layout_height的值设置成了match_parent,最后运行程序就成了一条消息占据了一个屏幕页,正确的值应该设置为wrap_content;
<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> <linearLayout androID:ID="@+ID/layout_left" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_gravity="left"> <ImageVIEw androID:ID="@+ID/image_left" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="@drawable/ai"/> <TextVIEw androID:ID="@+ID/msg_left" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="@drawable/msgleft" androID:padding="10dp" androID:layout_gravity="center"/> </linearLayout> <linearLayout androID:ID="@+ID/layout_right" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_gravity="right"> <TextVIEw androID:ID="@+ID/msg_right" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="@drawable/msgright" androID:layout_gravity="right" androID:padding="10dp"/> <ImageVIEw androID:ID="@+ID/image_right" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="@drawable/me"/> </linearLayout></linearLayout>
代码部分新建一个实体类,来区分消息类型;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; }}
创建适配器,用于实现把要展示的数据源传进来,然后可以基于这些数据源进行 *** 作,包括设置当消息类型为接收时隐藏右边的消息框,当消息为发送时,隐藏左边的对话框,在适配器里面,需要重写onCreatVIEwHolder()、onBindVIEwHolder()和getItemCoun()三个方法,在写适配器继承于RecyclerVIEw.Adapter的时候系统会自动提醒你;public class MsgAdapter extends RecyclerVIEw.Adapter<MsgAdapter.VIEwHolder> { private List<Msg>mMsgList; static class VIEwHolder extends RecyclerVIEw.VIEwHolder{ linearLayout leftLayout; linearLayout rightLayout; ImageVIEw leftimage; ImageVIEw rightimage; TextVIEw leftMsg; TextVIEw rightmsg; public VIEwHolder( VIEw vIEw) { super(vIEw); leftLayout = vIEw.findVIEwByID(R.ID.layout_left); rightLayout = vIEw.findVIEwByID(R.ID.layout_right); leftimage = vIEw.findVIEwByID(R.ID.image_left); rightimage = vIEw.findVIEwByID(R.ID.image_right); leftMsg = vIEw.findVIEwByID(R.ID.msg_left); rightmsg = vIEw.findVIEwByID(R.ID.msg_right); } } public MsgAdapter(List<Msg>msgList){ mMsgList = msgList; } @OverrIDe public VIEwHolder onCreateVIEwHolder( VIEwGroup parent, int vIEwType) { VIEw vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item,parent,false); return new VIEwHolder(vIEw); } @OverrIDe public voID onBindVIEwHolder( VIEwHolder holder, int position) { Msg msg = mMsgList.get(position); if (msg.getType() == Msg.TYPE_RECEIVED){ //如果是收到的消息,则显示在左边的布局,隐藏右边的布局 holder.leftLayout.setVisibility(VIEw.VISIBLE); holder.rightLayout.setVisibility(VIEw.GONE); holder.leftMsg.setText(msg.getContent()); }else if (msg.getType() == Msg.TYPE_SEND){ //如果是发出的消息,则显示在右边的布局,隐藏左边的布局 holder.leftLayout.setVisibility(VIEw.GONE); holder.rightLayout.setVisibility(VIEw.VISIBLE); holder.rightmsg.setText(msg.getContent()); } } @OverrIDe public int getItemCount() { return mMsgList.size(); }}
编写主代码,这里主要时调用适配器的notifyItemInserted()方法,来通知列表有新的数据插入。还有scrollToposition()用于定位到最后一行,这样才能显示最后一行的消息;public class MainActivity extends AppCompatActivity { private List<Msg>msgList = new ArrayList<>(); private EditText inputText; private button sendtext; private button sendvoice; private RecyclerVIEw msgRecycleVIEw; private MsgAdapter adapter; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); initMsgs(); inputText = findVIEwByID(R.ID.msg_edit); sendtext = findVIEwByID(R.ID.msg_send); sendvoice = findVIEwByID(R.ID.msg_voice); msgRecycleVIEw = findVIEwByID(R.ID.msg_vIEw); linearlayoutmanager layoutManager = new linearlayoutmanager(this); msgRecycleVIEw.setLayoutManager(layoutManager); adapter = new MsgAdapter(msgList); msgRecycleVIEw.setAdapter(adapter); sendtext.setonClickListener(v -> { String content = inputText.getText().toString(); if(!"".equals(content)){ Msg msg = new Msg(content,Msg.TYPE_SEND); msgList.add(msg); adapter.notifyItemInserted(msgList.size() - 1);//当有消息时刷新RecycleVIEw中的显示 msgRecycleVIEw.scrollToposition(msgList.size() - 1);//将RecycleVIEw定位到最后一行 inputText.setText("");//最后清空输入框中的内容 } }); } private voID initMsgs(){ Msg msg1 = new Msg("你好",Msg.TYPE_RECEIVED); msgList.add(msg1); Msg msg2 = new Msg("你好",Msg.TYPE_SEND); msgList.add(msg2); Msg msg3 = new Msg("很高兴认识你",Msg.TYPE_RECEIVED); msgList.add(msg3); }}
最后有一个重要的东西,我的真机是MI10,我把.9图放到drawable和drawable-hdpi中都不能显示.9图的引用效果。最后看到一位博主的解决办法得到灵感,想到在安卓版本较高的情况下,需要把图片资源放到xxxhdpi后缀的资源包下才能被显示出来,这里同理,同时可以观察在drawable下面的mipmap的命名规则也是这样的。
第一次写文章,如果有错望大家指出,我会积极修正。
总结以上是内存溢出为你收集整理的Android学习笔记——RecyclerView编写气泡聊天全部内容,希望文章能够帮你解决Android学习笔记——RecyclerView编写气泡聊天所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)