Android 5.0新特性RecycleView的基本使用

一、RecycleView简介

RecycleView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式。该控件用于在有限的窗口中展示大量数据集,它被作为ListView和GridView控件的继承者。

那么有了ListViewGridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManagerItemDecoration , ItemAnimator实现令人瞠目的效果

· 你想要控制其显示的方式,请通过布局管理器LayoutManager

· 你想要控制Item间的间隔(可绘制),请通过ItemDecoration

· 你想要控制Item增删的动画,请通过ItemAnimator

· 你想要控制其显示的方式,请通过布局管理器LayoutManager

         你想要控制点击,长按事件,请自己写


二、RecycleView的基本使用

1、在Gradle中引入RecycleView的依赖库。

compile 'com.android.support:recyclerview-v7:22.2.1'

2、在布局文件当中放置我们的RecycleView

xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >
    <FrameLayout
        android:id="@+id/deleteBar"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        android:alpha="0.7"
        android:elevation="1dp"
        android:background="@drawable/ripple_deletebar"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:fontFamily="sans-serif-light"
            android:textSize="20sp"
            android:textColor="?android:colorForeground"
            android:text="Delete"
            />
        FrameLayout>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/RecycleView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        />

    <ImageButton
        android:id="@+id/fab_add"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_width="@dimen/fab_size"
        android:layout_height="@dimen/fab_size"
        android:layout_gravity="bottom|right"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        android:background="@drawable/ripple"
        android:stateListAnimator="@anim/anim"
        android:src="@mipmap/ic_action_add"
        android:elevation="1dp"
        />
RelativeLayout>

3、创建适配器类继承RecycleViewAdapter,步骤为:

· 继承RecyclerView.Adapter,并且在Adapter里面声明ViewHolder类继承RecyclerView.ViewHolder,最后把自己的ViewHolder类丢进自己的Adapter类的泛型中去

· 在自定义ViewHolder类的构造方法中可以通过ID找到布局的控件,控件需要声明为自定义ViewHolder类的成员变量。

· 实现RecyclerView.Adapter的所有未实现的函数,onCreateViewHolder主要负责加载布局(加载的时候注意要把父布局写到参数里去),创建自定义ViewHolder类的对象;onBindViewHolder主要负责把数据设置到Item的控件中;getItemCount主要负责得到数据的数目

· 最好把数据声明为成员变量,在构造函数里面传进来。

· 由于RecycleView原生不支持点击事件,需要自己添加接口进行回调。


代码如下:

public class RecycleViewAdapter extends RecyclerView.Adapter {
    private Context context;
    private List mDatas;
    RecycleViewAdapter(List mDatas, Context context){
        this.mDatas=mDatas;
        this.context=context;
    }

    @Override
    public RecycleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater from = LayoutInflater.from(context);
        View view = from.inflate(R.layout.recycleview_item, parent, false);
        return new RecycleViewHolder(view);
    }
    //在这里显示item 数据
    @Override
    public void onBindViewHolder(final RecycleViewHolder holder, int position) {
        holder.textView.setText(mDatas.get(position));
    }

    @Override
    public int getItemCount() {
        return mDatas.size()!=0?mDatas.size():0;
    }

    /**
     * 添加数据
     */
    public void addData(int position , String data){
        if(mDatas.size()!=0){
            mDatas.add(position,data);
            notifyItemInserted(position);
        }else {
            mDatas.add(0,data);
            notifyItemInserted(position);
        }
    }

    /**
     * 删除数据
     */
    public void removeData(int position){
        if(mDatas.size()!=0){
            mDatas.remove(position);
            notifyItemRemoved(position);
        }
    }
    //自定义接口
    private OnItemClickListener onItemClick;
    public interface OnItemClickListener{
        void onItemClick(View v,int position,String data);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClick){
        this.onItemClick=onItemClick;
    }
    /**
     * 自定义ViewHolder 继承RecycleView
     */
    public class RecycleViewHolder extends RecyclerView.ViewHolder {
        private TextView textView;
        public RecycleViewHolder(final View itemView) {
            super(itemView);
            textView= (TextView) itemView.findViewById(R.id.tv);
            /*textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //自定义回调接口
                    Log.i("Charles", "设置监听");
                    if (onItemClick != null) {
                        onItemClick.onItemClick(itemView, getLayoutPosition(), mDatas.get(getLayoutPosition()));
                    }
                }
            });*/
        }
    }

4、下面是MainActivity中需要进行的处理。核心的步骤(某些步骤可不分先后)如下:

· 通过ID找到RecyclerView

· RecyclerView设置Adapter

· RecyclerView设置布局管理器,常用的布局管理器有LinearLayoutManager:线性布局,LayoutManager的实现类,类型包括Vertical和HorizontalGridLayoutManager;格子布局,继承自LinearLayoutManager,实现效果类似GridView;StaggeredGridLayoutManager交错的格子布局,同样也是LayoutManager的实现类,类型包括VerticalHorizontal,与GridLayoutManager很相似,不过是交错的格子,也就是宽高不等的格子视图,类似瀑布流的效果。

· RecyclerView设置数据插入、删除的时候的动画效果,这里使用默认的。下面的网址是GitHub上面的开源动画效果:https://github.com/gabrielemariotti/RecyclerViewItemAnimators

RecyclerView设置Item之间的装饰器,这里也是使用GitHub提供的装饰器

另外我还加入了添加和删除的动作。使用了

RecyclerView.OnItemTouchListener实现监听点击

代码如下:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private ArrayList mdata;
    private RecycleViewAdapter recyclerAdapter;
    private ImageButton bt;
    private FrameLayout mDeleteBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);
        recyclerView = (RecyclerView) findViewById(R.id.RecycleView);
        //设置适配器
        recyclerAdapter = new RecycleViewAdapter(Data.getSampleData(), this);
        //设置item动画
        SlideInLeftAnimatorAdapter animatorAdapter = new SlideInLeftAnimatorAdapter(recyclerAdapter, recyclerView);
        recyclerView.setAdapter(animatorAdapter);
        //设置插入,删除数据的动画
        recyclerView.setItemAnimator(new SlideInOutLeftItemAnimator(recyclerView));
        //设置布局管理器,以渲染出不同的效果
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        /* 设置每个item之间的分割线 */
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
        //设置监听 (1)
     /*   recyclerAdapter.setOnItemClickListener(new RecycleViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View v, int position, String data) {
                Toast.makeText(getApplicationContext(),data,Toast.LENGTH_SHORT).show();
            }
        });*/
        //设置监听(2)
        recyclerView.addOnItemTouchListener(new RecyclerClickListener(this, new RecyclerClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(getApplicationContext(), position + "", Toast.LENGTH_SHORT).show();
            }
        }));
        //添加数据的监听
        bt = (ImageButton) findViewById(R.id.fab_add);
        //为添加数据的按钮图标添加轮廓
        ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                // 获取按钮的尺寸
                int fabSize = getResources().getDimensionPixelSize(
                        R.dimen.fab_size);
                // 设置轮廓的尺寸
                outline.setOval(-4, -4, fabSize + 2, fabSize + 2);
            }
        };
        bt.setOutlineProvider(viewOutlineProvider);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取第一个可视的item位置
                int pos = layoutManager.findFirstCompletelyVisibleItemPosition();
                recyclerAdapter.addData(pos, "数据: " + new Random().nextInt(100));
                ObjectAnimator.ofFloat(v, "translationY", 0F, 10F).setDuration(1000).start();//Y轴平移旋转
            }
        });
        //添加删除的监听
        mDeleteBar= (FrameLayout) findViewById(R.id.deleteBar);
        mDeleteBar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int positionToRemove = layoutManager.findFirstCompletelyVisibleItemPosition();
                // 删除第一个可视的item
                recyclerAdapter.removeData(positionToRemove);
            }
        });
        //  为RecyclerView控件设置滚动事件
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //  dx:大于0,向右滚动    小于0,向左滚动
                //  dy:大于0,向上滚动    小于0,向下滚动
                Log.i("Charles","dx==="+dx+",  dy==="+dy);
                WindowManager windowManager = getWindowManager();
                Display display = windowManager.getDefaultDisplay();
                DisplayMetrics metrics=new DisplayMetrics();
                display.getMetrics(metrics);
                int height=metrics.heightPixels;
                if (dy > 0) {
                    //  列表向上滚动,隐藏删除面板
                    if (mDeleteBar.getVisibility() == View.VISIBLE) {
                        hideDeleteBar();
                    }
                } else {
                    // 列表向下滚动,显示删除面板
                    if (mDeleteBar.getVisibility() == View.GONE) {
                        showDeleteBar();
                    }
                }
            }
        });
    }
    private void showDeleteBar()
    {
        mDeleteBar.startAnimation(AnimationUtils.loadAnimation(this,
                R.anim.translate_up_on));
        mDeleteBar.setVisibility(View.VISIBLE);
    }
    private void hideDeleteBar()
    {
        mDeleteBar.startAnimation(AnimationUtils.loadAnimation(this,
                R.anim.translate_up_off));
        mDeleteBar.setVisibility(View.GONE);
    }

//监听的代码:

public class RecyclerClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mOnClickListener;
    GestureDetector mGestureDetector;

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }
    public RecyclerClickListener(Context context, OnItemClickListener listener){
        this.mOnClickListener=listener;
        mGestureDetector=new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }
    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mOnClickListener != null && mGestureDetector.onTouchEvent(e)) {
            mOnClickListener.onItemClick(childView, view.getChildPosition(childView));
            return true;
        }
        return false;
    }
    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
//用到的item 动画需要导入Library,下面会附上源码


三、运行效果

Android 5.0新特性RecycleView的基本使用_第1张图片


对啦,notifyDataSetChanged方法以及弃用了,请注意RecycleView的新规矩:

notifyDataSetChanged() 弃用notifyItemChanged(int position)notifyItemInserted(int position)notifyItemMoved(int fromPosition, int toPosition)notifyItemRemoved(int position)//range系列,多个item的操作notifyItemRangeChanged(int positionStart, int itemCount)notifyItemRangeInserted(int positionStart, int itemCount)notifyItemRangeRemoved(int positionStart, int itemCount) 

补充:可以通过AdaptergetViewType(int position)方法实现多种不同的条目。

具体做法是根据position的不同例如奇数偶数,或者特定值,然后根据viewType参数的不同去inflate不同的item布局即可。


另外,关于项目的不会上传演示的效果,只能给大家一张预览图片,请大家下载源码地址:

http://download.csdn.net/detail/plxiaopan/9438506








你可能感兴趣的:(Android 5.0新特性RecycleView的基本使用)