即使设置为 false,clipChildren 也无法正常工作?
Posted
技术标签:
【中文标题】即使设置为 false,clipChildren 也无法正常工作?【英文标题】:clipChildren is not working even though set to false? 【发布时间】:2014-04-08 07:41:34 【问题描述】:在我的应用程序中,我尝试使用动画来移动图像。
即使我在每个 xml 块中使用 clipChildren
false ,当我尝试对图像进行动画处理时,图像也会被剪切
<RelativeLayout
android:id="@+id/baselayout"
android:layout_
android:layout_
android:layout_alignParentRight="true"
android:layout_below="@+id/imageView1"
android:clipChildren="false"
android:clipToPadding="false" >
【问题讨论】:
对于在此处使用谷歌搜索的任何人,请注意 roflharrison 已经解决了问题,但是 roflharrison 给出的代码示例中存在错误。正确代码:***.com/a/53654808/294884 【参考方案1】:RelativeLayout 的父级之一可能正在裁剪子级(有时兼容性库会添加一个神秘的 ViewGroup,例如 NoSaveStateFrameLayout)。我过去曾成功地使用过类似的方法来禁用视图的所有父级上的剪辑:
public void disableClipOnParents(View v)
if (v.getParent() == null)
return;
if (v instanceof ViewGroup)
((ViewGroup) v).setClipChildren(false);
if (v.getParent() instanceof View)
disableClipOnParents((View) v.getParent());
【讨论】:
它对我有用,谢谢你的回答!显然,当您包含布局时会添加一些视图,这对我来说是个问题。 更新:我使用的是支持库 21.0.3。更新到 22.0.0 为我解决了这个问题! 它对我有用。但是遇到一个问题。条件是:假设 ListView_1 有 RelativeLayout_1 父级。 ListView_1 是RelativeLayout_2 的父级。 ImageView_1 的 RelativeLayout_2 父级。我需要为孩子“ImageView_1”设置动画并将其移到父母之外,而不是我使用你的方法。它工作得很好,但是在滚动列表时,ListView_1 也出现了 RelativeLayout_1。是否可以只对一个孩子应用剪辑? 对于未来的读者:以编程方式设置可能不适用于在 android4.x
设备上留下对话框片段的动画视图。但是通过 XML 为所有ViewGroup
s 设置clipChildren
和clipToPadding
+ 在onAnimationUpdate
事件上使fragment root view
无效就可以了。由于某些原因,我真的不明白,以编程方式设置剪辑设置 + 使 4x 设备上的根视图无效does not work
。在 5x 设备上,它可以在没有 XML 和手动失效的情况下工作。
系统将您的视图包装到辅助视图组中并不明显。如果您想查看它的实际效果,请打开 Layout Inspector 以查看您遇到 clipChildren="false"
无法正常工作的情况,您可能会在您的层次结构中找到一个神秘的 ViewGroup。【参考方案2】:
我知道已经晚了,但这是最简单的完整答案:
只需放置每个布局:
android:clipChildren="false"
android:clipToPadding="false"
注意@roflharrison 提到: 这在操作系统将您的视图包装/注入不在您的布局中的 ViewGroup 中的情况下不起作用
【讨论】:
正如我在回答中所解释的,这在操作系统将您的视图包装/注入不在您的布局中的 ViewGroup 中的情况下不起作用。 是的,没错【参考方案3】:最后一个原因是“RelativeLayout”。 所以要解决它,不要使用 RelativeLayout 作为大于父控件的父控件。取而代之的是 FrameLayout,例如:
<!-- it's ok as grand parent -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:clipChildren="false">
<!-- parent must not be a RelativeLayout -->
<FrameLayout
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_marginBottom="9dp">
<!-- Your Larger-than-parent View -->
<View
android:layout_
android:layout_
android:layout_gravity="center"
android:background="@android:color/black" />
</FrameLayout>
</RelativeLayout>
【讨论】:
【参考方案4】:@roflharrison 的想法很好,但是代码有一些问题:
这里我们递归地禁用了clipChildren,但是当我们到达根视图时,它的v.getParents()
会为null,方法立即返回,并且它的ClipChildren属性不会被禁用。
更重要的是,对于以下行:
if (v.getParent() instanceof View)
??视图的父级不应该是 ViewGroup 吗?我们不应该禁用 ViewGroup 的剪辑属性,而不是 View 的吗?于是我把代码改成下面这样,效果还不错:
public void disableClipOnParents(View v)
if (v == null)
return;
if (v instanceof ViewGroup)
((ViewGroup) v).setClipChildren(false);
disableClipOnParents((View) v.getParent());
【讨论】:
正确答案谢谢!! 请注意,您可能还希望设置setClipToPadding(false)
。
这也不适用于所有设备。在将其转换为 View
之前,您应该检查 v.getParent() instanceof View
。你最终可能会得到ClassCastException: android.view.ViewRootImpl cannot be cast to android.view.View
或类似的东西。有多种情况会发生这种情况 (see search results)。【参考方案5】:
您好~如果您的布局包含“paddingXXX”标签,您可以删除它们并重试。对我有用~
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:clipChildren="false"
android:gravity="center_vertical"
android:padding="8dp"
android:orientation="horizontal">
上面的代码会裁剪 childView 而下一个不会:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:clipChildren="false"
android:gravity="center_vertical"
android:orientation="horizontal">
【讨论】:
【参考方案6】:在我的情况下,clipChildren=false
不起作用,因为我还在代码中的父级上设置了 clipToOutline = true
。这个属性导致孩子被剪裁在父母的轮廓中,在我的例子中是父母背景的轮廓。似乎clipToOutline
的优先级高于clipChildren=false
。
如果clipChildren=false
不适合您,请确保您没有在代码中设置clipToOutline=true
。
【讨论】:
以上是关于即使设置为 false,clipChildren 也无法正常工作?的主要内容,如果未能解决你的问题,请参考以下文章