赞
踩
一、RecycleView简介
RecycleView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式。该控件用于在有限的窗口中展示大量数据集,它被作为ListView和GridView控件的继承者。
那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , 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、创建适配器类继承RecycleView的Adapter,步骤为:
· 继承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<RecycleViewAdapter.RecycleViewHolder> { private Context context; private List<String> mDatas; RecycleViewAdapter(List<String> 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的实现类,类型包括Vertical和Horizontal,与GridLayoutManager很相似,不过是交错的格子,也就是宽高不等的格子视图,类似瀑布流的效果。
· RecyclerView设置数据插入、删除的时候的动画效果,这里使用默认的。下面的网址是GitHub上面的开源动画效果:https://github.com/gabrielemariotti/RecyclerViewItemAnimators
RecyclerView设置Item之间的装饰器,这里也是使用GitHub提供的装饰器
另外我还加入了添加和删除的动作。使用了
RecyclerView.OnItemTouchListener实现监听点击
代码如下:
public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private ArrayList<String> 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,下面会附上源码
三、运行效果
对啦,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)
补充:可以通过Adapter的getViewType(int position)方法实现多种不同的条目。
具体做法是根据position的不同例如奇数偶数,或者特定值,然后根据viewType参数的不同去inflate不同的item布局即可。
另外,关于项目的不会上传演示的效果,只能给大家一张预览图片,请大家下载源码地址:
http://download.csdn.net/detail/plxiaopan/9438506
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。