Metail Design之RecyclerView
Posted jeffery336699
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Metail Design之RecyclerView相关的知识,希望对你有一定的参考价值。
1.RecyclerView简单设置:
1 private void initRecyclerView() {
2 mList = new ArrayList<>();
3 for (int i = 0; i < 60; i++) {
4 mList.add(String.format(getString(R.string.lesson),(1+i)+""));
5 }
6 setLayoutManget(switchId);
7 mAdapter = new MainRecyclerAdapter(mList);
8 mRy.setAdapter(mAdapter);
9 mRy.setItemAnimator(new DefaultItemAnimator());
10 mAdapter.setItemClickListener(new MainRecyclerAdapter.ItemClickListener() {
11 @Override
12 public void click(View view, int position, String text) {
13 Toast.makeText(MainActivity.this, "点击--" + text, Toast.LENGTH_SHORT).show();
14 goActivity(position);
15 }
16 });
17 }
rv是高度解耦,可以为他设置LayoutManger,ItemAnimotor,Adaper,Deliver分割线等.
2.设置条目添加,移除时可以局部刷新,尽可能优化性能:
3.要使用StaggeredGridLayoutManager
1).这里模拟给每个Item动态分配高度,记得使用
1 @Override
2 public MainViewHold onCreateViewHolder(ViewGroup parent, int viewType) {
3 // View view = View.inflate(parent.getContext(), android.R.layout.simple_list_item_1, null);//没有添加进parent
4 // View view = View.inflate(parent.getContext(), android.R.layout.simple_list_item_1, parent);//双重parent
5 View view =LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1,parent,false);
6 return new MainViewHold(view);
7 }
2).上面注释两种方式有问题,第一种getLayoutParams参数为空,第二种resoure(android.R.layout.simple_list_item_1)有两个parent,因为查看源码发现root.add(view,params)添加了一次,recyclerview自己又会把item添加进入它之中.
3).上面两种方法最终调用的是这个方法,对应的还是第三种方法
4).上一张瀑布流的图:
3.RecyclerView设置条目点击事件:
方式一:采用holder.getAdaperPosition()来获得当前条目的位置信息,这种可以实时获取position信息,包括addItem和remove条目,最好应用于数据集变化的情况.
监听器:
应用于RecyclerView:
4.RecycleView分割线:
1).初识RecyclerView.ItemDecoration中的 getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
我们可以给divider一个set方法,来动态设置
设置所有item的偏移:
divider绘制的位置:(根据上面)
onDraw()真正的绘制:
计算边距:
这里以绘制垂直方法为例,也就是长形矩形为例讲解:
这里有一点非常需要注意:
就是parent.getChildCount()方法是获得当前屏幕一屏的ChildView 数量:
(1).这里绘制的时候child的param要用RecyclerView.LayoutParam的,因为它继承与MaragLayout可以拿到Margin边距
drawHorazotion()也是同样的原理,再讲讲我们自定义的ItemDecoration怎么应用于recyclerview:
2).这里说说如何判断最后一行最后一列:
3).判断最后一列:
5.RecyclerView像ListView那样添加头和尾布局:
1).通过看ListView添加头尾的源码,它其中采用了代理模式,添加头尾的时候重新new了一个WrapHeaderListViewAdapter,里面分别用两个List<View> 来存放添加进来的头和尾,getView,getCount等方法还是使用原来adapter,或者加以修饰还是交给子类去实现,所以我们也来模仿这样:
3).通过getItemViewType来区分当前条目是什么类型(头,尾,正常条目)
5).onBindViewHolder
6).使用还是跟平常rv一样使用,wrapheadrecyclerview使我们偷偷做的
效果图:
6.RecyclerView添加拖拽和侧滑:
1).添加拖拽和侧滑需要用到一个ItemTouchHelper,以及ItemTouchHelper.Callback:
1 getMovementFlags()方法
onMove()方法
onSwiped()方法
isLongPressDragEnabled()方法:
onSelectedChanged()方法:
clearView()方法:
onChildDraw()方法:
2).两个不同的类之间通信,采用Interface接口做桥梁,很好的降低耦合:
public QQAdapter(List<QQMessage> list, StartDragListener startDragListener) {
this.list = list;
mStartDragListener =startDragListener;
}
holder.iv_logo.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN){
mStartDragListener.onStartDrag(holder);
}
return false;
}
});
例如:这里QQAdapter相与外界通信,通过StartDragListener 接口,把图标iv_logo按下移动时,让ItemTouchHelper调用startDrag()方法
/**
* 监听Viewhold.icon按下上下拖拽的监听
*/
public interface StartDragListener {
void onStartDrag(RecyclerView.ViewHolder viewHolder);
}
在Activity中这样实现:
QQAdaper中:
都是调用的notify方法
效果图如下:
注意:
如图:
以上是关于Metail Design之RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章
Block Design 小技巧之添加RTL代码到block_design