Программный перевод Просмотр Pre-Honeycomb
Как я могу программно перевести произвольное представление без использования анимации (android.view.animation.*
)?
API 11 представил setTranslationX
и setTranslationY
, setX
и setY
, и getMatrix
— все это можно использовать для выполнения того, что я ищу. Однако я не могу найти эквивалент на предыдущих уровнях API.
android.view.animation.TranslateAnimation
использует getMatrix
в своей реализации (еще в API 4), но в течение этого времени он был частным API.
Есть ли способ сделать это, не прибегая к размышлениям?
Ответы
Ответ 1
В фаворитах, потому что я хотел бы быть доказанным неправильно на этом, но я столкнулся с подобной стеной, когда несколько раз перескакивал назад.
Я уверен, что вы застряли с offsetTopAndBottom()
и offsetLeftAndRight()
для перемещения View
вокруг без анимации в ранних API. Большой недостаток заключается в том, что эти методы фактически изменяют значения top/bottom/left/right, поэтому вам нужно сделать довольно тяжелое отслеживание, если вы хотите вернуться туда, откуда вы начали.
Другим вариантом было бы просто использовать TranslateAnimation
с ОЧЕНЬ короткой продолжительностью и установить на fillAfter
...
Другие параметры требуют подклассификации и все еще не очень хороши, например, при переводе Canvas
View
. Проблема здесь заключается в том, что вы также должны создать родителя, который не зациклирует его на детей, чтобы представление могло рисовать вне его собственных границ.
Ответ 2
Да, вы можете использовать TranslateAnimation. С fillAfter, установленным в true, ваш вид останется переведенным даже после окончания анимации. Вот пример:
TranslateAnimation anim=new TranslateAnimation(0, 0, 20, 20);
anim.setFillAfter(true);
anim.setDuration(0);
yourView.startAnimation(anim);
Ответ 3
Ответ Гришки мне очень помог, отлично работает. Чтобы анимировать перевод с использованием API Honeycomb с помощью девятидюймородов, я установил FloatEvaluator для значения перевода, а затем использовал либо setTranslationX на Honeycomb +, либо метод TranslateAnimation. Вот мой код:
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;
}
}
Ответ 4
У меня была такая же проблема. Мне удалось добиться перевода, манипулируя макетами, в частности полями, взглядов, которые я хотел перевести. Вы можете использовать отрицательные значения для полей btw.
Ответ 5
Одной из альтернатив TranslateAnimation является подкласс View и перевод Canvas на dispatchDraw.
Что-то вроде:
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);
}
}
}
Ответ 6
Вы также можете попробовать этот код: https://github.com/BeyondAR/beyondar/blob/development/android/BeyondAR_Framework/src/com/beyondar/android/view/CustomLayout.java
Используйте метод setPosition.
Ответ 7
Обходной путь, который я нашел, заключался в том, чтобы установить отрицательные поля, используя:
layoutParams.setMargins(left, top, right, bottom);
yourView.setLayoutParams(layoutParams);