Android - 在LinearLayout或RelativeLayout中为View的topMargin/bottomMargin/etc设置动画

kar*_*age 11 android android-animation android-layout

我正在尝试创建一个从底部向上滑动的菜单.它从菜单的视图开始,只在屏幕底部可见,然后单击它使其向上滑动.我尝试使用a TranslateAnimation,但是虽然像素移动,但菜单的命中区域与之前的位置相同.所以我认为如果我可以在动画完成后调整菜单的边距,这将完成我想要的.但是,我无法弄清楚如何调整边距.

我试图创建一个LinearLayout.LayoutMargins对象,然后设置它的边距并将其应用到菜单的视图(这是一个LinearLayout),但这不起作用.

有任何想法吗?

Arn*_*son 21

以下对我有用.首先确定菜单向上(完全可见)或向下(大部分隐藏)的下边距(以逢低计).

private static final int BOTTOM_MARGIN_UP = -50; // My menu view is a bit too tall.
private static final int BOTTOM_MARGIN_DOWN = -120;
Run Code Online (Sandbox Code Playgroud)

然后,在onCreate()中:

menuLinearLayout = (LinearLayout)findViewById(R.id.menuLinearLayout);
setBottomMargin(menuLinearLayout, BOTTOM_MARGIN_DOWN);

upAnimation = makeAnimation(BOTTOM_MARGIN_DOWN, BOTTOM_MARGIN_UP);
downAnimation = makeAnimation(BOTTOM_MARGIN_UP, BOTTOM_MARGIN_DOWN);

Button toggleMenuButton = (Button)findViewById(R.id.toggleMenuButton);
toggleMenuButton.setOnTouchListener(new View.OnTouchListener()
{
    public boolean onTouch(View view, MotionEvent motionEvent)
    {
        if (motionEvent.getAction() != MotionEvent.ACTION_DOWN) return false;
        ViewGroup.MarginLayoutParams layoutParams =
            (ViewGroup.MarginLayoutParams)menuLinearLayout.getLayoutParams();
        boolean isUp = layoutParams.bottomMargin == dipsToPixels(BOTTOM_MARGIN_UP);
        menuLinearLayout.startAnimation(isUp ? downAnimation : upAnimation);
        return true;
    }
});
Run Code Online (Sandbox Code Playgroud)

这是秘密酱;-)

private TranslateAnimation makeAnimation(final int fromMargin, final int toMargin)
{
    TranslateAnimation animation = 
        new TranslateAnimation(0, 0, 0, dipsToPixels(fromMargin - toMargin));
    animation.setDuration(250);
    animation.setAnimationListener(new Animation.AnimationListener()
    {
        public void onAnimationEnd(Animation animation)
        {
            // Cancel the animation to stop the menu from popping back.
            menuLinearLayout.clearAnimation();

            // Set the new bottom margin.
            setBottomMargin(menuLinearLayout, toMargin);
        }

        public void onAnimationStart(Animation animation) {}

        public void onAnimationRepeat(Animation animation) {}
    });
    return animation;
}
Run Code Online (Sandbox Code Playgroud)

我使用两个实用功能:

private void setBottomMargin(View view, int bottomMarginInDips)
{
    ViewGroup.MarginLayoutParams layoutParams =    
        (ViewGroup.MarginLayoutParams)view.getLayoutParams();
    layoutParams.bottomMargin = dipsToPixels(bottomMarginInDips);
    view.requestLayout();
}

private int dipsToPixels(int dips)
{
    final float scale = getResources().getDisplayMetrics().density;
    return (int)(dips * scale + 0.5f);
}
Run Code Online (Sandbox Code Playgroud)

瞧!


kar*_*age 3

我的解决方案是创建两个 LinearLayout,一个处于向上状态(设置为消失),另一个处于菜单向下状态。然后,当用户单击按钮向上滑动菜单时,我调用TranslateAnimation显示菜单向上滑动。我在动画上放置了一个侦听器,使向上状态可见,并且在动画完成时向下状态消失。我将其反转为“关闭”操作。

与我最初想象的方式不完全一样,但它确实有效。