1.Android recycleView万能分隔线 GridLayoutManager布局item左右间距均等(最易懂)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.Android recycleView万能分隔线 GridLayoutManager布局item左右间距均等(最易懂)相关的知识,希望对你有一定的参考价值。
参考技术A 今天开始讲RecycleView的系列教程。分割线,分组,局部刷新,动态添加,缓存原理,抖音效果,瀑布流。嵌套,动画等等RecyclerView的分割线是通过canvas和设置item偏移画出来的.需要知道2个方法
getItemOffsets()和onDraw方法
getItemOffsets 是针对每一个 ItemView
onDraw:遍历,进行颜色修改
我们可以看到自定义的 TestDividerItemDeoration 只实现了一个方法 getItemOffsets()。方法里面有四个参数。
Rect outRect
View view
RecyclerView parent
RecyclerView.State state
绿色区域代表 RecyclerView 中的一个 ItemView,而外面橙色区域也就是相应的 outRect,也就是 ItemView 与其它组件的偏移区域,等同于 margin 属性,通过复写 getItemOffsets() 方法,然后指定 outRect 中的 top、left、right、bottom 就可以控制各个方向的间隔了。
这实现了简单的分隔线效果,但这种方法分隔线的效果只能取决于背景色,如果我要定制分割线的颜色呢?这个时候就要 onDraw()。
————————————————
源码分析:在recycleview中的
分割线要注意,没有颜色,默认是白色的,会看不出来
第一种方案,通过
getItemOffsets()方法进行分割线!
判断是否是第一个,最后一个,是单个还是双个,是什么类型
/***
* 分割线要注意,没有颜色,默认是白色的,会看不出来
* @param outRect
* @param view
* @param parent
* @param state
*/
private void testItemOffset(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
int childAdapterPosition = parent.getChildAdapterPosition(view);
if (childAdapterPosition ==0)
outRect.set(0, 20, 0, 20);
else
outRect.set(0, 0, 0, 20);
第二种方案:ondraw()
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)
super.onDraw(c, parent, state);
int childCount = parent.getChildCount();
for (int i =0; i < childCount; i++)
View view = parent.getChildAt(i);
int index = parent.getChildAdapterPosition(view);
//第一个ItemView不需要绘制
if (index ==0)
continue;
float dividerTop = view.getTop() -mDividerHeight;
float dividerLeft = parent.getPaddingLeft();
float dividerBottom = view.getTop();
float dividerRight = parent.getWidth() - parent.getPaddingRight();
c.drawRect(dividerLeft, dividerTop, dividerRight, dividerBottom, mPaint);
GridLayoutManager布局item左右间距均等
思路分析
首先,我们知道,对于 GridLayoutmanager ,当我们设置的 spancount 为 3 的时候,那么每个 item 的最大宽度为 itemMaxW = recycylerW / spancount = recycylerW / 3.
假设我们 spancount 为 3,那么在不设置 itemDercation 的情况下它的分布是这样的,可以看到第一列与最后一行的距离是不一样的
GridVIew出现的问题:本来固定item.高度和宽度
1.分割线有,不是理想的,左右均等
2.上下没有分割线
源码得到:
按上面分析的源码,我们可以知道,调用outRect.set(int left, int top, int right, int bottom)方法时,left一直为0,right一直为divider的宽度,而每一项item的宽度都要减去(left+right)大小,
left一直为0,right一直为divider的宽度
左上右下到底是什么的值?
计算每一个item移动的距离,左边和右边的移动距离
计算分析:
1.左边的分割线宽度为sW (已知)
2.每个显示item的宽度,布局定义的itemWidth
3. 总共分割线宽度:totalDivider=屏幕宽度-spanCount*itemWidth
4.列之间的分割线宽度为dw =(屏幕宽度-spanCount*item-2*sW )/(spantcount-1)
5.每个item需要留出的空间 ew=totalDivider/spanCount(即paddingLeft+paddingRight)
left: 左边的间距值(绝对值,差值)
right:右边的间距值
每个item移动的距离:
第一个Item:L0=sW R0=eW-sW
第二个Item:L1=dW-R0=dW-eW+sW R1=eW-L1=2eW-dW-sW
第三个Item:L2=dW-R1=2(dW-eW)+sW R2=eW-L2=3eW-2dW-sW
得出公式:
Ln=(position%spanCount)*(dw-ew)+sw
Rn=ew-Ln
总结:得到3个值dw,ew, sw的值
sw:左边的距离
ew:每个的平均的分割线
dw: 列之间的分割线宽度
int firstLastSpace =50;//最左边的分割线宽度
@SuppressLint("LongLogTag")
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
super.getItemOffsets(outRect, view, parent, state);
count++;
outRect.top =20;
mDividerHeight =0;
int itemWidth =dip2px(context, 100);
int screenWidth = getScreenWidth(context);
int dw = (screenWidth -3 * itemWidth -2 *firstLastSpace) /2;//最终计算出这个padding值
//误区:中间的分割线的总距离,左右可能是不等的
int totalDivder = screenWidth -3 * itemWidth;
Log.d("TestDividerItemDecoration", "totalDivder" + totalDivder);
int eachDivder = totalDivder /3;
int itemPosition = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
//不要用for循环
outRect.left = (itemPosition %3) * (dw - eachDivder) +firstLastSpace;
outRect.right = eachDivder - outRect.right;
错误的思路:
//误区:中间的分割线的总距离,左右可能是不等的
//不要用for循环
int firstLastSpace =50;//最左边的分割线宽度
@SuppressLint("LongLogTag")
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
super.getItemOffsets(outRect, view, parent, state);
count++;
outRect.top =20;
mDividerHeight =0;
int itemWidth =dip2px(context, 100);
int screenWidth = getScreenWidth(context);
int padding = (screenWidth -3 * itemWidth -2 *firstLastSpace) /4;//最终计算出这个padding值
//不能这么算,必须保证每个item的分割线一样才行。
Log.d("TestDividerItemDecoration", "getItemOffsets" +count +"item宽度:" + itemWidth +"padding" + padding);
//仅仅计算左边和右边的距离
int childCount = parent.getChildCount();
for (int i =0; i < childCount; i++)
if (i %3 ==0) //最左边的item
outRect.left =firstLastSpace;
outRect.right = padding;
else if (i %3 ==1)
outRect.left = padding;
outRect.right = padding;
else if (i %3 ==2)
outRect.left = padding;
outRect.right =firstLastSpace;
瀑布流的设置:
int spanIndex = layoutParams.getSpanIndex();
public class FeedDecorationextends RecyclerView.ItemDecoration
private HomePageCardAdaptermHomePageCardAdapter;
public FeedDecoration(HomePageCardAdapter mHomePageCardAdapter)
this.mHomePageCardAdapter = mHomePageCardAdapter;
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state)
if (mHomePageCardAdapter ==null)
return;
if (mHomePageCardAdapter.getItemViewType(parent.getChildAdapterPosition(view)) == HomePageMultipleCard.HOMEPAGE_MULTIPLE_CARD_TYPE_FITNESS_FEED)
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
int spanIndex = layoutParams.getSpanIndex();
if (spanIndex ==0)
outRect.set(DensityUtil.dip2px(ShadowApp.context(), 14), 0, DensityUtil.dip2px(ShadowApp.context(), 5), DensityUtil.dip2px(ShadowApp.context(), 10));
else
outRect.set(DensityUtil.dip2px(ShadowApp.context(), 5), 0, DensityUtil.dip2px(ShadowApp.context(), 14), DensityUtil.dip2px(ShadowApp.context(), 10));
demo地址: https://github.com/pengcaihua123456/shennandadao
苹果MAC电脑到底怎么使用WiFi万能钥匙
电脑版的wifi万能钥匙和手机版的使用方法一样的,需要连接手机的数据连接,或者连接现在的无线网络热点才能辅助破解网络连接。使用万能钥匙需要开启手机数据流量或者连接无线wifi热点网络,需要从网络下载WiFi热点网络数据进行分析才能连接上被分享的wifi网络热点。
能不能连接上无线wifi网络热点,关键靠其他的用户分享无线wifi热点账户数据才能连接。 参考技术A 建议安装Wi-Fi万能钥匙解密连接起来
以上是关于1.Android recycleView万能分隔线 GridLayoutManager布局item左右间距均等(最易懂)的主要内容,如果未能解决你的问题,请参考以下文章