资讯专栏INFORMATION COLUMN

RecycleView 与 Elevation

neu / 2521人阅读

摘要:以前一直用,因为可以搞定绝大部分需求。如果只用做透明的分割线,复写就可以实现了。列表本身如果对分割线的不敏感,复写就可以。阴影是子打在父上的子必须设置父必须比子稍大一些,父不要用,在子上用属性

RecycleView

以前一直用ListView,因为ListView可以搞定绝大部分需求。最近项目UI做了很大调整,需要宽度不同的Item混排,记录一下遇到的问题。
类似这样效果

宽度不同的Item混排-SpanSizeLookup

这个很简单,一个方法就搞定了

int maxSpanSize = 2;
GridLayoutManager manager = new GridLayoutManager(mContext, maxSpanSize, GridLayoutManager.VERTICAL, false);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        HomeItemInfo itemInfo = homeItemInfoList.get(position);
        if (itemInfo.isTwoItem()) {
            return 1;//  1/maxSpanSize, 这里代表占最大宽度的1/2
        } else {
            return 2;//  2/maxSpanSize, 这里代表与最大宽度等宽
        }
    }
});
分割线 ItemDecoration

onDrawOver
绘制在图层的最上层

onDraw
绘制图层在ItemView以下,所以如果绘制区域与ItemView区域相重叠,会被遮挡

getItemOffsets
设置ItemView的内嵌偏移长度

RecycleView的ItemDecoration 用起来比ListView的Divider还是复杂很多。
如果只用做透明的分割线,复写getItemOffsets就可以实现了。列表本身如果对分割线的不敏感,复写onDrawOver就可以。一些复杂的分割线需要同时复写getItemOffsets、onDrawOver,计算还是有些麻烦的。下面分享下getItemOffsets的计算。

public class RecycleDivider extends RecyclerView.ItemDecoration {

    private int rightMargin = 100;//px, item距离右边的margin
    private int leftMargin = 100;//px, item距离左边的margin
    private int verticalDivider = 20;//px, 竖直方向分割线的宽度
    private int horizontalDivider = 10;//px, 水平方向分割线的宽度

    private List itemInfos = new ArrayList<>();

    public RecycleDivider() {
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
        GridLayoutManager.SpanSizeLookup lookup = layoutManager.getSpanSizeLookup();
        GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) view.getLayoutParams();
        int childPosition = parent.getChildAdapterPosition(view);
        int spanCount = layoutManager.getSpanCount();
        int position = parent.getChildAdapterPosition(view);//得到它在总数里面的位置
        int spanIndex = lookup.getSpanIndex(position, layoutManager.getSpanCount());//获取每排的位置
        int spanSize = lookup.getSpanSize(position);//获取它所占有的比重,上面讲的

        if (layoutManager.getOrientation() == GridLayoutManager.VERTICAL) {//这里只处理竖直方向的列表
            //竖直方向
            if (layoutManager.getSpanSizeLookup().getSpanGroupIndex(childPosition, spanCount) == 0) {//第一排的需要上面
                outRect.top = horizontalDivider;
            }
            outRect.bottom = horizontalDivider;

            //水平方向,这里只适合一行两个item的情况
            //每个item的宽度是均分的,如果每个item的outRect.left, outRect.right加起来的和不一样,会导致item大小不一致
            outRect.left = verticalDivider / 2;
            outRect.right = verticalDivider / 2;
            boolean isRight = spanIndex + spanSize == spanCount;//最右
            boolean isLeft = spanIndex == 0;//最左
            if (isLeft) {
                outRect.left = leftMargin;
            }
            if (isRight) {
                outRect.right = rightMargin;
            }
        }
    }
}
Elevation

Android从5.0开始支持阴影,5.0之前可以用CardView,但是CardView用padding实现,对界面会有影响,可以只在5.0以上支持阴影。

阴影是子View打在父View上的

子View必须设置Background

父View必须比子View稍大一些,父View不要用padding,在子View上用Margin属性



    

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69225.html

相关文章

  • 数字高程模型(Digital Elevation Model) DEM 切片以及数据发布展示学习笔

    摘要:是一套库,用来渲染地球,区域地图,和多种要素,不需要安装任何插件就能在支持最新标准的浏览器上运行,支持硬件加速,非常适合动态数据在图层上的展示,是一个跨平台,开源,非常有前途的表现层库。 Cesiumjs 是一套javascript库,用来渲染3D地球,2D区域地图,和多种GIS要素,不需要安装任何插件就能在支持最新HTML5标准的浏览器上运行,支持WebGL硬件加速,非常适合动态数据...

    FleyX 评论0 收藏0

发表评论

0条评论

neu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<