手记

Android零基础入门第67节:RecyclerView数据动态更新

列表的数据往往会跟随业务逻辑不断刷新,所呈现出来的数据需要动态更新,那么RecyclerView是如何动态更新数据的呢?


    之前在学习ListView的时候如果数据改变,需要调用notifyDataSetChanged()方法来刷新数据,而在RecyclerView中当数据改变时分别调用notifyItemChanged、notifyItemInserted和notifyItemRemoved方法来更新页面数据。

    接下来通过一个案例来学习如何动态更新数据,当单击某个item时则在其下方插入一个item,如果长压某个item时则删除对应item。

    继续使用上期的案例,首先在RecyclerViewAdapter类中新增一个插入和删除处理的公开方法,RecyclerViewAdapter类修改后的代码如下:

[代码]java代码:

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

package com.jinyu.cqkxzsxy.android.advancedviewsample.adapter;

 

import android.content.Context;

import android.support.v7.widget.RecyclerView;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.TextView;

 

import com.jinyu.cqkxzsxy.android.advancedviewsample.R;

 

import java.util.ArrayList;

 

/**

 * @创建者 鑫鱻

 * @描述 Android零基础入门到精通系列教程

 * 首发微信公众号分享达人秀(ShareExpert)

 */

public class RecyclerViewAdapter   extends RecyclerView.Adapter<recyclerviewadapter.viewholder>   {

    private ArrayList<string> mDatas = null;

    private LayoutInflater mInflater = null;

    private OnItemClickListener mOnItemClickListener   = null;

    private OnItemLongClickListener   mOnItemLongClickListener = null;

 

    public RecyclerViewAdapter2(Context context,   ArrayList<string> datas) {

        this.mDatas   = datas;

        this.mInflater   = LayoutInflater.from(context);

    }

 

    // 创建新View,被LayoutManager所调用

    @Override

    public ViewHolder onCreateViewHolder(ViewGroup   parent, int viewType)   {

        View   view = mInflater.inflate(R.layout.recyclerview_item, parent, false);

        ViewHolder   vewHolder = new ViewHolder(view);

        return vewHolder;

    }

 

    // 将数据与界面进行绑定的操作

    @Override

    public void onBindViewHolder(final ViewHolder holder, final int position)   {

        String   name = mDatas.get(position);

        holder.titleTv.setText("Title   " +   name);

        holder.contenTv.setText("content   " +   name);

 

        //   点击事件注册及分发

        if(null != mOnItemClickListener) {

            holder.titleTv.setOnClickListener(new View.OnClickListener() {

                @Override

                public void onClick(View v) {

                    mOnItemClickListener.onClick(holder.titleTv,   position);

                }

            });

            holder.contenTv.setOnClickListener(new View.OnClickListener() {

                @Override

                public void onClick(View v) {

                    mOnItemClickListener.onClick(holder.contenTv,   position);

                }

            });

        }

        //   长按事件注册及分发

        if(null != mOnItemLongClickListener) {

            holder.titleTv.setOnLongClickListener(new View.OnLongClickListener() {

                @Override

                public boolean onLongClick(View v) {

                    return mOnItemLongClickListener.onLongClick(holder.titleTv,   position);

                }

            });

            holder.contenTv.setOnLongClickListener(new View.OnLongClickListener() {

                @Override

                public boolean onLongClick(View v) {

                    return mOnItemLongClickListener.onLongClick(holder.contenTv,   position);

                }

            });

        }

    }

 

    // 获取数据的数量

    @Override

    public int getItemCount() {

        return mDatas == null ? 0 : mDatas.size();

    }

 

    // 设置点击事件

    public void setOnItemClickListener(OnItemClickListener l) {

        this.mOnItemClickListener   = l;

    }

 

    // 设置长按事件

    public void setOnItemLongClickListener(OnItemLongClickListener l) {

        this.mOnItemLongClickListener   = l;

    }

 

    // 在对应位置增加一个item

    public void addData(int position) {

        mDatas.add(position,   "Insert " + position);

        notifyItemInserted(position);

    }

 

    // 删除对应item

    public void removeData(int position) {

        mDatas.remove(position);

        notifyItemRemoved(position);

    }

 

    // 点击事件接口

    public interface OnItemClickListener {

        void onClick(View parent, int position);

    }

 

    // 长按事件接口

    public interface OnItemLongClickListener {

        boolean onLongClick(View parent, int position);

    }

 

    // 自定义的ViewHolder,持有每个Item的的所有界面组件

    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView titleTv = null;

        public TextView contenTv = null;

 

        public ViewHolder(View itemView) {

            super(itemView);

 

            titleTv   = (TextView) itemView.findViewById(R.id.title_tv);

            contenTv   = (TextView) itemView.findViewById(R.id.content_tv);

        }

    }

}

</string></string></recyclerviewadapter.viewholder>

    然后在Activity中事件回调的时候进行插入和删除处理,RecyclerViewActivity修改后的代码如下:

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

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

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

package com.jinyu.cqkxzsxy.android.advancedviewsample;

 

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.support.v7.widget.DefaultItemAnimator;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.view.View;

 

import com.jinyu.cqkxzsxy.android.advancedviewsample.adapter.RecyclerViewAdapter;

import com.jinyu.cqkxzsxy.android.advancedviewsample.view.RecyclerViewItemDivider;

 

import java.util.ArrayList;

 

/**

 * @创建者 鑫鱻

 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert

 */

public class RecyclerViewActivity   extends AppCompatActivity   implements

        RecyclerViewAdapter.OnItemClickListener,

        RecyclerViewAdapter.OnItemLongClickListener   {

    private RecyclerView mRecyclerView = null;

    private RecyclerViewAdapter mAdapter = null;

    private ArrayList<string> mDatas = null;

     

     

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.recyclerview_layout);

 

        //   获取组件

        mRecyclerView   = (RecyclerView) findViewById(R.id.recyclerview);

 

        //   设置管理器

        LinearLayoutManager   layoutManager = new LinearLayoutManager(this);

        mRecyclerView.setLayoutManager(layoutManager);

        //   自定义分割线

        RecyclerView.ItemDecoration   itemDecoration = new RecyclerViewItemDivider(this,

                R.drawable.recyclerview_item_divider);

        mRecyclerView.addItemDecoration(itemDecoration);

        //   如果可以确定每个item的高度是固定的,设置这个选项可以提高性能

        mRecyclerView.setHasFixedSize(true);

 

        //   初始化列表数据

        initDatas();

 

        //   设置适配器

        mAdapter   = new RecyclerViewAdapter(this,   mDatas);

        mAdapter.setOnItemClickListener(this);

        mAdapter.setOnItemLongClickListener(this);

        mRecyclerView.setAdapter(mAdapter);

 

        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    }

 

    private void initDatas() {

        mDatas   = new ArrayList<>();

 

        for (int i = 0; i < 50; i++) {

            mDatas.add(i,   i + 1 + "");

        }

    }

 

    @Override

    public void onClick(View parent, int position) {

        mAdapter.addData(position   + 1);

        //Toast.makeText(this,   "点击了第" + (position + 1) + "项",   Toast.LENGTH_SHORT).show();

    }

 

    @Override

    public boolean onLongClick(View parent, int position) {

        mAdapter.removeData(position);

        //Toast.makeText(this,   "长压了第" + (position + 1) + "项",   Toast.LENGTH_SHORT).show();

        return true;

    }

}

</string>

    其余布局文件代码不变,重新运行程序,然后可以测试点击事件和长压事件,可以看到数据能够插入和删除,

    值得注意的是RecyclerView的添加删除都是有默认的动画效果的,如果没有效果可以添加如下代码:       mRecyclerView.setItemAnimator(newDefaultItemAnimator());

    不知道你是否发现,当我们插入数据或者删除item的时候,item的位置并没有发生改变或产生位置错乱,需要重新调用notifyDataSetChanged方法,虽然问题得到了解决,但是又会产生新的问题,就是RecyclerView的动画效果没了,那应该如何操作呢?

    其实RecyclerView还提供了几个局部刷新的方法,只需要在删除或插入数据的同时,再刷新改变位置item下方的所有Item的位置即可。修正后的局部代码如下:

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

// 在对应位置增加一个item

public void addData(int position) {

    mDatas.add(position,   "Insert " + position);

    notifyItemInserted(position);

 

    if(position !=   getItemCount()) {

        notifyItemRangeChanged(position,   getItemCount());

    }

}

 

// 删除对应item

public void removeData(int position) {

    mDatas.remove(position);

    notifyItemRemoved(position);

 

    if(position !=   getItemCount()) {

        notifyItemRangeChanged(position,   getItemCount());

    }

}

    再次运行程序,可以发现这一次的操作就已经OK了

    如果对这一块还有疑问,欢迎加入微信讨论群一起探讨。

    今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

原文链接:http://www.apkbus.com/blog-205190-72777.html

0人推荐
随时随地看视频
慕课网APP