美文网首页AndroidAndroid开发程序员
03UI开发-RecyclerView及简单聊天界面

03UI开发-RecyclerView及简单聊天界面

作者: 何惧l | 来源:发表于2018-03-18 12:29 被阅读22次

    基本用法

    1. 想要使用这个控件,首先在项目的build.gradle中添加相应的依赖库才行
      打开app/build.gradle文件,在dependencies闭包中添加
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:26.1.0'
        // 添加的是这一句
        compile 'com.android.support:recyclerview-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.0.2'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.1'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    }
    
    
    1. 添加完成后点击一下Sync Now来进行同步,然后修改activity_main.xml中的代码
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view_1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
    
    

    添加一个控件,宽度和高度都是占满整部布局空间的

    1. 接下来定义一个自定义布局fruit_item.xml,这个时候注意layout_width="wrap_content"的设置,让它自适应大就可以了
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    
        <ImageView
            android:id="@+id/img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="20dp"
            />
    
    </LinearLayout>
    
    

    4.定义一个实体类,作为RecyclerView适配器的适配类型,建立Fruit

    
    public class Fruit {
        private String name;
        private int imageId;
    
        public Fruit(String name,int imageId){
            this.imageId = imageId;
            this.name = name;
        }
        public String getName() {
            return name;
        }
    
        public int getImageId() {
            return imageId;
        }
    }
    
    
    1. 为RecyclerView准备一个适配器,新建FruitAdapter类,让这个适配器继承RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,其中ViewHolder是我们在FruitAdapter中定义的一个内部类
    
    public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    
        private List<Fruit> mFruitList;
    
        static class ViewHolder extends RecyclerView.ViewHolder{
            ImageView fruitImage;
            TextView fruitName;
    
            public ViewHolder(View view){
                super(view);
                fruitImage=(ImageView)view.findViewById(R.id.img);
                fruitName = (TextView)view.findViewById(R.id.text);
            }
        }
    
        public FruitAdapter(List<Fruit> fruitList){
            mFruitList = fruitList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = mFruitList.get(position);
            holder.fruitImage.setImageResource(fruit.getImageId());
            holder.fruitName.setText(fruit.getName());
        }
    
        @Override
        public int getItemCount() {
            return mFruitList.size();
        }
    
    
    }
    
    
    
    • 首先定义了一个内部类,ViewHolder要继承自RecyclerView.ViewHolder,然后在这个里面的构造函数中传入了一个View参数,这个参数通常就是RecyclerView子项的最外层布局,那么就可以通过这个findViewById()的方法获取到布局中的ImageVIew和TextView的实例了
    • FruitAdapter中也有一个构造函数,这个函数用于将把要展示的数据源传递进来,并赋值给一个全局变量mFruitList,后面操作的就是这个数据源了
    • 由于FruitAdapter继承自RecyclerView.Adapter,那么就必须重写 onCreateViewHolder(),onBindViewHolder(),getItemCount()这三个方法,
    • onCreateViewHolder()方法用于创建一个ViewHolder实例,并把加载出来的布局传入到构造函数中,最后将ViewHolder的实例返回
    • onBindViewHolder()方法用与对RecyclerView子项的数据进行赋值,会在每个子项滚动到屏幕内的时候执行,通过position参数可以获得当前项的Fruit实例,然后再将数据设置到ViewHolder的ImageView和TextVIew中
    • getItemCount()用于告诉RecyclerVIew一共有多少个子项,直接返回数据源的长度
    1. 接下来就可以使用RecyclerView,修改MainActivity中的代码
    
    public class MainActivity extends AppCompatActivity {
    
        private List<Fruit> fruitList = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // 用于初始化水果
            initFruits();
            RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view_1);
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            recyclerView.setLayoutManager(layoutManager);
            FruitAdapter adapter = new FruitAdapter(fruitList);
            recyclerView.setAdapter(adapter);
        }
    
    
        private void initFruits(){
            for (int i= 0;i<2;i++){
                Fruit apple = new Fruit("Apple",R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit("Banana",R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit("orange",R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit("watermelon",R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit("pear",R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit("grape",R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit("pineapple",R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit("strawberry",R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit("cherry",R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit("mango",R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    
    }
    
    
    • 使用了同样的initFruits()方法,用于初始化水果的数据,接着onCreate()方法获取到RecyclerView的实例,
    • 创建一个LayoutManager用于指定RecycleView的布局方式,这里使用的是LinearLayoutManager是线性布局的意思,可以实现和ListView类似的效果,
    • 接下来创建一个FruitAdapter的实例,将水果的数据传入到FruitAdapter的构造函数中
    • 最后调用RecyclerView的setAdapter()方法来完成适配器的设置,这样RecyclerVIew和数据之间的关联就建立完成了


      2018-03-11_16-06-47.png

    实现横向滚动和瀑布流布局

    1. 首先要对fruit_item布局进行修改,实现横向滚动,得把这里面的元素改成垂直排列的方式
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="100dp"
        android:layout_height="wrap_content">
    
        <ImageView
            android:id="@+id/img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            />
    
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            />
    
    </LinearLayout>
    
    
    • android:orientation="vertical"该成了垂直方向排列,而且宽度色设置为100dp,这样不会因为每种水果名字的长度不一而导致RecycleView的各个子项长短不一
    • android:layout_gravity="center_horizontal" 都设置为水平居中
    1. 修改MainActivity中的代码
    package com.example.md.recyclerview;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
    
        private List<Fruit> fruitList = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // 用于初始化水果
            initFruits();
            RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view_1);
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            // 多添加这一句话
            layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
            recyclerView.setLayoutManager(layoutManager);
            FruitAdapter adapter = new FruitAdapter(fruitList);
            recyclerView.setAdapter(adapter);
        }
            
        ..............
    
    }
    
    
    
    • 相比之下,只多了一行代码,调用了layoutManager的setOrientation()方法来设置布局的排列方法,默认是纵向的,传入LinearLayoutManager.HORIZONTAL表示让布局横向排列
      Snipaste_2018-03-11_16-20-07.png
    1. 除了LinearLayoutManager之外,RecyclerView还提供了GridLayoutManagerStaggeredGridLayoutManager这样中内置的布局排列方式,GridLayoutManager是用于网络布局,StaggeredGridLayoutManager用于瀑布布局
      修改fruit_item.xml中的代码
    <?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:layout_margin="5dp">
    
        <ImageView
            android:id="@+id/img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            />
    
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="left"
            android:layout_marginTop="20dp"
            />
    
    </LinearLayout>
    
    

    只有几处调整,把宽度有100dp改成match_parent,因为瀑布的宽度是根据布局的列数自动匹配的,不是一个固定的值,还用margin属性,让子项之间留点间距,文字的对齐方式改成了左对齐

    1. 修改MainActivity中的代码
    
    public class MainActivity extends AppCompatActivity {
    
    
        private List<Fruit> fruitList = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // 用于初始化水果
            initFruits();
            RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view_1);
    //        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            // 多添加这一句话
    //        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    
    //      主要就是这一行代码,瀑布
            StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(
                    3, StaggeredGridLayoutManager.VERTICAL
            );
    
            // 网络
            //GridLayoutManager layoutManager = new GridLayoutManager(this,4);
    
            recyclerView.setLayoutManager(layoutManager);
            FruitAdapter adapter = new FruitAdapter(fruitList);
            recyclerView.setAdapter(adapter);
        }
    
        private void initFruits(){
            for (int i= 0;i<2;i++){
                Fruit apple = new Fruit(getRandomLengthName("Apple"),R.drawable.apple_pic);
                fruitList.add(apple);
                Fruit banana = new Fruit(getRandomLengthName("Banana"),R.drawable.banana_pic);
                fruitList.add(banana);
                Fruit orange = new Fruit(getRandomLengthName("orange"),R.drawable.orange_pic);
                fruitList.add(orange);
                Fruit watermelon = new Fruit(getRandomLengthName("watermelon"),R.drawable.watermelon_pic);
                fruitList.add(watermelon);
                Fruit pear = new Fruit(getRandomLengthName("pear"),R.drawable.pear_pic);
                fruitList.add(pear);
                Fruit grape = new Fruit(getRandomLengthName("grape"),R.drawable.grape_pic);
                fruitList.add(grape);
                Fruit pineapple = new Fruit(getRandomLengthName("pineapple"),R.drawable.pineapple_pic);
                fruitList.add(pineapple);
                Fruit strawberry = new Fruit(getRandomLengthName("strawberry"),R.drawable.strawberry_pic);
                fruitList.add(strawberry);
                Fruit cherry = new Fruit(getRandomLengthName("cherry"),R.drawable.cherry_pic);
                fruitList.add(cherry);
                Fruit mango = new Fruit(getRandomLengthName("mango"),R.drawable.mango_pic);
                fruitList.add(mango);
            }
        }
    
    // 不想实现也可以不用写
        private String getRandomLengthName(String name){
            Random random = new Random();
            int length = random.nextInt(20) + 1;
            StringBuilder builder = new StringBuilder();
            for(int i = 0;i<length;i++){
                builder.append(name);
            }
            return builder.toString();
        }
    
    }
    
    
    • 首先在onCreate()方法中,创建了StaggeredGridLayoutManager的实例,它的构造函数接收了两个参数,第一个用于指定布局的列数,传入3表示会把布局分为3列,第二个参数用于指定布局的排列方向, StaggeredGridLayoutManager.VERTICAL表示是纵向排列,最后再把创建好的实例设置到RecyclerView中
    • 这里使用了一个小技巧,在这个getRandomLengthName()方法上,这个方法用了Random对象来创造一个1到20之间的随机数,然后将参数中传入的字符重复随即便,在initFruits()方法中,每个水果的名字都调用这个方法来生成,这样就保证水果的名字的长短差距大,子项的高度就不一样了


      2018-03-11_16-45-14.png
    • 若不写这个方法也是可以的,在传入的时候直接写入水果的名字也可以


      2018-03-17_11-13-27.png
    • 当然了,还可以写网络布局,只需要创建一个GridLayoutManager实例就可以了,它的构造函数接收两个参数,第一个是上下文对象,第二个参数是一行显示几列数据


      2018-03-17_11-19-17.png

    RecyclerView的点击事件

    这个的注册监听器方法是需要我们自己给子项具体的View去注册点击事件的

    1. 修改FruitAdapter中的代码
    
    public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {
    
        private List<Fruit> mFruitList;
    
        static class ViewHolder extends RecyclerView.ViewHolder{
            // 这里定义一个View变量
            View fruitView;
            ImageView fruitImage;
            TextView fruitName;
    
            public ViewHolder(View view){
                super(view);
                // 保存最外层的布局实例
                fruitView  = view;
                fruitImage = view.findViewById(R.id.img);
                fruitName = view.findViewById(R.id.text);
            }
        }
    
        public FruitAdapter(List<Fruit> fruitList){
            mFruitList = fruitList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
           // 
            final ViewHolder holder = new ViewHolder(view);
    
            //分别为最外层的布局和Image注册点击事件
            holder.fruitView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 获取到position,然后拿到Fruit实例
                    int position = holder.getAdapterPosition();
                    Fruit fruit = mFruitList.get(position);
                    Toast.makeText(v.getContext(),"you click view"+fruit.getName(),Toast.LENGTH_SHORT).show();
                }
            });
            holder.fruitImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = holder.getAdapterPosition();
                    Fruit fruit = mFruitList.get(position);
                    Toast.makeText(v.getContext(),"you clcik image"+fruit.getImageId(),Toast.LENGTH_SHORT).show();
                }
            });
            return holder;
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Fruit fruit = mFruitList.get(position);
            holder.fruitImage.setImageResource(fruit.getImageId());
            holder.fruitName.setText(fruit.getName());
        }
    
        @Override
        public int getItemCount() {
            return mFruitList.size();
        }
    }
    
    
    • 先修改ViewHolder,在ViewHolder中添加fruitView变量来保存子项最外层布局的实例,然后在onCreateViewHolder()方法中注册点击事件
    • 分别为最外层的布局和Image都注册了事件,先获取到用户点击的position,然后通过position拿到响应的Fruit实例,然后通过Toast显示


      点击图片.png
      点击文字.png

    了解Nine-Patch

    1. 现在项目中有一个气泡状的图片,将这个图片设置为背景图片
    <?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:background="@drawable/beijing"
        >
    </LinearLayout>
    
    
    2018-03-17_13-53-54.png

    这个时候可以看到图片被均匀的拉伸了,效果极差,这个时候就可以使用Nine-Patch来处理了

    1. 右击要添加的图片,点击Create 9-Patch file


      2018-03-17_13-55-30.png
    2. 就进入到这个页面


      2018-03-17_13-57-25.png

      我们可以在四周绘制一个个小黑点,按住Shift键拖动就可以进行擦除,使用这个新的图片替换原来的,再运行程序就可以看到


      2018-03-17_14-00-18.png
    3. 这样,当图片需要拉伸的时候,就指定拉伸的区域,在外观上就好看了

    编写聊天界面

    1. 首先使用到的是RecyclerView,所以首先进行在app/build.gradle中添加依赖库
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:26.1.0'
        // 添加这行代码
        compile 'com.android.support:recyclerview-v7:26.1.0'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.1'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    }
    
    
    1. 编写主页面,修改activity_main.xml
    <?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="#d8e0e8"
        >
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyc_1"
            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/edit_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="Type something here"
                android:textSize="25sp"
                android:maxLines="2"/>
    
            <Button
                android:id="@+id/send"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="25sp"
                android:text="Send"/>
    
        </LinearLayout>
    
    
    
    </LinearLayout>
    
    
    • 在主页面中放一个RecycleView用于显示聊天的消息内容,又放置了一个输入框,和一个按钮
    1. 定义消息的实体类,新建一个Msg
    public class Msg {
        // 接收到一条消息
        public static final int TYPE_RECEVED = 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;
        }
    }
    
    
    • Msg中只有两个字段,content表示消息的内容,type表示消息的类型,其中消息的类型有两个值可选,一个是TYPE_RECEVED表示接收到的数据,TYPE_SENT表示发送的数据
    1. 接下来编写RecyclerView的子项布局,新建msg_item.xml
    <?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">
    
        <LinearLayout
            android:id="@+id/left_layout"
            android:layout_gravity="left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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"
                android:textSize="25sp"/>
    
        </LinearLayout>
    
    
        <LinearLayout
            android:id="@+id/right_layout"
            android:layout_gravity="right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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"
                android:textColor="#000000"
                android:textSize="25sp"/>
    
        </LinearLayout>
    
    
    </LinearLayout>
    
    
    • 接收到的消息左对齐,发送的消息右对齐,这个时候问题来了,怎么让收到的消息和发出的消息在一个布局中呢在这一个布局中,必定有一个控件是空白的在学基本控件的时候学到了可见属性,稍后在代码中可以根据这个消息的类型来决定隐藏和显示那种消息
    1. 编写自定义的MagAdapter适配器,和在RecyclerView写的适配器代码基本一样
    
    public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> {
    
        private List<Msg> mMsgList;
    
        static class ViewHolder extends RecyclerView.ViewHolder{
    
            LinearLayout leftLayout;
            LinearLayout rightLayout;
            TextView lefMsg;
            TextView rightMsg;
    
            public ViewHolder(View itemView) {
                super(itemView);
                leftLayout = (LinearLayout)itemView.findViewById(R.id.left_layout);
                rightLayout = (LinearLayout)itemView.findViewById(R.id.right_layout);
                lefMsg = (TextView)itemView.findViewById(R.id.left_msg);
                rightMsg = (TextView)itemView.findViewById(R.id.right_msg);
            }
    
        }
    
        public MsgAdapter(List<Msg> msgList){
            mMsgList = msgList;
        }
    
        @Override
        public MsgAdapter.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(MsgAdapter.ViewHolder holder, int position) {
            Msg msg = mMsgList.get(position);
            if (msg.getType() == Msg.TYPE_RECEVED){
                // 如果是接收到的消息,则显示左边的消息布局,将右边的隐藏
                holder.leftLayout.setVisibility(View.VISIBLE);
                holder.rightLayout.setVisibility(View.GONE);
                holder.lefMsg.setText(msg.getContent());
            }else if (msg.getType() == Msg.TYPE_SENT){
                // 如果是发送消息,那么显示右边的布局,把左边的布局隐藏
                holder.rightLayout.setVisibility(View.VISIBLE);
                holder.leftLayout.setVisibility(View.GONE);
                holder.rightMsg.setText(msg.getContent());
            }
        }
    
        @Override
        public int getItemCount() {
            return mMsgList.size();
        }
    }
    
    
    
    1. 修改MainActivity中的代码
    
    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.main_layout);
            // 初始化消息数据
            initMsag();
            inputText = (EditText)findViewById(R.id.edit_1);
            send = (Button)findViewById(R.id.send);
            // 获取到这个滚动控件
            msgRecyclerView = (RecyclerView)findViewById(R.id.recyc_1);
            // 指定这个控件的布局方式
            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 view) {
                    // 获取到消息框中的内容
                    String content = inputText.getText().toString();
                    if (!"".equals(content)){
                        Msg msg = new Msg(content,Msg.TYPE_SENT);
                        msgList.add(msg);
                        // 当有新的消息的时候刷新ListView中的显示
                        adapter.notifyItemInserted(msgList.size()-1);
                        // 将ListView定位到最后一行
                        msgRecyclerView.scrollToPosition(msgList.size()-1);
                        // 清空输入框中的内容
                        inputText.setText("");
                    }
                }
            });
    
    
        }
    
        public void initMsag(){
            Msg msg = new Msg("hello pony",Msg.TYPE_RECEVED);
            msgList.add(msg);
            Msg msg1 = new Msg("hello Tom",Msg.TYPE_SENT);
            msgList.add(msg1);
            Msg msg2 = new Msg("我们去哪里呀?",Msg.TYPE_RECEVED);
            msgList.add(msg2);
        }
    }
    
    
    
    • 在initMsag()中初始化了几条数据,用于在RecyclerView中显示
    • 在点击按钮的时候,如果内容不为空,就创建了一个Msg对象,并且添加到了msgList中去
    • 然后调用适配器的notifyItemInserted()方法,用于通知列表中有新的数据插入,这样新增的一条消息才能够在RecyclerVIew中显示,
    • 接着调用RecyclerView的scrollToPosition()方法,将数据定位到最后一行,
    • 最后调用setTExt()方法将输入的内容清空


      2018-03-17_16-13-25.png

    参考数据:第一行代码
    若有错误请指出

    相关文章

      网友评论

        本文标题:03UI开发-RecyclerView及简单聊天界面

        本文链接:https://www.haomeiwen.com/subject/eqjeqftx.html