【问题标题】:Android Linear Layout clipping with animation带有动画的 Android 线性布局剪辑
【发布时间】:2017-07-07 08:35:47
【问题描述】:

我需要构建一个自定义视图

我将其实现为扩展 LinearLayout 的自定义视图,LinearLayout 包含另外两个 LinearLayout(对于每一行),每个元素都是另一个自定义视图,扩展了 RelativeLayout 并包含动画/状态更改的功能。

我遇到的问题是 .. 因为用箭头扩大圆圈的动画会缩放 imageview,所以 imageview 会被其父容器剪切,因为一旦绘制就设置了大小。在缩放图像视图之前,我可以在父级本身上调用 setScaleX/Y .. 但是我得到了一些奇怪的行为......必须有一个更简单的解决方案!

布局文件类

public class CameraCalibrationIndicatorCircles extends LinearLayout {

ArrayList<CalibrationIndicatorCircle> circles;
int currentCircleIndex = 0;

public CameraCalibrationIndicatorCircles(Context context) {
    super(context);
    initialize(context);
}

public CameraCalibrationIndicatorCircles(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize(context);
}

public CameraCalibrationIndicatorCircles(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initialize(context);
}

public void initialize(Context context){
    inflate(context, R.layout.camera_calibration_indication_circles_view, this);

    circles = new ArrayList<>();

    CalibrationIndicatorCircle
            c0,     c1,    c2,     c3,     c4,
            c5,     c6,    c7,     c8,     c9;

    c0 = (CalibrationIndicatorCircle)findViewById(R.id.c0);
    c1 = (CalibrationIndicatorCircle)findViewById(R.id.c1);
    c2 = (CalibrationIndicatorCircle)findViewById(R.id.c2);
    c3 = (CalibrationIndicatorCircle)findViewById(R.id.c3);
    c4 = (CalibrationIndicatorCircle)findViewById(R.id.c4);
    c5 = (CalibrationIndicatorCircle)findViewById(R.id.c5);
    c6 = (CalibrationIndicatorCircle)findViewById(R.id.c6);
    c7 = (CalibrationIndicatorCircle)findViewById(R.id.c7);
    c8 = (CalibrationIndicatorCircle)findViewById(R.id.c8);
    c9 = (CalibrationIndicatorCircle)findViewById(R.id.c9);

    circles.add(c0);
    circles.add(c1);
    circles.add(c2);
    circles.add(c3);
    circles.add(c4);
    circles.add(c5);
    circles.add(c6);
    circles.add(c7);
    circles.add(c8);
    circles.add(c9);

    currentCircleIndex = 0;
    circles.get(currentCircleIndex).indicateCurrent();

}

public void successfulEvent(){
    if(currentCircleIndex < CalibrationBox.MINIMUM_NUMBER_OF_CAMERA_IMAGES_FOR_CALIB) {
        circles.get(currentCircleIndex).indicateSucess(1,1, true);
        currentCircleIndex++;
        if (currentCircleIndex < CalibrationBox.MINIMUM_NUMBER_OF_CAMERA_IMAGES_FOR_CALIB)
            circles.get(currentCircleIndex).indicateCurrent();
    }
}

}

布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:weightSum="4"
android:clipChildren="false">

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:weightSum="5"
    android:layout_weight="1"
    android:orientation="horizontal"
    android:clipChildren="false">

    <CalibrationIndicatorCircle
        android:id="@+id/c0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:weightSum="5"
    android:layout_weight="1"
    android:orientation="horizontal">

    <CalibrationIndicatorCircle
        android:id="@+id/c5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <CalibrationIndicatorCircle
        android:id="@+id/c9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>
</LinearLayout>

单圆视图类

public class CalibrationIndicatorCircle extends RelativeLayout {

ImageView mWaiting, mCurrent, mSuccess, mCompleted;
boolean mIsCurrent = false;
Context mContext;

public CalibrationIndicatorCircle(Context context) {
    super(context);
    initialize(context);
}

public CalibrationIndicatorCircle(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize(context);
}

public CalibrationIndicatorCircle(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initialize(context);
}

public void initialize(Context context){
    inflate(context, R.layout.calibration_indicator_circle_view, this);
    mWaiting = (ImageView)findViewById(R.id.waiting);
    mCurrent = (ImageView)findViewById(R.id.current);
    mSuccess = (ImageView)findViewById(R.id.success);
    mCompleted = (ImageView)findViewById(R.id.completed);
    mCurrent.setVisibility(INVISIBLE);
    mSuccess.setVisibility(INVISIBLE);
    mCompleted.setVisibility(INVISIBLE);
}

public void indicateCurrent(){
    post(new Runnable() {
        @Override
        public void run() {
            mWaiting.setVisibility(INVISIBLE);
            mCurrent.setVisibility(VISIBLE);
            mIsCurrent = true;
        }
    });
}

public void indicateSucess(final float scaleX, final float scaleY, final boolean hideCheckMark){

    post(new Runnable() {
        @Override
        public void run() {
            //Animate
            mSuccess.setScaleX(0);
            mSuccess.setScaleY(0);
            mSuccess.setVisibility(VISIBLE);
            mCurrent.setVisibility(INVISIBLE);
            mWaiting.setVisibility(INVISIBLE);
            mSuccess
                    .animate()
                    .scaleX(scaleX)
                    .scaleY(scaleY)
                    .setDuration(500)
                    .setListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {

                            if(hideCheckMark) {

                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        postDelayed(new Runnable() {
                                            @Override
                                            public void run() {
                                                mSuccess.setVisibility(INVISIBLE);
                                                mCompleted.setVisibility(VISIBLE);
                                            }
                                        }, 300);
                                    }
                                }).start();

                            }

                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    })
                    .start();
        }
    });

}

public void hideUntilReady() {
    post(new Runnable() {
        @Override
        public void run() {
            mWaiting.setVisibility(INVISIBLE);
            mCurrent.setVisibility(INVISIBLE);
            mSuccess.setVisibility(INVISIBLE);
            mCompleted.setVisibility(INVISIBLE);
        }
    });
}
}

单圈布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:clipChildren="false">

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/image_success_icon"
    android:layout_centerInParent="true"
    android:id="@+id/success"
    android:scaleType="fitXY" />

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/image_current_icon"
    android:layout_centerInParent="true"
    android:id="@+id/current"
    android:scaleType="fitXY" />

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/image_waiting_icon"
    android:id="@+id/waiting"
    android:layout_centerInParent="true"
    android:scaleType="fitXY" />

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:srcCompat="@drawable/image_taken_icon"
    android:id="@+id/completed"
    android:layout_centerInParent="true"
    android:scaleType="fitXY" />

</RelativeLayout>

【问题讨论】:

    标签: android android-layout android-animation android-view


    【解决方案1】:

    setClipChildren(false) 用于ViewGroup 中的RelativeLayoutLinearLayout,其中包含ImageView

    【讨论】:

    • 在层次结构上的每一层布局中都试过这个......与绘制后设置的视图大小有关,无论动画如何
    • 我已经用了很长时间了,效果很好。如果您使用 xml 发布代码,我们只能进一步挖掘。
    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多