原帖: 跳转
Android实现聊天界面
更新时间:2018年06月13日 14:14:05 作者:Thierryxc
这篇文章主要为大家详细介绍了Android实现聊天界面的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了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"
?>
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"
?>
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&client=ca-pub-6384567588307613&output=html&h=90&slotname=3921475131&adk=2397501576&adf=4234509282&pi=t.ma~as.3921475131&w=728&lmt=1604479279&psa=1&format=728x90&url=https%3A%2F%2Fwww.jb51.net%2Farticle%2F141973.htm&flash=0&wgl=1&adsid=ChAIgL-J_QUQ1fflpvXQjOZwEi8AOCs2X87XtqbfVID6RhIG23Ro49Il-Pt-0OQTbAAJy_wrJ39Fap6Pd6WkcdMV9g&dt=1604479268164&bpp=12&bdt=522&idt=25&shv=r20201029&cbv=r20190131&ptt=9&saldr=aa&abxe=1&cookie=ID%3D02e9f1c318054318-224761710ec40025%3AT%3D1602604450%3ART%3D1602604450%3AS%3DALNI_MZH-rh5SJpj7hKKxTJ8KU5Btfl5Ng&prev_fmts=300x250%2C300x250%2C0x0&nras=1&correlator=2705107884820&frm=20&pv=1&ga_vid=1502374269.1604479268&ga_sid=1604479268&ga_hid=518357530&ga_fc=0&iag=0&icsg=563947069505539&dssz=53&mdo=0&mso=8&u_tz=480&u_his=1&u_java=0&u_h=900&u_w=1440&u_ah=814&u_aw=1440&u_cd=24&u_nplug=3&u_nmime=4&adx=181&ady=8882&biw=1440&bih=735&scr_x=0&scr_y=5945&eid=44726949%2C21067467&oid=3&psts=AGkb-H-wmc1AEmVUj1auH84zZ5OSrloIfLIxwaF7WG8AIMBlkFApNOG27JNGghWS3n-uNQY_kh_MzKt6ZsvH9K5scQ%2CAGkb-H-tmY42s7blHiwekIdziMIHxNWoiUJNoXQmePq-hdOIbb5lEXsYZy3HHjy3I8lJZsc-mX5I3Y2bHJqUCoZlpg&pvsid=1919265170697132&pem=500&ref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dcc-Pim1EIra3KQrRdmwUNvLpRu5wJlZhAEtmvVQvu0og5IOxDuouUOhZEonSsd4JxSllr-R-NC8rAvJ2Qz7Fia%26wd%3D%26eqid%3Deae00e71000267e8000000045fa26678&rx=0&eae=0&fc=896&brdim=0%2C23%2C0%2C23%2C1440%2C23%2C1440%2C814%2C1440%2C735&vis=1&rsz=%7C%7CeEbr%7C&abl=CS&pfx=0&fu=8200&bc=31&jar=2020-11-04-05&ifi=1&uci=a!1&btvi=1&fsb=1&xpc=e4HqwtVCaw&p=https%3A//www.jb51.net&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&hei=120&di=u4806172&ltu=https%3A%2F%2Fwww.jb51.net%2Farticle%2F141973.htm&psi=2a8da32a907f68f1826196ab17215684&dc=3&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&ps=8870x135&drs=1&pcs=1440x735&pss=1440x10342&cfv=0&cpl=3&chi=1&cce=true&cec=GBK&tlm=1604479268&psr=1440x900&par=1440x814&pis=-1x-1&ccd=24&cja=false&cmi=4&col=zh-CN&cdo=-1&tcn=1604479268&dtm=HTML_POST&tpr=1604479268202&ari=2&ant=0&exps=110257,110009,111000,112027,110011&prot=2&dis=0&dai=1&dri=0&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拍照,相册选图及裁剪等图片操作功能及权限控制相关操作技巧,需要的朋友可以参考下2018-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>