以编程方式翻译查看Pre-Honeycomb

时间:2012-01-04 21:04:44

标签: android android-layout

如何在不使用动画(android.view.animation.*)的情况下以编程方式翻译任意视图?

API 11引入了setTranslationXsetTranslationYsetXsetY以及getMatrix - 所有这些都可用于完成我正在寻找的内容对于。但是,我似乎无法找到先前API级别的等效项。

android.view.animation.TranslateAnimation在其实施中使用getMatrix(早在API 4),但在此期间它是一个私有API。

有没有办法在不诉诸反思的情况下实现这一目标?

7 个答案:

答案 0 :(得分:14)

很受欢迎,因为我希望在这个问题上被证明是错误的,但是在我做一些Drag-n-Drop调查时我遇到了类似的问题。

我非常确定你在offsetTopAndBottom()offsetLeftAndRight()时仍然坚持在早期API中没有动画的情况下移动View。这里的一大缺点是这些方法实际上修改了顶部/底部/左/右值,因此如果你想回到起点,你必须做一些非常重的跟踪。

另一种选择是只使用时间非常短的TranslateAnimation并设置为fillAfter ......

其他选项需要子类化,但仍然不是很漂亮,比如翻译Canvas View。这里的问题是你还必须创建一个不剪切它的子节点的父节点,这样视图就可以在它自己的边界之外绘制。

答案 1 :(得分:11)

是的,您可以使用TranslateAnimation。将fillAfter设置为true后,即使动画结束,您的视图也会保持翻译状态。这是一个例子:

TranslateAnimation anim=new TranslateAnimation(0, 0, 20, 20);
anim.setFillAfter(true);
anim.setDuration(0);
yourView.startAnimation(anim);

答案 2 :(得分:6)

格里什卡的回答帮了我很多,工作得很完美。为了使用带有nineoldandroids的Honeycomb API为转换设置动画,我为转换值设置了FloatEvaluator,然后在Honeycomb +或TranslateAnimation方法上使用setTranslationX。这是我的代码:

public class TranslationXEvaluator extends FloatEvaluator {

private View view;

public TranslationXEvaluator(View view) {
    this.view = view;
}

@Override
public Float evaluate(float fraction, Number startValue, Number endValue) {
    float translationX = super.evaluate(fraction, startValue, endValue);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        view.setTranslationX(translationX);
    } else {
        TranslateAnimation anim = new TranslateAnimation(translationX, translationX, 0, 0);
        anim.setFillAfter(true);
        anim.setDuration(0);
        view.startAnimation(anim);
    }
    return translationX;
}

}

答案 3 :(得分:1)

我遇到了同样的问题。我能够通过操纵我想翻译的视图的layoutparams,特别是边距来实现翻译。您可以使用负值btw。

答案 4 :(得分:1)

TranslateAnimation的一个替代方法是将View子类化并在dispatchDraw上翻译Canvas。 类似的东西:

 public class TranslateView extends View {

        private float mTranslationX = 0;
        private float mTranslationY = 0;
        private boolean mWillUseSDKTranslation = true;

        @Override
        protected void dispatchDraw(final Canvas canvas) {
            if (mWillUseSDKTranslation == false) {
                // keep track of the current state
                canvas.save(Canvas.MATRIX_SAVE_FLAG);
                // translate
                canvas.translate(mTranslationX, mTranslationY);
                // draw it
                super.dispatchDraw(canvas);
                // restore to the previous state
                canvas.restore();
            } else {
                super.dispatchDraw(canvas);
            }
        }

        public void setTranslationValue(final float aTranslationX, final float aTranslationY) {
            if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
                mWillUseSDKTranslation = false;
                mTranslationX = aTranslationX;
                mTranslationY = aTranslationY;
                invalidate();
            } else {
                setTranslationX(aTranslationX);
                setTranslationY(aTranslationY);
            }
        }

    }

答案 5 :(得分:0)

答案 6 :(得分:0)

我找到的解决方法是使用以下方式设置负边距:

layoutParams.setMargins(left, top, right, bottom);
yourView.setLayoutParams(layoutParams);