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();    }}

这里写图片描述

0 0
原创粉丝点击