如何在不使用动画(android.view.animation.*
)的情况下以编程方式翻译任意视图?
API 11引入了setTranslationX
和setTranslationY
,setX
和setY
以及getMatrix
- 所有这些都可用于完成我正在寻找的内容对于。但是,我似乎无法找到先前API级别的等效项。
android.view.animation.TranslateAnimation
在其实施中使用getMatrix
(早在API 4),但在此期间它是一个私有API。
有没有办法在不诉诸反思的情况下实现这一目标?
答案 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)
使用方法setPosition。
答案 6 :(得分:0)
我找到的解决方法是使用以下方式设置负边距:
layoutParams.setMargins(left, top, right, bottom);
yourView.setLayoutParams(layoutParams);