一个简单的RecyclerView多布局实现
来源:互联网 发布:java项目开发实例源码 编辑:程序博客网 时间:2024/05/21 08:51
实现一个简单的item多布局,当做记录,主要是通过不同的itemType来实现,先放上我的实现效果,运行使用的是 API19的模拟器,如下,图片大都是百度的:
由于使用了百分比布局,所以横屏的也顺便适配了,横屏的如下,
需要注意一下这些地方:
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 包含子元素的个数。
- 一个简单的RecyclerView多布局实现
- RecyclerView多布局的简单实现
- RecyclerView多布局的简单实现
- RecyclerView实现多布局
- 实现RecyclerView多布局
- RecyclerView多布局实现
- RecyclerView多布局实现
- 一个recyclerView实现linear和Grid的布局
- Android RecyclerView与泛型 简单实现多布局
- Android RecyclerView加载不同布局简单实现
- RecyclerView的多布局
- 一个RecyclerView实现QQ空间相册布局
- MultiRecyclerView(多布局的RecyclerView)的简单使用
- RecyclerView样式布局文件的简单使用
- Android简单的实现RecyclerView
- RecyclerView的简单使用(一)———— 实现各种布局效果
- recyclerView实现复杂布局的好处
- 优雅地实现RecyclerView的复杂布局
- RxJava 和 RxAndroid 三(生命周期控制和内存优化)
- MVV-LVA
- Naive Bayes Classifier in OpenNLP
- iOS 缓存文件管理
- scrollview滑动随着actiongbar状态变化
- 一个简单的RecyclerView多布局实现
- FreeRTOS系列第12篇---FreeRTOS任务应用函数
- MicroPython - 硬件
- Java开源报表JasperReport、iReport4.5.1使用详解(一)
- java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
- OpenCV3.1-OpenCL的使用
- dispatch_soruce_t的简单使用事例
- CodeForces 732B Cormen — The Best Friend Of a Man(带着宠物轧马路)
- 探索 Android——Handler