ClipChildren не работает
В моем приложении я пытаюсь перемещать изображения с помощью анимации.
Когда я пытаюсь анимировать изображение (imageView2
или imageView4
) до imageView1
, изображение вырезается, когда оно выходит из макета.
Здесь исходное изображение imageView2
или imageView4
, а целевое изображение imageView1
Ниже мой XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/animRL"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="40dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/deskcard" />
<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" >
<RelativeLayout
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="5dp"
android:clipChildren="false"
android:clipToPadding="false"
android:gravity="bottom|center" >
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="@+id/imageView4"
android:layout_marginLeft="118dp"
android:clipChildren="false"
android:clipToPadding="false"
android:src="@drawable/test" />
<ImageView
android:id="@+id/imageView4"
android:layout_width="40dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="104dp"
android:clipChildren="false"
android:clipToPadding="false"
android:src="@drawable/test1" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
И код анимации ниже:
imageView4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int sourceCoords[] = new int[2];
int targetCoords[] = new int[2];
int xDelta;
int yDelta;
imageView4.getLocationOnScreen(sourceCoords);
image.getLocationOnScreen(targetCoords);
xDelta = targetCoords[0] - sourceCoords[0];
yDelta = targetCoords[1] - sourceCoords[1];
TranslateAnimation animation = new TranslateAnimation(0, xDelta, 0, yDelta);
animation.setDuration(400);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener());
imageView4.startAnimation(animation);
}
});
Ответы
Ответ 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());
}
}
Ответ 2
Последняя причина - RelativeLayout.
Поэтому, чтобы решить эту проблему, не используйте RelativeLayout в качестве родителя-регулятора Larger-parent. FrameLayout вместо этого, например:
<!-- it 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>
Ответ 3
Я знаю его поздно, но это самый простой полный ответ:
просто наденьте каждый макет:
android:clipChildren="false"
android:clipToPadding="false"
Ответ 4
Привет ~, если ваш макет содержит теги paddingXXX, вы можете удалить их и повторить попытку. это работает для меня ~
<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">
код выше будет обрезать childView, а следующий не будет:
<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">
Ответ 5
Идея @roflharrison неплоха, однако коды имеют некоторые проблемы: здесь мы отключили clipChildren рекурсивно, но когда мы достигли корневого представления, v.getParents()
будет иметь значение null, метод немедленно вернется и его атрибут ClipChildren не будет отключен.
Что еще, для следующей строки:
if (v.getParent() instanceof View)
?? Разве родительский взгляд не должен быть ViewGroup? И не следует ли отключать атрибуты клипов ViewGroup, а не View's? Поэтому я меняю код на следующий, и он работал достаточно хорошо:
public void disableClipOnParents(View v) {
if (v == null) {
return;
}
if (v instanceof ViewGroup) {
((ViewGroup) v).setClipChildren(false);
}
disableClipOnParents((View) v.getParent());
}