Android - 在translationY()动画中更新视图高度

8
我有一个布局,在点击按钮后希望它能够扩展,如下所示: Expectation 问题在于我需要使用动画,因此我决定使用View.animate.translationY()。以下是我的代码:
private void showBottomThreeLines(boolean show){
    if(show)
        mShiftContainer.animate().translationY(0);
    else
        mShiftContainer.animate().translationY(-(mFifthLineContainer.getHeight() * 3));
}

然而,测试后我得到了这个结果:
当前高度仍然与之前的高度相同!视图的高度使用MATCH_PARENT。我甚至尝试将其更改为1000dp,但它仍具有相同的高度。在translationY()动画期间如何更新视图的高度?

1
translate不会设置高度,它将视图移动到x、y...缩放为您完成工作...使用mShiftContainer.animate().scaleY(-(mFifthLineContainer.getHeight() * 3)).setDuration(2000); - Angad Tiwari
尝试使用不同的属性,例如mShiftContainer.animate().scaleYBy()或mShiftContainer.animate().y()。 - Angad Tiwari
我认为scaleY()不是一个好的解决方案,因为它会放大我的字体大小、填充、边距等。这只会破坏我的布局。另外,我已经尝试过y(),但它只更新了我的Y位置而没有增加其高度。 - Harry
1
尝试这个:https://dev59.com/fGkw5IYBdhLWcg3wus7K - Angad Tiwari
答案得到了14个赞...它对我完美地工作。 - Angad Tiwari
显示剩余2条评论
2个回答

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

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

Android 动画闪烁

使用动画和 onAnimationEnd 监听器时的 Android 闪烁

因此,我改变了我的 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);
    }
}

0

使用这个:

private ActionMode mActionMode;

...


private void expandView(View summary, int height, final boolean isSearch) {
        if (isSearch) summary.setVisibility(View.VISIBLE);

        final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
        summary.measure(widthSpec, height);

        Animator animator = slideAnimator(summary.getHeight(), height, summary);
        animator.start();
    }

    private void collapseView(final View summary, int height, final boolean isSearch) {
        int finalHeight = summary.getHeight();

        ValueAnimator mAnimator = slideAnimator(finalHeight, height, summary);
        final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
        summary.measure(widthSpec, height);

        Animator animator = slideAnimator(summary.getHeight(), height, summary);
        animator.start();
        mAnimator.start();
    }

    /**
     * Slide animation
     *
     * @param start   start animation from position
     * @param end     end animation to position
     * @param summary view to animate
     * @return valueAnimator
     */
    private ValueAnimator slideAnimator(int start, int end, final View summary) {

        ValueAnimator animator = ValueAnimator.ofInt(start, end);

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //Update Height
                int value = (Integer) valueAnimator.getAnimatedValue();

                ViewGroup.LayoutParams layoutParams = summary.getLayoutParams();
                layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, value, getResources().getDisplayMetrics());//value;
                summary.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }

    private ActionMode.Callback mActionModeCallBack = new ActionMode.Callback() {
        //Contextual action menu. Shows different options in action bar when a list item is long clicked!
        @Override
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            // Inflate a menu resource providing context menu items
            MenuInflater inflater = actionMode.getMenuInflater();
            inflater.inflate(R.menu.contextual_menu_options, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
            mActionMode.finish();
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode actionMode) {
            mActionMode = null;
        }
    };

希望这能对你有所帮助!


谢谢你的回答!我尝试了你的代码,但还是没有成功。高度已经改变了,但布局的Y位置没有改变。你的代码中是否有需要修改的部分才能实现我的目标? - Harry
@Harry,你能发一下你的XML文件吗? - ArbenMaloku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接