Android - 在translateY()动画上更新视图的高度

Har*_*rry 5 android android-animation android-layout

我有一个布局,我想在按钮点击后展开,如下所示:

期望

问题是我需要使用动画,所以我决定使用View.animate.translationY().这是我的代码:

private void showBottomThreeLines(boolean show){
    if(show)
        mShiftContainer.animate().translationY(0);
    else
        mShiftContainer.animate().translationY(-(mFifthLineContainer.getHeight() * 3));
}
Run Code Online (Sandbox Code Playgroud)

但是,这是我在测试后获得的:

现实

当前高度仍然是一样的先前的高度!视图的高度正在使用MATCH_PARENT.我甚至试图改变它1000dp,但它仍然具有相同的高度.如何在translationY()动画期间更新视图的高度?

Har*_*rry 2

经过一些研究,我发现平移后定义视图高度根本不会增加其高度。看来整个视图的高度总和不能超过其父布局的高度。这意味着,如果您将父布局的高度设置为MATCH_PARENT并且屏幕尺寸为 960 dp,则子视图的最大高度将为 960 dp,即使您定义了其高度,例如android:layout_height="1200dp"

因此,我决定动态调整父布局的高度,并设置页脚布局的高度MATCH_PARENT。默认情况下,我的父布局的高度是MATCH_PARENT,但我在 上调用以下方法onCreateView()

private void adjustParentHeight(){
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics metrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(metrics);
    ViewGroup.LayoutParams params = mView.getLayoutParams();
    mFifthLineContainer.measure(0, 0);
    params.height = metrics.heightPixels + (mFifthLineContainer.getMeasuredHeight() * 3);
    mView.setLayoutParams(params);
}
Run Code Online (Sandbox Code Playgroud)

这将使我的页脚布局变得超出屏幕。然后我尝试使用View.animate().translationY(),但又遇到了另一个问题!Android 动画存在一个 bug ,导致调用时出现 View.setY() 闪烁 onAnimationEnd()。看来原因是onAnimationEnd() 在动画真正结束之前被调用。以下是我用来解决此问题的参考资料:

Android 动画闪烁

Android使用Animation和onAnimationEnd Listener时出现闪烁

因此,我改变了我的showBottomThreeLines()方法:

private void showBottomThreeLines(boolean show){
    if(show){
        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, -(mFifthLineContainer.getHeight() * 3), 0);
        translateAnimation.setDuration(300);
        translateAnimation.setFillAfter(true);
        translateAnimation.setFillEnabled(true);
        translateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                mShiftContainer.setY(mShiftContainer.getY() + mFifthLineContainer.getHeight() * 3);
            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        mShiftContainer.startAnimation(translateAnimation);
    } else{
        TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, mFifthLineContainer.getHeight() * 3, 0);
        translateAnimation.setDuration(300);
        translateAnimation.setFillAfter(true);
        translateAnimation.setFillEnabled(true);
        translateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                mShiftContainer.setY(mFifthLineContainer.getY());
            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        mShiftContainer.startAnimation(translateAnimation);
    }
}
Run Code Online (Sandbox Code Playgroud)