RecycleView的使用及坑
来源:互联网 发布:浙江省中医院知乎 编辑:程序博客网 时间:2024/06/16 02:23
腾讯写的:https://www.cnblogs.com/bugly/p/6264751.html
RecycleView的使用及坑
原文: http://dalufan.com/2016/12/02/android-recycleview-useage-issues/ 作者: 大路
控制Item的宽度
在布局中存在某个item占用一行,而有的一行会有多个item,及类似于listview和gridview的混合,这时可以通过下面的方法来设置:
12345678910
GridLayoutManager layoutManager = new GridLayoutManager(this, 3);layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {public int getSpanSize(int position) {//如果isSection(position),那么这个条目将占用SpanCount()这么多的列数,也就是3//而如果不是,就占用1列即可return isSection(position) ? layoutManager.getSpanCount() : 1;}});recycleview.setLayoutManager(layoutManager);
滑动停止刷新数据
判断是否正在滑动的方法是getScrollState(),如果它等于RecyclerView.SCROLL_STATE_IDLE说明不在滑动,判断有没有在计算layout的方法是isComputingLayout(),取否就可以得到不在计算的时候,通过这两个条件来决定是否刷新数据
123
if (!recyclerView.isComputingLayout() && RecyclerView.SCROLL_STATE_IDLE == recyclerView.getScrollState()) {mAdapter.notifyDataSetChanged();}
getPosition getLayoutPosition getAdapterPosition
- getPosition(); 查阅资料后发现[已弃用]
- getLayoutPosition(); [条目在最新布局计算中的位置]
- getAdapterPosition(); [条目在是适配器中的位置]
getLayoutPosition
、getAdapterPosition
这两种类型的位置是等同的,除非在分发adapter.notify*事件和更新布局时。
adapter和layout的位置会有时间差(<16ms), 如果你改变了Adapter的数据然后刷新视图, layout需要过一段时间才会更新视图, 在这段时间里面, 这两个方法返回的position会不一样.
在notifyDataSetChanged之后并不能马上获取Adapter中的position, 要等布局结束之后才能获取到.
而对于Layout的position, 在notifyItemInserted之后, Layout不能马上获取到新的position, 因为布局还没更新(需要<16ms的时间刷新视图), 所以只能获取到旧的, 但是Adapter中的position就可以马上获取到最新的position.
返回布局位置的方法使用最近一次布局运算后的位置,如getLayoutPosition()和findViewHolderForLayoutPosition(int)。这些位置包含了最近一次布局运算后的变化。你可以根据这些位置来与用户正在屏幕上看到的保持一致。比如,你有一个条目列表,当用户请求第5个条目时,你可以使用这些方法来匹配用户看到的。
另外一系列方法与AdapterPosition关联,比如getAdapterPosition()和findViewHolderForAdapterPosition(int)。当你想获得条目在更新后的适配器中的位置使用这些方法,即使这些位置变化还没反映到布局中。比如,你想访问适配器中条目的位置时,就应该使用getAdapterPosition()。注意,如果notifyDataSetChanged()已经被调用而且还没计算新布局,这些方法或许不能够计算适配器位置。所以,你要小心处理这些方法返回NO_POSITION和null的情况。
总之,当使用RecycleView.LayoutManager时使用getLayoutPosition布局位置。使用RecycleView.Adapter时,使用getAdapterPosition适配器位置。
pointToPosition
在AbsListView(listview、gridview)中,有个根据屏幕位置获取pos的方法:pointToPosition
,但在recycleview中没有这个方法,可以通过下面方法来达到相同的效果
12
View targetView = recyclerView.findChildViewUnder(x, y);recyclerView.getChildAdapterPosition(targetView);
OnContextMenuListener
http://stackoverflow.com/questions/26466877/how-to-create-context-menu-for-recyclerview
ContextMenuRecyclerView.java
1234567891011121314151617181920212223242526272829303132333435363738394041424344
public class ContextMenuRecyclerView extends RecyclerView {public ContextMenuRecyclerView(Context context) {super(context);}public ContextMenuRecyclerView(Context context, AttributeSet attrs) {super(context, attrs);}public ContextMenuRecyclerView(Context arg0, AttributeSet arg1, int arg2) {super(arg0, arg1, arg2);}private RecyclerViewContextMenuInfo mContextMenuInfo;protected ContextMenu.ContextMenuInfo getContextMenuInfo() {return mContextMenuInfo;}public boolean showContextMenuForChild(View originalView) {final int longPressPosition = getChildAdapterPosition(originalView);if (longPressPosition >= 0) {final long longPressId = getAdapter().getItemId(longPressPosition);mContextMenuInfo = new RecyclerViewContextMenuInfo(longPressPosition, longPressId);return super.showContextMenuForChild(originalView);}return false;}public static class RecyclerViewContextMenuInfo implements ContextMenu.ContextMenuInfo {public RecyclerViewContextMenuInfo(int position, long id) {this.position = position;this.id = id;}final public int position;final public long id;}}
In your Fragment (or Activity):
123456789101112131415161718192021
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);mRecyclerView = view.findViewById(R.id.recyclerview);registerForContextMenu(mRecyclerView);}public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {super.onCreateContextMenu(menu, v, menuInfo);// inflate menuMenuInflater inflater = getActivity().getMenuInflater();inflater.inflate(R.menu.my_context_menu, menu);}public boolean onContextItemSelected(MenuItem item) {return super.onContextItemSelected(item);RecyclerViewContextMenuInfo info = (RecyclerViewContextMenuInfo) item.getMenuInfo();// handle menu item here}
ViewHolder
123456
class MyViewHolder extends RecyclerView.View.ViewHolder {...private void onLongClick() {itemView.showContextMenu();}}
getChildAt is null
使用下面两个方法代替
12345
//1findViewHolderForAdapterPosition//2View viewItem = recycleView.getLayoutManager().findViewByPosition(position);View icon = viewItem.findViewById(R.id.view);
notifyitemchanged方法会回到顶部
当点击某个item的时候,RecyclerView回到顶部.
解决办法。使用setHasFixedSize(true)
方法。
下面是RecyclerView单选点击实现:
12345
categories.get(lastPosition).setSelected(false);categoryAdapter.notifyItemChanged(lastPosition);categories.get(position).setSelected(true);categoryAdapter.notifyItemChanged(position);lastPosition=position;
- RecycleView的使用及坑
- Android RecycleView---- RecycleView的简单使用
- Recycleview的使用
- RecycleView的使用
- RecycleView 的使用
- Android RecycleView的使用
- RecycleView的简单使用
- RecycleView 的使用
- RecycleView的基础使用
- android RecycleView的使用
- RecycleView的学习使用
- RecycleView的使用(一)
- RecycleView的首次使用
- RecycleView的使用
- RecycleView的使用
- RecycleView 的简单使用
- recycleView的使用
- RecycleView的使用
- Linux---ubuntu下core文件的产生与使用
- gulp自动化构建工具
- 初创企业如何快速实现数据化运营
- 性能测试划分
- 走穿Android动画---补间动画alpha、scale、translate、rotate、set的xml属性及用法
- RecycleView的使用及坑
- 高通ffbm的一些问题随笔记 7 19
- Could not open ServletContext resource
- ES6循环数组新方法for-of(转)
- mybatis中 find_in_set 与in的使用
- Android开发使用的常见第三方框架汇总
- 【分布式存储项目】(4)Nginx服务器反向代理与负载均衡
- Pie 【二分】
- 线程 的使用