RecyclerView的 item侧滑拖动、添加head、footview、下拉刷新。
来源:互联网 发布:python 模拟火势蔓延 编辑:程序博客网 时间:2024/05/23 23:43
越来越喜欢RecylerView了,尤其配合上CardView,界面简直就瞬间高大上了。。。。
先说个题外话,我的Android studio2.1.1,电脑还算可以,不过用AS经常电脑卡死!对,卡到任务管理器都开不了,点什么都没用。网上查了查。解决方法:setting--System setting--Updates--然后把两个选择框都取消了。果然解决了! 当然日常卡的话,不要管,喝点水回来就好了。。。
(公司电脑不能联网。。小代码就先直接贴出来了,以后把代码都搞Github上。看着不爽,还见谅了。。)
进入主题:本篇博文 分享的内容是用ItemTouchHelp类实现侧滑、拖动,headview和footview的添加(三种layoutmanager)、下拉刷新。
先来张效果图:
1.添加headerView、footerView
使用RecyclerView发现没有和listView一样的设置头,尾项的方法了。那好,咱们自己搞!条条大路通罗马。。
RecyclerView中有Type机制。有个type的回调方法--getItemViewType(position);
那好我们就来用Type机制。我们以添加个FooterView为例吧。
(1)思路:
1.再写一个ViewHolder,作为FooterView的Holder。
2.重写public int getItemViewType(int position);方法。这个方法中,根据position返回不同的Type。比如position为数据的最后一项时,返回Type为FooterView。
3.重写的public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)方法。这个方法中根据参数viewType,来返回不同的ViewHolder。
4.重写的public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)方法。通过holder instanceof XXViewHolder,来进行不同的item数据显示。
5.getItemCount()方法。可别忘记把新增的数量加上去。比如加了N个FooterView,就要+N;
好了,贴下几个方法具体代码了:
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_ITEM) { View inflate = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false); return new MyViewHolder(inflate); } else { View inflate = LayoutInflater.from(mContext).inflate(R.layout.footer_item, parent, false); return new FooterHolder(inflate); } } @Override public int getItemViewType(int position) { if (position == getItemCount() - 1) { return TYPE_FOOTER; } return TYPE_ITEM; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof MyViewHolder) { ((MyViewHolder) holder).setContentText(datas.get(position)); ((MyViewHolder) holder).setDateText("2020-09-0" + position); ((MyViewHolder) holder).setItemClick(); ((MyViewHolder) holder).setItemLongClick(); ((MyViewHolder) holder).setImage(); } else if (holder instanceof FooterHolder) { } } @Override public int getItemCount() { return datas.size() + 1; }
(2)兼容各种layoutManager:
1.解决瀑布layoutmanager:
@Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); Log.e("TAG","onViewAttachedToWindow"); ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams(); if (holder.getItemViewType() == TYPE_FOOTER && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) { ((StaggeredGridLayoutManager.LayoutParams) layoutParams).setFullSpan(true); } }是在onViewAttachedToWindow方法下,将对应的一项的layoutParams设置为全宽。
@Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { Log.e("TAG", "onAttachedToRecyclerView"); super.onAttachedToRecyclerView(recyclerView); isStaggerid = false;//重置标记位 final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { final GridLayoutManager manager = (GridLayoutManager) layoutManager; manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override //该方法返回此position要占用的span. public int getSpanSize(int position) { int viewType = getItemViewType(position); if (viewType == TYPE_FOOTER) { //分两列,则return 2;表示占两个 return ((GridLayoutManager) layoutManager).getSpanCount(); } else { //其余正常项,占用一个 return 1; } } }); } else if (layoutManager instanceof StaggeredGridLayoutManager) { isStaggerid = true; } }在onCreateViewHolder中判断并设置params:
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Log.e("TAG", "onCreateViewHolder"); RecyclerView.ViewHolder myViewHolder = null; if (viewType == TYPE_ITEM) { View inflate = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false); myViewHolder = new MyViewHolder(inflate); } else if (viewType == TYPE_FOOTER) { View inflate = LayoutInflater.from(mContext).inflate(R.layout.footer_item, parent, false); myViewHolder = new FooterHolder(inflate); } if(myViewHolder!=null){ ViewGroup.LayoutParams layoutParams = myViewHolder.itemView.getLayoutParams(); //如果type是FooterView,并且是瀑布流manager,就改变其layoutParams为全宽 if (viewType == TYPE_FOOTER && isStaggerid) { ((StaggeredGridLayoutManager.LayoutParams) layoutParams).setFullSpan(true); } } return myViewHolder; }
2.解决GridLayoutManager:
那好,我们看看这个adpater里面还有什么可以重写的方法。
发现嫌疑方法:
1.public void onAttachedToRecyclerView(RecyclerView recyclerView):看方法名,大概明了了。并且参数是recyclerView,这样就可以获取到当前的layoutManger了。
再看看源码,发现有好多span相关的方法。GridLayoutManager类里面有一个这方法:
public void setSpanSizeLookup(GridLayoutManager.SpanSizeLookup spanSizeLookup):Sets the source to get the number of spans occupied by each item in the adapter.
不管怎样,试试吧。需要实现getSpanSize(int position)方法。此方法注释:Returns the number of span occupied by the item at position.(所占据的span数量。。)
先根据position获取到Type,如果type是footerView等,则返回占据全部span。反之,返回正常item占据的span数量。
该方法代码:
@Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { Log.e("TAG", "onAttachedToRecyclerView"); super.onAttachedToRecyclerView(recyclerView); isStaggerid = false;//重置标记位 final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { final GridLayoutManager manager = (GridLayoutManager) layoutManager; manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override //该方法返回此position要占用的span. public int getSpanSize(int position) { int viewType = getItemViewType(position); if (viewType == TYPE_FOOTER) { //分两列,则return 2;表示占两个 return ((GridLayoutManager) layoutManager).getSpanCount(); } else { //其余正常项,占用一个 return 1; } } }); } else if (layoutManager instanceof StaggeredGridLayoutManager) { isStaggerid = true; } }
GridLayoutManager解决!
(3)总结:
这中type方法,不仅仅是HeaderView,FooterView,分组功能也是可以的。很方便的设计!
2.ItemTouchHelp实现item的拖动,侧滑
public MyRecyclerViewAdapter(Context context, final ArrayList<String> datas, RecyclerView recyclerView) { this.mContext = context; this.datas = datas; this.view = recyclerView; //手势帮助类 ItemTouchHelper touchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { private RecyclerView.ViewHolder vh; @Override public boolean isItemViewSwipeEnabled() { return true; } /** * 在某个Item被拖动和移动时回调,这里用来播放动画,当viewHolder不为空时为选中状态,否则为释放状态。 * @param viewHolder * @param actionState */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if (viewHolder != null) { pickUpAnimation(viewHolder.itemView); vh = viewHolder; } else { if (vh != null) { putDownAnimation(vh.itemView); } } } /** * 设置滑动,移动方向 * @param recyclerView * @param viewHolder * @return */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if (viewHolder instanceof FooterHolder) { return 0; } //拖动标记方向 int dragDirection = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; //swipe 的标记方向 int swipeDirection = ItemTouchHelper.START | ItemTouchHelper.END; // int swipeDirection = 0; return makeMovementFlags(dragDirection, swipeDirection); } /** * 当移动至要交换的程度,执行此方法 * @param recyclerView * @param viewHolder * @param target * @return */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { if (!(target instanceof FooterHolder)) { Collections.swap(datas, viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } return false; } /** * 在onMove后马上执行此方法 */ @Override public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y){ Log.e("TAG", "onMoved"); super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y); MyRecyclerViewAdapter.this.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition()); } /** * 滑动之后回调 * @param viewHolder * @param direction */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { int layoutPosition = viewHolder.getAdapterPosition(); notifyItemRemoved(layoutPosition); MyRecyclerViewAdapter.this.datas.remove(layoutPosition); } @Override public float getSwipeEscapeVelocity(float defaultValue) { return super.getSwipeEscapeVelocity(defaultValue); } }); touchHelper.attachToRecyclerView(view); }
private void pickUpAnimation(View view) { ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationZ", 5f, 20f); animator.setInterpolator(new DecelerateInterpolator()); animator.setDuration(300); animator.start(); } private void putDownAnimation(View view) { ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationZ", 20f, 5f); animator.setInterpolator(new DecelerateInterpolator()); animator.setDuration(300); animator.start(); }
(1) 几行代码重点:
(2)注意点:
3.下拉刷新:
(1)用SwipRefreshLayout包裹RecyclerView就OK了。
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swiperefresh" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/toolbar"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical"></android.support.v7.widget.RecyclerView> </android.support.v4.widget.SwipeRefreshLayout>
(2)可以设置一下监听:
/** * 下拉刷新的回调 */ @Override public void onRefresh() { swipLayout.setRefreshing(true); new Handler().postDelayed(new Runnable() { @Override public void run() { String s = "Refreshing!!!!!!!!!!!!!"; datas.set(0, s); swipLayout.setRefreshing(false); adapter.notifyDataSetChanged(); } }, 4000); }
(3)设置其他效果
4.总结
- RecyclerView的 item侧滑拖动、添加head、footview、下拉刷新。
- RecyclerView 下拉刷新 加载更多 左滑删除 拖动排序
- 最强RecyclerView,Item侧滑菜单,长按拖拽Item,滑动删除Item。可以和任何下拉刷新框架结合使用
- recyclerview中添加下拉刷新
- Android RecyclerView+item动画+下拉刷新,上拉加载更多,侧滑删除(易用可定制)
- RecyclerView添加headerview和footview
- RecyclerView的下拉刷新
- RecyclerView的基本用法,下拉刷新下拉加载以及item的增删
- 添加头、尾和动画的下拉刷新RecyclerView
- 上拉加载下拉刷新的RecyclerView可添加headerView
- 可添加Header可下拉刷新的RecyclerView
- 为RecyclerView添加FootView和HeadView
- RecyclerView(ScrollView嵌套,添加HeardView、FootView)
- RecyclerView+OkHttp的下拉刷新
- 让多种类型item的Recyclerview能够上拉和下拉刷新--XRefreshView
- RecyclerView下拉刷新,滑动删除以及拖动变换位置
- 问题排除:RecyclerView添加分割线后,每次下拉刷新 Item与分割线间都会增加间距。
- RecyclerView实现上拉刷新,下拉加载,item点击事件
- 从内存角度解析Java字符编码
- Springmvc
- 137. Single Number II LeetCode
- J2EE进阶(五)Spring在web.xml中的配置
- 数据结构与算法MOOC习题解题报告(PART 1:第6课-第8课)与PART 1总结
- RecyclerView的 item侧滑拖动、添加head、footview、下拉刷新。
- git Permission denied (publickey) 问题
- zookeeper原理
- (转)知乎的提问--服务器端测试主要包含什么?
- iOS-最全的App上架教程
- Hibernate多对一与一对多
- 哥德巴赫猜想
- Java的常量
- 【4003】编码