clipToPadding和clipChildren

clipToPadding解决listview滚动问题

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#2262"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:paddingTop="16dp" >
    </ListView>

</LinearLayout>

这里写图片描述
可以发现滚动时顶部16dp的padding是永远滚不到的,这样看起来比较奇怪,怎么解决?
只要在ListView里加入一行代码,就可以解决问题

 android:clipToPadding="false"

这里写图片描述
原理分析

问题:设置了clipToPadding=false之后,为何一开始的时候padding里没东西,滚的时候可以滚到padding里去了呢?

clipToPadding官方解释是
the ViewGroup will clip its children and resize (but not clip) any EdgeEffect to its padding, if padding is not zero.
意思是padding非空的时候,viewgroup会根据padding值来裁剪子view。
默认情况下,clipToPadding为true,表示会裁剪子view并且resize边界效果。
实际上是clipToPadding影响的是绘制的时候是否绘制padding里的子view内容。可以这么理解,clipToPadding对measure和layout无影响,只会影响draw阶段。无论clipToPadding是true还是false,滚的时候,都会滚到padding里去,但是clipToPadding为true,就会clip,这样padding里的部分就看不到了。回头看看刚才的问题,滚动前,布局是考虑padding的,所以padding里没有child元素,然后滚动的时候会把child滚动到padding里去,而由于clipToPadding=false,不裁剪,所以我们能看到padding里的child。如果设置clipToPadding=true,那padding里的child就会被裁剪掉,我们就看不到了。

关键代码可以看ViewGroup的dispatchDraw

  final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
        if (clipToPadding) {
            clipSaveCount = canvas.save();
            canvas.clipRect(mScrollX + mPaddingLeft, mScrollY + mPaddingTop,
                    mScrollX + mRight - mLeft - mPaddingRight,
                    mScrollY + mBottom - mTop - mPaddingBottom);
        }

clipChildren

还有个类似的clipChildren,这个的作用是,如果子view比parent大的时候,是否裁剪,默认为true裁剪。也是在绘制阶段作用的。

举个例子,在100*100的布局里放个200*200的button会怎么样?

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:orientation="vertical">

    <LinearLayout
        android:background="#ff0000"
        android:layout_width="100dp"
        android:layout_height="100dp">

        <Button
            android:id="@+id/btn"
            android:text="ww"
            android:layout_width="200dp"
            android:layout_height="200dp" />
    </LinearLayout>

</LinearLayout>

这里写图片描述
默认情况下结果如左图所示,Button被裁剪,只有parent内部的可以显示,clipChildren设置为true之后,如右图所示,整个button都显示出来了,非常简单.注意android:clipChildren=”false”必须在最外层布局里写才有效果。这个属性在做动画的时候非常有用,因为默认是被裁剪的,所以一个view无法超过parent,在放大或者移动的动画中就可能被裁剪,用了此属性就不会被裁剪了。

ps,为何上图中会有部分红色,这是Button样式决定的,Button上下左右都会有点留白。

总结

1、clipToPadding 是否可以在padding区域内绘制
2、子view是否可以超出父view的区域
3、对应工程ClipDemo
来源:
点击这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值