Android进阶——RecycleView的使用之自定义聊天界面(三)
来源:互联网 发布:安卓数据恢复软件 编辑:程序博客网 时间:2024/06/10 09:13
引言
最近在项目中有一项是智能语音识别和唤醒的功能,正好需要用到类似聊天的界面,一开始有点懵,后面再去看了一下官方说明文档,发现了一个无论是在AdapterView的Apdapter还是RecycleView的Adapter中常常被很多教程忽略的方法(先卖个关子),也间接导致了不了解的人走了很多弯路,还好我比较喜欢先看api,因为有些时候再第一次学的时忽略掉了一些api,没有走多少弯路,借助于这个方法瞬间思路豁然开朗。
一、RecycleView大致的工作流程
RecycleView得以正常完成基本的工作离不开RecycleView.Adapter和RecyclerView.LayoutManager,RecycleView相当于只是一个容器,如果没有Adapter那么它就没有任何价值。Acitivty通过布局加载RecycleView,然后触发对应的生命周期方法,去完成AdapterView的初始化工作:首先肯定是调用Adapter的构造方法——>然后调用getItemCount()方法——>getItemViewType()——>再调用onCreateViewHolder()来创建ViewHolder——>自然进入到ViewHolder的构造方法——>最后再到onBindViewHolder()把数据和View填充到ViewHolder里
创建第二个item时
二、自定义聊天界面的核心思路
我想通过上面的Log信息,已经不难看出来,RecycleView本身已经提供了这样的一个动态创建ItemView的机制,我们只需要在每次创建的时候,根据一个标记值去加载不同的布局创建不同的ViewHolder即可,而getItemViewType()正好提供了这个值,还传递到了onCreateViewHolder里。
- getItemViewType的原型
/***如果不重写,默认返回0,代表该适配器所有Item都是一种布局。可以通过重写来实现在一个适配器里适配多种布局*/int getItemViewType (int position)
- onCreateViewHolder(ViewGroup parent, int viewType)
三、实现自定义聊天界面
1、在Gradle脚本里引入RecycleView
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.jakewharton:butterknife:7.0.1' compile 'com.android.support:appcompat-v7:24.2.0' compile 'com.android.support:recyclerview-v7:24.0.0'}
2、实现接收/发送信息时的item布局
这里有个小技巧:LinearLayout水平方向默认是从左到右布局的,但是可以通过设置gravity属性来改变布局的起点
item_response.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:padding="10dp" android:gravity="left" android:orientation="horizontal"> <ImageView android:id="@+id/iv_response" android:layout_width="32dp" android:layout_height="32dp" android:src="@mipmap/ic_respnonse" /> <TextView android:id="@+id/tv_resopense" android:padding="2dp" android:layout_width="120dp" android:layout_height="30dp" android:gravity="center" android:textSize="20sp" android:background="@mipmap/delay_time_wait" android:text="Hi~~" /></LinearLayout>
item_send.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:padding="10dp" android:orientation="horizontal" android:gravity="right"> <TextView android:id="@+id/tv_send" android:layout_width="200dp" android:layout_height="30dp" android:textAlignment="center" android:padding="2dp" android:gravity="center" android:textSize="20sp" android:text="Hello!!~" android:background="@mipmap/delay_time_over" /> <ImageView android:id="@+id/iv_send" android:layout_width="32dp" android:layout_height="32dp" android:src="@mipmap/ic_send" /></LinearLayout>
3、封装Bean实现Adapter
public class ChatBean { String content; Drawable drawable;//可以通过这个来修改头像 int type;//用于标识告知Adpater应该创建的是哪一类的ItenView public ChatBean(String content, Drawable drawable, int type) { this.content = content; this.drawable = drawable; this.type = type; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Drawable getDrawable() { return drawable; } public void setDrawable(Drawable drawable) { this.drawable = drawable; } public int getType() { return type; } public void setType(int type) { this.type = type; }}
/*为了方便这个类是写在MainActivity里作为内部类的*/class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> { private List<ChatBean> chatBeanList; private LayoutInflater inflater; public ChatAdapter(Context context,List<ChatBean> chatBeans){ this.chatBeanList=chatBeans; this.inflater=LayoutInflater.from(context); } @Override public ChatViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ChatViewHolder holder; //根据ViewType值创建不同的ViewHolder if(viewType==0) { holder = new ChatViewHolder(LayoutInflater.from( MainActivity.this).inflate(R.layout.item_response, parent, false)); } else{ holder = new ChatViewHolder(LayoutInflater.from( MainActivity.this).inflate(R.layout.item_send, parent, false)); } return holder; } @Override public int getItemViewType(int position) { return chatBeanList.get(position).getType();//**返回集合Bean里的值作为标记值将传递到onCreateViewHolder里 } @Override public void onBindViewHolder(ChatViewHolder holder, int position) { //这里只是简单的实现了设置聊天内容并未对头像处理 if(chatBeanList.get(position).getType()==0) { holder.tvResponse.setText(chatBeanList.get(position).getContent()); }else { holder.tvSend.setText(chatBeanList.get(position).getContent()); } } @Override public int getItemCount() { return chatBeanList.size(); } //简单实现的ViewHolder,开发中最好再做些优化可以参考上一篇 class ChatViewHolder extends RecyclerView.ViewHolder { TextView tvResponse; TextView tvSend; public ChatViewHolder(View view) { super(view); tvResponse = (TextView) view.findViewById(R.id.tv_resopense); tvSend=(TextView)view.findViewById(R.id.tv_send); } } }
4、实现Activity
import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * @auther: Crazy.Mo * Date: 2016/10/11 * Time:01:01 * Des: */public class MainActivity extends Activity { private RecyclerView recyclerView; private List<ChatBean> chatBeanList; private ChatAdapter chatAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void getViews() { recyclerView = (RecyclerView) findViewById(R.id.listv_chatting); } private void initAdapter(){ chatBeanList=new ArrayList<>(); chatBeanList.add(new ChatBean("Hello~~~",null,0)); chatBeanList.add(new ChatBean("Nice to meet U",null,1)); chatBeanList.add(new ChatBean("Me tooo",null,0)); chatBeanList.add(new ChatBean("LOL~~~",null,1)); chatBeanList.add(new ChatBean("LOL~~~",null,1)); chatBeanList.add(new ChatBean("LOL~~~",null,0)); } private void initRecyclerView(){ //设置布局管理器 recyclerView.setLayoutManager(new LinearLayoutManager(this)); //设置adapter recyclerView.setAdapter(new ChatAdapter(this, chatBeanList)); //设置默认动画 recyclerView.setItemAnimator(new DefaultItemAnimator()); } private void init() { getViews(); initAdapter(); initRecyclerView(); }}
- Android进阶——RecycleView的使用之自定义聊天界面(三)
- Android进阶——RecycleView的使用之自定义单选列表(二)
- Android进阶——万能的RecycleView详解(一)
- recycleview多item布局的实现(简单聊天界面)
- Android进阶之自定义view(三)
- 【Android进阶之自定义View(三)】
- Android进阶之使用自定义的字体库
- Android 开发之RecycleView的简单使用
- Android之高仿微信聊天的界面
- Android之高仿微信聊天的界面
- Android进阶之自定义控件三
- 通过代码自定义cell——实现qq聊天界面(Version 2 实现聊天内容的背景)
- 关于如何通过recycleview实现聊天界面的效果
- <Android 进阶(三)> 自定义View之支持Gravity的ViewGroup
- Android RecycleView的使用
- android RecycleView的使用
- android RecycleView的使用
- Android RecycleView---- RecycleView的简单使用
- Android:视图绘制(五) ------Paint进阶之PathEffect
- Eclipse 配置黑色主题
- 172. Factorial Trailing Zeroes
- java发送http的get、post请求
- 全局引用和本地引用
- Android进阶——RecycleView的使用之自定义聊天界面(三)
- Java面试题大全
- Android 5.0之后隐式声明Intent 启动Service引发的问题
- 在web项目中使用 ThreadLocal 要谨慎,使用不当容易造成内存溢出
- php几种根据生日计算年龄的方法
- Qt5的widget项目文件解析
- UE4中蓝图转换成C++代码
- android 主题兼容问题
- 视频课程-前端开发