如何在不使用动画(android.view.animation.*
)的情况下以编程方式转换任意视图?
API 11引入了setTranslationX
和setTranslationY
、setX
和setY
以及getMatrix
;所有这些都可以用来完成我想要的。然而,我似乎在以前的API级别上找不到对等的。
android.view.animation.TranslateAnimation
在其实现中使用getMatrix
(早在API 4),但在这段时间内,它一直是私有的API。
有没有办法做到这一点而不需要反思?
很受欢迎,因为我很想在这件事上被证明是错的,但不久前我在做一些拖放调查时遇到了类似的问题。
我敢肯定,您会被offsetTopAndBottom()
和offsetLeftAndRight()
所困扰,因为它们在早期的API中移动View
时没有动画。这里最大的缺点是,这些方法实际上会修改上/下/左/右值,所以如果你想回到起点,就必须进行一些相当繁重的跟踪。
另一种选择是简单地使用持续时间非常短的TranslateAnimation
并设置为fillAfter
。。。
其他选项需要子类化,但仍然不漂亮,比如转换View
所绘制的Canvas
。这里的问题是,你还必须创建一个不剪裁其子对象的父对象,这样视图就可以在自己的边界之外绘制。
是的,您可以使用TranslateAnimation。将fillAfter设置为true后,即使动画结束,视图也将保持平移状态。这里有一个例子:
TranslateAnimation anim=new TranslateAnimation(0, 0, 20, 20);
anim.setFillAfter(true);
anim.setDuration(0);
yourView.startAnimation(anim);
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;
}
}
我也遇到了同样的问题。我能够通过操纵我想要翻译的视图的布局参数,特别是页边空白来实现翻译。您可以对边距使用负值。
TranslateAnimation的一个替代方案是在dispatchDraw上为View子类化并翻译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);
}
}
}
您也可以尝试以下代码:https://github.com/BeyondAR/beyondar/blob/development/android/BeyondAR_Framework/src/com/beyondar/android/view/CustomLayout.java
使用方法setPosition。
我发现的一个解决方法是使用设置负边距
layoutParams.setMargins(left, top, right, bottom);
yourView.setLayoutParams(layoutParams);