Android的 - 动画视图的TOPMARGIN中的LinearLayout或RelativeLayout的/ bottomMargin的/ etc

StackOverflow https://stackoverflow.com/questions/2239442

我想创建一个从底部滑出了菜单。它首先在屏幕的底部只是可见的,然后单击它使其向上滑动菜单的视图。我试图用一个TranslateAnimation,但虽然像素移动,菜单的命中领域之前是在相同的位置。所以我想,如果我可以调整菜单的利润率动画完成后,这将完成我想要的东西。然而,我无法找出如何调整边距。

我试图创建一个LinearLayout.LayoutMargins对象,然后设置其利润率,并将其应用到菜单的观点(这是一个LinearLayout),但这是行不通的。

任何想法?

有帮助吗?

解决方案 2

我的解决方案是创建两个LinearLayouts,一个在它的最高状态(设置为走了),另一个在菜单的下跌状态。然后,当在用户点击按钮滑动菜单,我打电话显示菜单滑了TranslateAnimation。我把一个监听器上引起了状态可见动画和向下状态消失在动画完成时。我逆转了这种用于“关闭”操作。

不完全是我原本想象的这样做,但它的工作方式。

其他提示

以下为我工作。先决定的菜单往上(完全可见)或下底边缘(浸液)(大部分隐藏)。

private static final int BOTTOM_MARGIN_UP = -50; // My menu view is a bit too tall.
private static final int BOTTOM_MARGIN_DOWN = -120;

然后,在的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;
    }
});

和来这里的秘密武器; - )

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

我使用两个实用功能:

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

瞧!

使用ViewPropertyAnimator

if (view.getY() != margin) {
    view.animate().y(margin).setDuration(150).start();
}

我觉得这是一个黑客攻击少一点。基本上,它是使自己的动画。在它下面的设置只在topMargin修改RelativeLayout,但它不会是很难一概而论的。

import java.util.Calendar;

import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.RelativeLayout.LayoutParams;

public class MarginAnimation extends Thread {
    final String TAG = "MarginAnimation";
    long mStartTime;
    long mTotalTime;
    Interpolator mI;

    int mStartMargin;
    int mEndMargin;

    View mV;
    Activity mA;
    public MarginAnimation(Activity a, View v, 
            int startMargin, int endMargin, int totaltime,
            Interpolator i) {
        mV = v;
        mStartMargin = startMargin;
        mEndMargin = endMargin;
        mTotalTime = totaltime;
        mI = i;
        mA = a;
    }

    @Override
    public void run() {
        mStartTime = Calendar.getInstance().getTimeInMillis();
        while(!this.isInterrupted() && 
                Calendar.getInstance().getTimeInMillis() - mStartTime < mTotalTime) {

            mA.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(MarginAnimation.this.isInterrupted())
                        return;
                    long cur_time = Calendar.getInstance().getTimeInMillis();
                    float perc_done = 1.0f*(cur_time-mStartTime)/mTotalTime;

                    final int new_margin = (int)(1.0f*(mEndMargin-mStartMargin)*mI.getInterpolation(perc_done)) + mStartMargin;
                    LayoutParams p = (LayoutParams) mV.getLayoutParams();
                    Log.v(TAG, String.format("Setting Margin to %d", new_margin));
                    p.topMargin = new_margin;
                    mV.setLayoutParams(p);                  
                }
            });

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                return;
            }
        }
    }

}

该职位帮助我得到我的动画工作。就我而言,我有一个全屏幕的WebView。在一些用户操作,该web视图向右滑动,约70%和新的WebView从左边出现将可用的空间。最终的结果,新的网页视图覆盖70%(x轴)和旧web视图的其余部分。阿恩的解决方案帮助我极大,一旦动画完成设立保证金的旧观点。伪代码:

       marginParams.leftMargin = 336; //(70% of 480px)

不过,我面临着一个怪异的行为,我想我的老的WebView(现在只占30%的空间),被重新格式化的内容,可能会认为它是现榨成更小的空间,而不是表现得好像它只是向右滑动。换句话说,只要我设置保证金,web视图的HTML布局更改。同样,我不知道为什么我的的是它认为它的父窗口的大小改变。基于这种假设,我添加的一行代码:

      marginParams.rightMargin = -336; //(same amount, but negative margin!)

和实现该诀窍,没有的HTML内容的重新格式化和我可以在两个平行进行交互网页视图。

我张贴这是一个很大的谢谢阿恩为理念,也得到了我看到的行为,我为它假设的任何输入。其实我喜欢的端到端解决方案,具有逻辑意义,但我可能是错的。 。 。任何想法和输入将不胜感激。非常感谢你。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top