前言
Android 中当子 View 的宽度/高度超过父 View 时,超出部分系统不会显示。
但有时 UI 设计人员对于自己的设计理念有着执着的追求。使用 clipChildren 属性可以满足需求,同时减少我们的代码量。
Andoid - clipChildren
clipChildren 的默认值为 true,即子 View 的宽度/高度超过父 View 时,超出部分系统不会显示。
当 clipChildren 值为 false 时,如果子 View 的宽度/高度超过父 View 时,超出部分系统不会显示。
然而事情并没有那么简单,在使用过程发现该属性不会生效。
小结
笔者做了七个实验,但肯定有哥们没耐心看完,总结下 clipChildren 生效的前提条件:
- clipChildren 声明在爷爷属性下即可。我当初写代码写急眼了,写了个递归,所有 ViewGroup 的 View 属性都设置了 clipChildren。没必要,只需要设置爷爷属性即可。
- 要保证爷爷有足够的空间显示超出的部分。
- 如果超出部分在爷爷的最右侧,可以给爷爷设置 paddingRight,同时给爷爷设置 clipToPadding=“false” 即可。可见最后一个示例。
另外 clipChildren 会导致超出部分无法响应点击事件,可以通过此篇文章试下,我就不测试了。
实验
写了一个简单的 Demo,记录各种无效的、有效的写法,防止后人踩坑。
图片 img_brand :
clipChildren 设置在父 View 属性下
设置不会无效:一个 Activity,其布局文件设置如下:
<?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:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@color/red"
android:clipChildren="false">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</LinearLayout>
示例图如下:
clipChildren 设置在爷爷属性下且爷爷比父 View 更宽
设置会生效:一个 Activity,其布局文件设置如下:
<?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:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@color/red"
android:clipChildren="false">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</LinearLayout>
示例图如下:
clipChildren 设置在爷爷属性下且爷爷和父亲一样宽
设置不会生效:一个 Activity,其布局文件设置如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" // 或者设置为 120 dp
android:layout_height="wrap_content" // 或者设置为 120 dp
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@color/red"
android:clipChildren="false">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</LinearLayout>
示例图如下:
clipChildren 设置在爷爷属性下且爷爷比父 View 更宽,但是只宽一点点
设置会生效,但是只显示了部分:一个 Activity,其布局文件设置如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="130dp" // 因为我设置了 gravity="center",要想完全显示,需要设置为 140 dp。
android:layout_height="130dp"
android:gravity="center"
android:background="@color/blue"
android:orientation="vertical">
<RelativeLayout
android:layout_width="120dp"
android:layout_height="120dp"
android:background="@color/red"
android:clipChildren="false">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</LinearLayout>
示例图如下:
因为我设置了 gravity=“center”,要想完全显示,需要设置其爷爷宽度为 140 dp。
clipChildren 设置在爷爷属性下且爷爷比父 View 更宽且 View 在最右侧
设置不会生效,因为爷爷的右侧没有显示的空间了。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="160dp"
android:layout_height="160dp"
android:background="@color/blue"
android:clipChildren="false">
<RelativeLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:background="@color/red">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</RelativeLayout>
示例图如下:
clipChildren 设置在爷爷属性下且 爷爷比父 View 更宽且 View 在最右侧且爷爷右侧设置足够空间的 padding
设置不会生效:有的哥们说,既然最右侧没有空间显示,那么给爷爷设置一个 padding,那不就显示了吗?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="160dp"
android:layout_height="160dp"
android:background="@color/blue"
android:clipChildren="false"
android:paddingRight="10dp">
<RelativeLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:background="@color/red">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</RelativeLayout>
示例图如下:
clipChildren 设置在爷爷属性下且爷爷比父 View 更宽且 View 在最右侧且爷爷右侧设置足够空间的 padding 且爷爷设置了 clipToPadding
设置会生效:上个例子的思路是对的,要想生效,还需要额外给爷爷设置一个属性 clipToPadding=“false”。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="160dp"
android:layout_height="160dp"
android:background="@color/blue"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingRight="10dp">
<RelativeLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:background="@color/red">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="-10dp"
android:src="@drawable/img_brand" />
</RelativeLayout>
</RelativeLayout>
示例图如下: