Vamshi
Vamshi

Reputation: 1495

clipChildren is not working even though set to false?

In my application I am trying to move images using animation. When I try to animate the image is cutting even though I use clipChildren false in every xml block

    <RelativeLayout
        android:id="@+id/baselayout"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/imageView1"
        android:clipChildren="false"
        android:clipToPadding="false" >

Upvotes: 36

Views: 43159

Answers (7)

Sergei K
Sergei K

Reputation: 1107

Same on Kotlin:

Recursive:

fun disableClipChildrenOnParents(view: View?) {
    if (view != null) {
        (view as? ViewGroup)?.clipChildren = false
        disableClipChildrenOnParents(view.parent as? ViewGroup)
    }
}

Not recursive:

private fun disableClipChildrenOnParents(view: View?) {
    var viewGroup: ViewGroup? = view?.parent as? ViewGroup
    while (viewGroup != null) {
        viewGroup.clipChildren = false
        viewGroup = viewGroup.parent as? ViewGroup
    }
}

Upvotes: 0

Milszym
Milszym

Reputation: 376

In my case clipChildren=false didn't work, because I had also set clipToOutline = true on the parent in my code. This attribute caused children to be clipped in the parent's outline which in my case was a contour of the parent's background. Seems like clipToOutline has higher priority than clipChildren=false.

If clipChildren=false does not work for you, please make sure you don't have clipToOutline=true set in the code.

Upvotes: 0

mhdjazmati
mhdjazmati

Reputation: 4232

I know its late, but this is the simplest complete answer:

just put on every layout :

    android:clipChildren="false"
    android:clipToPadding="false"

Note @roflharrison mentioned: this won't work in the cases where the operating system wraps/injects your view in ViewGroup's that's aren't in your layout

Upvotes: 23

Kehui Li
Kehui Li

Reputation: 311

The idea of @roflharrison is quite good, however, the codes has some problem: Here we disable clipChildren recursively, but when we reached the root view, it's v.getParents() would be null, the method returns immediately, and its ClipChildren attribute won't be disabled.

What's more, for the following line:

if (v.getParent() instanceof View)

?? Shouldn't the parent of the view be a ViewGroup? And shouldn't we disable ViewGroup's clip attributes, not View's? So I change the code to the following, and it worked quite well:

public void disableClipOnParents(View v) {
    if (v == null) {
        return;
    }
    if (v instanceof ViewGroup) {
        ((ViewGroup) v).setClipChildren(false);
    }
    disableClipOnParents((View) v.getParent());
}

Upvotes: 6

Yun.Lu
Yun.Lu

Reputation: 61

Hi~ if your layout includes "paddingXXX" tags, you can remove them and try again. it's work for me~

<RelativeLayout 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:clipChildren="false"
    android:gravity="center_vertical"
    android:padding="8dp"
    android:orientation="horizontal">

code above will clip childView and next will not:

<RelativeLayout 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:clipChildren="false"
    android:gravity="center_vertical"
    android:orientation="horizontal">

Upvotes: 1

Xavier.S
Xavier.S

Reputation: 329

The final reason is "RelativeLayout". So to solve it, don't use RelativeLayout as your Larger-than-parent control's parent. FrameLayout instead, like:

<!-- it's ok as grand parent -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipChildren="false">

    <!-- parent must not be a RelativeLayout -->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="38dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="9dp">

        <!-- Your Larger-than-parent View -->
        <View
            android:layout_width="56dp"
            android:layout_height="138dp"
            android:layout_gravity="center"
            android:background="@android:color/black" />

    </FrameLayout>

</RelativeLayout>

Upvotes: 11

roflharrison
roflharrison

Reputation: 2320

One of the parents of your RelativeLayout might be clipping children (sometimes compatibility libraries add a mystery ViewGroup such as NoSaveStateFrameLayout for example). I've used something like this in the past with success to disable clip on all parents of a view:

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());
    }
}

Upvotes: 39

Related Questions