安卓Android实现聊天滚动界面

原帖: 跳转

Android实现聊天界面

 更新时间:2018年06月13日 14:14:05   作者:Thierryxc  
这篇文章主要为大家详细介绍了Android实现聊天界面的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
java

本文实例为大家分享了Android实现聊天界面的具体代码,供大家参考,具体内容如下

文件目录

在app下的build.gradle中添加依赖库(RecyclerView)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apply plugin: 'com.android.application'
 
android {
   compileSdkVersion 24
   buildToolsVersion "26.0.1"
   defaultConfig {
     applicationId "com.example.uibestpractice"
     minSdkVersion 15
     targetSdkVersion 24
     versionCode 1
     versionName "1.0"
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
   }
   buildTypes {
     release {
       minifyEnabled false
       proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguarrules.pro'
     }
   }
}
 
dependencies {
   compile fileTree(dir: 'libs' , include: [ '*.jar' ])
   androidTestCompile( 'com.android.support.test.espresso:espresso-core:2.2.2' , {
     exclude group: 'com.android.support' , module: 'support-annotations'
   })
   compile 'com.android.support:appcompat-v7:24.2.1'
   compile 'com.android.support.constraint:constraint-layout:1.0.2'
   compile 'com.android.support:recyclerview-v7:24.2.1' //添加RecyclerView依赖库
   testCompile 'junit:junit:4.12'
}

编写主界面(activity_main.xml)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<? 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 = "#d8e0d8" >
 
< android.support.v7.widget.RecyclerView
   android:id = "@+id/msg_recycler_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" >
 
   < EditText
     android: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" />
 
   < Button
     android:id = "@+id/send"
     android:layout_width = "wrap_content"
     android:layout_height = "wrap_content"
     android:text = "Send" />
 
</ LinearLayout >
 
</ LinearLayout >
  • 在主界面中放置的RecyclerView用于显示消息
  • EditText用于编辑消息
  • Button用于发送消息

定义消息的实体类Msg

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.uibestpractice;
 
public class Msg {
   public static final int TYPE_RECEIVED = 0 ;
   public static final int TYPE_SENT = 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;
   }
}
  • 用两个常量来表示消息的类型(接收的还是发送的)

编写RecyclerView的子布局(msg_item.xml)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<? 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 = "wrap_content"
   android:padding = "10dp" >
 
   < LinearLayout
     android:id = "@+id/left_layout"
     android:layout_width = "wrap_content"
     android:layout_height = "wrap_content"
     android:layout_gravity = "left"
     android:background = "@drawable/message_left" >
 
     < TextView
       android: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
     android:id = "@+id/right_layout"
     android:layout_width = "wrap_content"
     android:layout_height = "wrap_content"
     android:layout_gravity = "right"
     android:background = "@drawable/message_right" >
 
     < TextView
       android:id = "@+id/right_msg"
       android:layout_width = "wrap_content"
       android:layout_height = "wrap_content"
       android:layout_gravity = "center"
       android:layout_margin = "10dp" />
   </ LinearLayout >
 
</ LinearLayout >
  • 将接收的消息居左对齐,发送的消息居右对齐

创建RecyclerView适配器类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.example.uibestpractice;
 
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
 
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 rihgtMsg;
 
     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);
       rihgtMsg = (TextView) view.findViewById(R.id.right_msg);
     }
   }
 
   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_SENT) {
       holder.rightLayout.setVisibility(View.VISIBLE);
       holder.leftLayout.setVisibility(View.GONE);
       holder.rihgtMsg.setText(msg.getContent());
     }
   }
 
   @Override
   public int getItemCount() {
     return mMsgList.size();
   }
}
  • 定义了一个内部类ViewHolder,继承自RecyclerView.ViewHolder。ViewHolder的构造函数中传入一个View参数,这个参数通常是RecyclerView子项的最外层布局,这样我们就可以通过findViewById()方法来获取布局中的接收和发送消息布局的实例了。
  • MsgAdapter中也有一个构造函数,将要展示的数据源传进来复制给mMsgList。
  • MsgAdapter继承自RecyclerView.Adapter,必须重写onCreateViewHolder()、onBindViewHolder()、getItemCount()三个方法。
  • onCreateViewHolder()用于创建ViewHolder实例,在这个方法中将msg_item布局加载进来,然后创建一个ViewHolder实例,并把加载出来的布局传到构造函数中,返回实例。
  • onBindViewHolder()用于对RecyclerView子项的数据进行赋值。
  • getItemCount()获得RecyclerView有多少个子项

使用RecyclerView(修改MainActivity)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.example.uibestpractice;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity {
   private List<Msg> msgList = new ArrayList<>();
   private EditText inputText;
   private Button send;
   private RecyclerView msgRecyclerView;
   private MsgAdapter adapter;
 
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super .onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     initMsgs();
     inputText = (EditText) findViewById(R.id.input_text);
     send = (Button) findViewById(R.id.send);
     msgRecyclerView = (RecyclerView) findViewById(R.id.msg_recycler_view);
     LinearLayoutManager layoutManager = new LinearLayoutManager( this );
     msgRecyclerView.setLayoutManager(layoutManager);
     adapter = new MsgAdapter(msgList);
     msgRecyclerView.setAdapter(adapter);
     send.setOnClickListener( new View.OnClickListener() {
       @Override
       public void onClick(View v) {
         String content = inputText.getText().toString();
         if (! "" .equals(content)) {
           Msg msg = new Msg(content,Msg.TYPE_SENT);
           msgList.add(msg);
           adapter.notifyItemInserted(msgList.size()- 1 );
           msgRecyclerView.scrollToPosition(msgList.size()- 1 );
           inputText.setText( "" );
         }
       }
     });
   }
 
   private void initMsgs() {
     Msg msg1 = new Msg( "Hello" ,Msg.TYPE_RECEIVED);
     msgList.add(msg1);
     Msg msg2 = new Msg( "I'm John" ,Msg.TYPE_RECEIVED);
     msgList.add(msg2);
     Msg msg3 = new Msg( "Hello" ,Msg.TYPE_SENT);
     msgList.add(msg3);
   }
}

onCreate()方法中先获得了RecyclerView的实例,然后创建了LinearLayoutManager对象,并把它设置到RecyclerView的实例中去。LayoutManager用于指定RecyclerView的布局方式,这里使用是线性布局的意思,可以实现ListView相同的效果。

设置了send按钮的响应事件,如果内容不为空则创建出一个新的Msg对象,并添加到msgList中去,之后调用了适配器的方法notifyItemInserted()来通知列表有新数据插入,这样新增的消息才能在RecyclerView中显示。接着调用RecyclerView的scrollToPosition()方法,将显示的数据定位到最后一行,最后清空输入栏。

效果图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

                    <div class="art_xg">
                    <b>您可能感兴趣的文章:</b><ul><li><a href="/article/118882.htm" title="Android利用RecyclerView编写聊天界面" target="_blank">Android利用RecyclerView编写聊天界面</a></li><li><a href="/article/108060.htm" title="android recyclerview模拟聊天界面" target="_blank">android recyclerview模拟聊天界面</a></li><li><a href="/article/108052.htm" title="android Listview模拟聊天界面" target="_blank">android Listview模拟聊天界面</a></li><li><a href="/article/98112.htm" title="Android仿微信语音聊天界面设计" target="_blank">Android仿微信语音聊天界面设计</a></li><li><a href="/article/97325.htm" title="android仿微信聊天界面 语音录制功能" target="_blank">android仿微信聊天界面 语音录制功能</a></li><li><a href="/article/96615.htm" title="Android仿QQ、微信聊天界面长按提示框效果" target="_blank">Android仿QQ、微信聊天界面长按提示框效果</a></li><li><a href="/article/79129.htm" title="Android高仿微信聊天界面代码分享" target="_blank">Android高仿微信聊天界面代码分享</a></li><li><a href="/article/75266.htm" title="Android编程实现泡泡聊天界面实例详解(附源码)" target="_blank">Android编程实现泡泡聊天界面实例详解(附源码)</a></li></ul>
                    </div>
					<div class="lbd_bot clearfix">
					<a href="https://mp.weixin.qq.com/s/HFvRM6gpaACettv5ffM0tg" target="_blank"><img src="https://files.jb51.net/image/msb800.jpg" alt="java" width="820"></a>

					</div><div id="ewm"><div class="jb51ewm"><div class="fl"><img src="//files.jb51.net/skin/2018/images/jb51ewm.png"></div><div class="fr"><p>微信公众号搜索 “ <span>脚本之家</span> ” ,选择关注</p><p>程序猿的那些事、送书等活动等着你</p></div></div></div><p>原文链接:https://blog.csdn.net/thierryxc/article/details/77715519</p>
				<p class="tip">也许是最全java资料!(文档+项目+资料)<a href="https://mp.weixin.qq.com/s/HFvRM6gpaACettv5ffM0tg" target="_blank">【点击下载】</a> 和努力的人一起学习Java!</p></div><!--endmain-->
				<div class="tags clearfix">
					<i class="icon-tag"></i>
					<ul class="meta-tags">
					  <li class="tag item"><a href="http://common.jb51.net/tag/Android/1.htm" target="_blank" title="搜索关于Android的文章" rel="nofollow">Android</a></li>
  • 聊天界面
  • 					</ul>
    				</div>
    				<div class="lbd clearfix">
    					<script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-6384567588307613" data-ad-slot="3921475131" data-adsbygoogle-status="done"><ins id="aswift_0_expand" style="display:inline-table;border:none;height:90px;margin:0;padding:0;position:relative;visibility:visible;width:728px;background-color:transparent;"><ins id="aswift_0_anchor" style="display:block;border:none;height:90px;margin:0;padding:0;position:relative;visibility:visible;width:728px;background-color:transparent;"><iframe id="aswift_0" name="aswift_0" style="left:0;position:absolute;top:0;border:0;width:728px;height:90px;" sandbox="allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-top-navigation-by-user-activation" width="728" height="90" frameborder="0" src="https://googleads.g.doubleclick.net/pagead/ads?guci=2.2.0.0.2.2.0.0&amp;client=ca-pub-6384567588307613&amp;output=html&amp;h=90&amp;slotname=3921475131&amp;adk=2397501576&amp;adf=4234509282&amp;pi=t.ma~as.3921475131&amp;w=728&amp;lmt=1604479279&amp;psa=1&amp;format=728x90&amp;url=https%3A%2F%2Fwww.jb51.net%2Farticle%2F141973.htm&amp;flash=0&amp;wgl=1&amp;adsid=ChAIgL-J_QUQ1fflpvXQjOZwEi8AOCs2X87XtqbfVID6RhIG23Ro49Il-Pt-0OQTbAAJy_wrJ39Fap6Pd6WkcdMV9g&amp;dt=1604479268164&amp;bpp=12&amp;bdt=522&amp;idt=25&amp;shv=r20201029&amp;cbv=r20190131&amp;ptt=9&amp;saldr=aa&amp;abxe=1&amp;cookie=ID%3D02e9f1c318054318-224761710ec40025%3AT%3D1602604450%3ART%3D1602604450%3AS%3DALNI_MZH-rh5SJpj7hKKxTJ8KU5Btfl5Ng&amp;prev_fmts=300x250%2C300x250%2C0x0&amp;nras=1&amp;correlator=2705107884820&amp;frm=20&amp;pv=1&amp;ga_vid=1502374269.1604479268&amp;ga_sid=1604479268&amp;ga_hid=518357530&amp;ga_fc=0&amp;iag=0&amp;icsg=563947069505539&amp;dssz=53&amp;mdo=0&amp;mso=8&amp;u_tz=480&amp;u_his=1&amp;u_java=0&amp;u_h=900&amp;u_w=1440&amp;u_ah=814&amp;u_aw=1440&amp;u_cd=24&amp;u_nplug=3&amp;u_nmime=4&amp;adx=181&amp;ady=8882&amp;biw=1440&amp;bih=735&amp;scr_x=0&amp;scr_y=5945&amp;eid=44726949%2C21067467&amp;oid=3&amp;psts=AGkb-H-wmc1AEmVUj1auH84zZ5OSrloIfLIxwaF7WG8AIMBlkFApNOG27JNGghWS3n-uNQY_kh_MzKt6ZsvH9K5scQ%2CAGkb-H-tmY42s7blHiwekIdziMIHxNWoiUJNoXQmePq-hdOIbb5lEXsYZy3HHjy3I8lJZsc-mX5I3Y2bHJqUCoZlpg&amp;pvsid=1919265170697132&amp;pem=500&amp;ref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dcc-Pim1EIra3KQrRdmwUNvLpRu5wJlZhAEtmvVQvu0og5IOxDuouUOhZEonSsd4JxSllr-R-NC8rAvJ2Qz7Fia%26wd%3D%26eqid%3Deae00e71000267e8000000045fa26678&amp;rx=0&amp;eae=0&amp;fc=896&amp;brdim=0%2C23%2C0%2C23%2C1440%2C23%2C1440%2C814%2C1440%2C735&amp;vis=1&amp;rsz=%7C%7CeEbr%7C&amp;abl=CS&amp;pfx=0&amp;fu=8200&amp;bc=31&amp;jar=2020-11-04-05&amp;ifi=1&amp;uci=a!1&amp;btvi=1&amp;fsb=1&amp;xpc=e4HqwtVCaw&amp;p=https%3A//www.jb51.net&amp;dtd=11828" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" data-google-container-id="a!1" data-google-query-id="CIqzpoy_6OwCFcMgKgodYBAN-g" data-load-complete="true"></iframe></ins></ins></ins><script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
    
    				</div>
    				<div id="shoucang"></div>
    				<div class="xgcomm clearfix">
    					<h2>相关文章</h2>
    					<ul><li class="lbd clearfix"><div id="_xj782w2kopm" style=""><iframe width="820" frameborder="0" height="120" scrolling="no" src="//pos.baidu.com/s?wid=820&amp;hei=120&amp;di=u4806172&amp;ltu=https%3A%2F%2Fwww.jb51.net%2Farticle%2F141973.htm&amp;psi=2a8da32a907f68f1826196ab17215684&amp;dc=3&amp;ti=Android%E5%AE%9E%E7%8E%B0%E8%81%8A%E5%A4%A9%E7%95%8C%E9%9D%A2_Android_%E8%84%9A%E6%9C%AC%E4%B9%8B%E5%AE%B6&amp;ps=8870x135&amp;drs=1&amp;pcs=1440x735&amp;pss=1440x10342&amp;cfv=0&amp;cpl=3&amp;chi=1&amp;cce=true&amp;cec=GBK&amp;tlm=1604479268&amp;psr=1440x900&amp;par=1440x814&amp;pis=-1x-1&amp;ccd=24&amp;cja=false&amp;cmi=4&amp;col=zh-CN&amp;cdo=-1&amp;tcn=1604479268&amp;dtm=HTML_POST&amp;tpr=1604479268202&amp;ari=2&amp;ant=0&amp;exps=110257,110009,111000,112027,110011&amp;prot=2&amp;dis=0&amp;dai=1&amp;dri=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dcc-Pim1EIra3KQrRdmwUNvLpRu5wJlZhAEtmvVQvu0og5IOxDuouUOhZEonSsd4JxSllr-R-NC8rAvJ2Qz7Fia%26wd%3D%26eqid%3Deae00e71000267e8000000045fa26678"></iframe><ins class="grzqpvmeeghqp" style="display:none;padding-left:0px;"></ins></div><script type="text/javascript" src="//jscode.jbzj.com/site/g/bx_d/production/hak_cq.js"></script>
    
  • Android 图片的三级缓存机制实例分析

    Android 图片的三级缓存机制实例分析

    这篇文章主要介绍了Android 图片的三级缓存机制实例分析的相关资料,需要的朋友可以参考下
    2017-05-05
  • Flutter 实现网易云音乐字幕的代码

    Flutter 实现网易云音乐字幕的代码

    这篇文章主要介绍了Flutter 实现网易云音乐字幕的代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 解决Android平台中应用程序OOM异常的方法

    解决Android平台中应用程序OOM异常的方法

    这篇文章主要介绍了解决Android平台中应用程序OOM异常的方法,通常这一块也是程序中的重点之一,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • 详解Android应用开发中Intent的作用及使用方法

    详解Android应用开发中Intent的作用及使用方法

    这篇文章主要介绍了Android应用开发中Intent的作用与用法,包括如何激活Activity组件与Intent的投递等,需要的朋友可以参考下
    2016-03-03
  • Android WebView控件捕获用户输入的信息

    Android WebView控件捕获用户输入的信息

    这篇文章主要为大家详细介绍了Android WebView控件捕获用户输入的信息,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • Android的多媒体管理库Glide的基本使用示例

    Android的多媒体管理库Glide的基本使用示例

    这篇文章主要介绍了Android的多媒体管理库Glide的基本使用示例,Glide在图片App中的表现非常好,Google旗下的Yelp也在使用,需要的朋友可以参考下
    2016-04-04
  • flutter  TextField换行自适应的实现

    flutter TextField换行自适应的实现

    这篇文章主要介绍了flutter TextField换行自适应的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • Android程序开发之给背景图加上移动的手势

    Android程序开发之给背景图加上移动的手势

    这篇文章主要介绍了Android程序开发之给背景图加上移动的手势 的相关资料,需要的朋友可以参考下
    2016-03-03
  • Android编程图片操作类定义与用法示例【拍照,相册选图及裁剪】

    Android编程图片操作类定义与用法示例【拍照,相册选图及裁剪】

    这篇文章主要介绍了Android编程图片操作类定义与用法,涉及Android拍照,相册选图及裁剪等图片操作功能及权限控制相关操作技巧,需要的朋友可以参考下
    2018-02-02
  • Android 开机广播的使用及配置

    Android 开机广播的使用及配置

    在配置文件AndroidManifest.xml中向系统注册receiver,子节点 intent-filter表示接收
    2013-02-02
  • 				</div>
    				<a href="#comments"></a>
    				<div id="comments">
    					<h2>最新评论</h2>
    					<div class="pd5"><div id="SOHUCS" sid="art_141973"></div></div>
    				</div>
    			  </div>
    
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值