RecycleView 与 Elevation

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<HomeItemInfo> 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属性

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true">

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="10dp"
        android:background="#ffffff"
        android:elevation="4dp" />
</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值