一个简单的RecyclerView多布局实现
2016-10-19 23:26
363 查看
实现一个简单的item多布局,当做记录,主要是通过不同的itemType来实现,先放上我的实现效果,运行使用的是 API19的模拟器,如下,图片大都是百度的:
![](http://7xpfzy.com1.z0.glb.clouddn.com/1.gif)
由于使用了百分比布局,所以横屏的也顺便适配了,横屏的如下,
![](http://7xpfzy.com1.z0.glb.clouddn.com/2.gif)
需要注意一下这些地方:
1、由于我的最外层布局使用的是 viewpager + fragment,在轮播图下面几个圆形按钮的布局(第二个itemType)也是fragment,所以在第二个itemType 里面需要使用
2、轮播图使用的是 github 的一个开源:
https://github.com/youth5201314/banner
也可以自己写,里面给的圆形指示器设置了大小和高度,所以我们需要通过反射来修改(如果是自定义指示器的话),或者通过一组圆形指示器图片来直接使用也可以,反射如下:
3、第二个itemType 的圆形指示器就通过xml来画,通过一个 linearLayout 动态添加即可:
4、还有一个是最后的itemType的实现,可以看到有三个有停车场的标志,有两个没有,所以需要让没有点设置为INVISIBLE,在onBindViewHolder中添加如下代码:
但是上面这个会出现 bug,就是下拉刷新之后停车场没有设置为INVISIBLE 标志也会随机的不见,开始可能有一个,也可能是两个,最后全部都消失,旋转屏幕之后回来又恢复正常,所以需要设置成如下:
我开始是想通过 layoutManager 来获取每个 item 之后隐藏,如下:
但是这样无效,同样,通过如下开始运行时候可以,但是由于它获取的是可见屏幕的位置,所以会导致隐藏位置不确定,代码如下,同样在 onAttachedToRecyclerView 中添加:
所以需要在 onBindViewHolder 中设置。
5、状态栏着色使用了 systembartint,封装了一下:
其它的都很简单,就是注意百分比布局的使用,通过 itemType同样 也可以添加上拉刷新,刷新数据可以写个观察者模式或者使用广播、EventBus,加载图片用的是Glide,并且这里没有使用Glide的缓存,代码还有很多欠缺,菜鸟一枚,权当记录。
代码放在这里:
https://github.com/laymanZ/SimpleRecyclerViewItem
6、上面这种实现的方法使用了多个fragment,另一种可以直接使用一个gridLayoutManager 和 一个 recyclerview 即可,通过重写 grdiLayoutManager 的 setSpanSizeLookup 方法,代码如下:
如上,gridLayoutManager 是 列数为 2 的管理器,在getSpanSize里面,
![](http://7xpfzy.com1.z0.glb.clouddn.com/1.gif)
由于使用了百分比布局,所以横屏的也顺便适配了,横屏的如下,
![](http://7xpfzy.com1.z0.glb.clouddn.com/2.gif)
需要注意一下这些地方:
1、由于我的最外层布局使用的是 viewpager + fragment,在轮播图下面几个圆形按钮的布局(第二个itemType)也是fragment,所以在第二个itemType 里面需要使用
getChildFragmentManager()而不是 getFragmentManager(),否则会造成 最下面导航栏切换 fragment 时,切换页面之后 第二个itemType 的圆形图标加载不出来(try try),这是因为变成了是fragment管理子fragment,所以需要这样设置;
2、轮播图使用的是 github 的一个开源:
https://github.com/youth5201314/banner
也可以自己写,里面给的圆形指示器设置了大小和高度,所以我们需要通过反射来修改(如果是自定义指示器的话),或者通过一组圆形指示器图片来直接使用也可以,反射如下:
int testDp = ***; Field field = banner.getClass().getDeclaredField("mIndicatorMargin"); field.setAccessible(true); field.set(banner,testDp);
3、第二个itemType 的圆形指示器就通过xml来画,通过一个 linearLayout 动态添加即可:
for(int i=0;i<3;i++) { // 设置圆圈点 View view = new View(getContext()); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(10,10); params.leftMargin = 20; view.setBackgroundResource(R.drawable.point_background); view.setLayoutParams(params); view.setEnabled(false); linearLayout.addView(view); }
4、还有一个是最后的itemType的实现,可以看到有三个有停车场的标志,有两个没有,所以需要让没有点设置为INVISIBLE,在onBindViewHolder中添加如下代码:
if(position != 3) holder.hot_title_place.setVisibility(View.GONE); for(int i = 0;i<hotPlaceHidePosition.length;i++) { if (position == hotPlaceHidePosition[i]) { holder.stop_car_sign.setVisibility(View.INVISIBLE); } }
但是上面这个会出现 bug,就是下拉刷新之后停车场没有设置为INVISIBLE 标志也会随机的不见,开始可能有一个,也可能是两个,最后全部都消失,旋转屏幕之后回来又恢复正常,所以需要设置成如下:
holder.hot_title_place.setVisibility(View.VISIBLE); if(position != 3) holder.hot_title_place.setVisibility(View.GONE); holder.stop_car_sign.setVisibility(View.VISIBLE); for(int i = 0;i<hotPlaceHidePosition.length;i++) { if (position == hotPlaceHidePosition[i]) { holder.stop_car_sign.setVisibility(View.INVISIBLE); } }
我开始是想通过 layoutManager 来获取每个 item 之后隐藏,如下:
@Override public void onAttachedToRecyclerView(final RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); Toast.makeText(context,"onAttachedToRecyclerView",Toast.LENGTH_SHORT).show(); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if(manager instanceof LinearLayoutManager) { View view = manager.findViewByPosition(5); ImageView imageView = (ImageView) view.findViewById(R.id.stop_car_sign); imageView.setVisibility(View.INVISIBLE); } }
但是这样无效,同样,通过如下开始运行时候可以,但是由于它获取的是可见屏幕的位置,所以会导致隐藏位置不确定,代码如下,同样在 onAttachedToRecyclerView 中添加:
recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int width = recyclerView.getWidth(); int height = recyclerView.getHeight(); if (width > 0 && height > 0) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { recyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } } View firstRecyclerViewItem = recyclerView.getLayoutManager().findViewByPosition(0); } });
所以需要在 onBindViewHolder 中设置。
5、状态栏着色使用了 systembartint,封装了一下:
public class MethodUtil { private SystemBarTintManager tintManager; private static MethodUtil methodUtil; public static MethodUtil getMethodUtil() { if(methodUtil == null) methodUtil = new MethodUtil(); return methodUtil; } /* * 通知栏统一颜色,沉浸式 * */ public void systemBarColorUtil(Context context,int color) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT<Build.VERSION_CODES.LOLLIPOP) { // 下面这句话必须的 getActivity(context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); tintManager = new SystemBarTintManager(getActivity(context)); tintManager.setStatusBarTintEnabled(true); tintManager.setTintResource(color);//通知栏所需颜色 } } /* * 通过获取 context 获取activity * */ private Activity getActivity(Context context) { while(!(context instanceof Activity) && context instanceof ContextWrapper) { context = ((ContextWrapper) context).getBaseContext(); } if(context instanceof Activity) { return (Activity)context; } throw new ActivityNotFoundException("Unable to get Activity"); } }
其它的都很简单,就是注意百分比布局的使用,通过 itemType同样 也可以添加上拉刷新,刷新数据可以写个观察者模式或者使用广播、EventBus,加载图片用的是Glide,并且这里没有使用Glide的缓存,代码还有很多欠缺,菜鸟一枚,权当记录。
代码放在这里:
https://github.com/laymanZ/SimpleRecyclerViewItem
6、上面这种实现的方法使用了多个fragment,另一种可以直接使用一个gridLayoutManager 和 一个 recyclerview 即可,通过重写 grdiLayoutManager 的 setSpanSizeLookup 方法,代码如下:
final GridLayoutManager gridLayoutManager = new GridLayoutManager(this,2); gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { int type = mRecyclerView.getAdapter().getItemViewType(position); if(type == DataModel.TYPE_THREE) return gridLayoutManager.getSpanCount(); else return 1; } }); mRecyclerView.setLayoutManager(gridLayoutManager);
如上,gridLayoutManager 是 列数为 2 的管理器,在getSpanSize里面,
return 1则表示返回的布局大小占一行的
1/2,因为 上面声明的是 2 列,即分母为 2 ,下面 return 1中1是分子,所以如果想要占满整个 Item 的话,return 2 即可,即
2/2(如果声明列数为3,return 1 即表示 占一个 item的 1/3,有点啰嗦,哈哈), 在这里 return 2 也就是 return gridLayoutManager.getSpanCount(),数据不会写死。所以,只要使用一个 gridLayoutManager 和 最外层 一个 recyclerview 即可,通过不同 type 来设置每一行的item 包含子元素的个数。
相关文章推荐
- android RecyclerView 简单实现横竖布局穿插
- 一个RecyclerView实现QQ空间相册布局
- Android RecyclerView加载不同布局简单实现
- Android RecyclerView加载不同布局简单实现
- Android RecyclerView与泛型 简单实现多布局
- 一个 ScrollView 里面包含 viewpager 嵌套 listview 或 RecyclerView 极少代码实现的流畅滑动效果 处理一个两层滑动 view 的自定义布局,以最少的代码实现,
- Recyclerview的一些个人理解与使用(二)实现一个简单的列表界面
- RecyclerView多布局的简单实现
- 一个recyclerView实现linear和Grid的布局
- RecyclerView多布局的简单实现
- iOS开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- 利用UIScrollView实现一个简单的图片轮播
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- iOS开发UI基础—23使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- 问题:关于贴友的一个书本页面简单布局(html+css)的实现
- Android学习-实现一个ListView中由Checkbox和TextView构成的布局
- ios开发UI基础—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- 一个实现了ViewPart和EditroPart的简单RCP例子