English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Einleitung
In der Android-Entwicklung ist View stets ein Dorn im Auge der Entwickler. Einerseits möchten sie sich verbessern, andererseits fürchten sie sich vor dem Fortschritt. Man kann sagen, dass das Android-View die größte Hürde auf dem Weg zur Verbesserung darstellt, da es so viele Dinge umfasst, wie z.B. die Bewegung von Views, die Übertragung von Berührungsevents und die Erstellung eigener Views, die alle äußerst wichtig und unumgänglich sind. Aber egal wie, die Schwierigkeiten, die jetzt nicht überwunden werden, werden in der Zukunft von den Schwierigkeiten überwunden werden.
Zuvor sollten wir die Regeln der Definition des Android-Koordinatensystems und einige Positionierungsparameter von View kennenlernen.
Android-Koordinatensystem
Der Ort und die Größe eines Views werden durch vier Parameter bestimmt, nämlich left, top, right, bottom, und alle vier Parameter sind relativ zu ihrem übergeordneten View.
int width = right-left; int height = bottom-top;
Nachdem das Layout in Activity abgeschlossen ist, können wir diese Parameterinformationen über einige Methoden von View abrufen:
//left, top, right, bottom Wertabfrage int left = getLeft(); int top = getTop(); int right = getRight(); int bottom = getBottom();
zusätzlich zu Android 3.0 nach dem Hinzufügen von x, y, translationX, translationY und anderen Parametern. (x, y) wird als der Wert von x, y am linken oberen Eckpunkt eines Views im ViewGroup dargestellt, translationX, translationY werden verwendet, um einen View zu verschieben. Standardmäßig sind beide 0, nach dem Aufruf von View.setTranslationX()/wird nach setTranslationY() geändert.
//x, y, translationX, translationY Parameterabfrage int x = getX(); int y = getY(); int translationX = getTranslationX(); int translationY = getTranslationY();
PS: Der Aufruf der Methoden setTranslationX() und setTranslationY() von View ermöglicht das Verschieben eines Views um eine bestimmte Distanz, dieser Prozess wird jedoch instantsich abgeschlossen. Um das Verschieben eines Views reibungslos zu gestalten, kann die Eigenschaftsanimation von View verwendet werden, um translationX und translationY zu spezifizieren.
ObjectAnimator valueAnimator = ObjectAnimator.ofFloat(textView, "translationX", 200); valueAnimator.setDuration(2000); valueAnimator.start();
Außerdem, wenn setTranslationX() und setTranslationY() für View eingestellt werden und die festgelegten Werte sich nicht ändern, bewegt sich der View nur einmal, d.h. der ersten angegebenen Bewegungsabstand. Nachdem wir den Quellcode überprüft haben, haben wir den Grund entdeckt: Nachdem der Wert eingestellt wurde, wird der eingestellte Wert und der aktuelle translationX, translationY verglichen, bewegt sich nur, wenn sie unterschiedlich sind.
Nachdem wir einige grundlegende Parameter von View verstanden haben, schauen wir uns die drei Bewegungsmethoden von View an.
1. Verwenden Sie scrollTo(), das von Android-System bereitgestellt wird/scrollBy() Methode zur Bewegung von View
Egal, ob scrollTo() oder scrollBy(), das Wesen ihrer Bewegung ist View/Inhaltsbereiche von ViewGroup. Und der Bewegungsprozess wird sofort abgeschlossen, daher muss er zusammen mit der Klasse Scroller verwendet werden, um bessere Bewegungseffekte zu erzielen. Außerdem ist es anders als oben beschrieben, es bewegt sich das View selbst, dies muss gut verstanden werden.
scrollTo() und scrollBy() sind Methoden in View und nicht in Scroller, aber die glatte Bewegung von View ist untrennbar mit der Klasse Scroller verbunden.
scrollTo() : Es bezieht sich auf die absolute Position, wenn sich die Position nicht ändert, hat wiederholtes Aufrufen keine Wirkung.
Illustration des scrollTo-Bewegungsprozesses
scrollBy() : Sein Wesen ist immer noch der Aufruf von scrollTo(), was die relative Entfernung der aktuellen Position bedeutet (jedes Mal werden der aktuelle Standort und der festgelegte Abstand zusammengefasst und scrollTo() aufgerufen, daher finden Sie, dass er jedes Mal einen bestimmten Abstand bewegt, was ein Unterschied zum Wesen von scrollTo() ist)
Illustration des scrollBy-Bewegungsprozesses
PS:Über die beiden obigen Bilder: Tatsächlich habe ich selbst nie vollständig verstanden, was relative und absolute bedeutet, daher könnten die beiden Handbilder möglicherweise leichter zu verstehen sein. Außerdem gibt es das Problem der Bewegungsrichtung von scrollTo() und scrollBy(), wir haben bereits die Android-Koordinatensysteme gezeigt, wobei die x-Achse von links nach rechts positiv und die y-Achse von oben nach unten positiv ist. Dies gilt jedoch nicht für scrollTo() und scrollBy(), die genau umgekehrt sind, d.h. die x-Achse von links nach rechts ist negativ und die y-Achse von oben nach unten ist negativ, was wirklich etwas lächerlich ist.
Analyse der Scroller-Klasse: Warum können Methoden der Scroller-Klasse den View/Wie bewegt man den Inhalt des ViewGroup? Versuchen wir, das zu analysieren.
Zunächst
Erstellen wir ein Objekt der Klasse Scroller mScroller.
Dann
Um den View in der angegebenen Zeit an die angegebene Position zu bewegen, rufen wir die Methode startScroll() auf, startScroll() ist eine Methode der Scroller-Klasse, und in der Scroller-Klasse gibt es auch eine Methode namens fluent(), die ebenfalls häufig verwendet wird. Diese Methode behandelt den glatten Bewegungsvorgang hauptsächlich, um in der Regel das Nachlaufeffekt des Glidens zu erzeugen, was den Bewegungsvorgang des Views realistischer macht. Nachfolgend sehen wir den Quellcode von startScroll():
//Es empfängt vier/Fünf Parameter. Wenn duration nicht festgelegt ist, wird der Standardwert verwendet. Diese vier Parameter sind leicht zu verstehen, daher werde ich sie hier nicht weiter erläutern. public void startScroll(int startX, int startY, int dx, int dy, int duration) { ... }
Normalerweise rufen wir diese Methode auf und rufen dann View.invalidate() auf, diese Methode kann die draw()-Methode des Views auslösen. Und draw() ruft computeScroll() auf, im Quellcode finden wir, dass computeScroll() eine leere Methode ist, daher müssen wir die Methode computeScroll() überschreiben. Da der tatsächliche Bewegungsvorgang in computeScroll() durchgeführt wird.
@Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); //Es muss View.postInvalidate() aufgerufen werden/invalidate(), ohne dies würde der View nur im ersten Frame bewegt. postInvalidate(); } super.computeScroll(); }
Wie wir oben sehen, hat die Scroller-Klasse auch eine Methode namens computeScrollOffset(), was macht diese Methode? Ihre Hauptfunktion ist es zu bestimmen, ob mCurrX und mCurrY geändert wurden, ja, dann wird true zurückgegeben, nein, dann wird false zurückgegeben. Durch die Bewertung dieser Methode kann bestimmt werden, ob scrollTo() ständig aufgerufen werden muss, um den View zu bewegen. Hier ist ein weiteres Beispiel, um den View mit scrollTo() so zu bewegen, dass er mit dem Finger geht:
public class CuView extends LinearLayout { private float mStartX; private float mStartY; private Scroller mScroller; /** * Ob die erste Berührung abgeschlossen ist */ private boolean isFirstFinish; public CuView(Context context) { super(context); init(context); } public CuView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context) { mScroller = new Scroller(context); } public CuView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public CuView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context); } /** * Lassen Sie das View Ihrem Finger folgen * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: /** * Nachdem die erste Bewegung abgeschlossen ist, benötigen wir die Startposition nicht mehr, da dies sonst den ursprünglichen Bewegungsbeginn des Views verursacht. */ if (!isFirstFinish) { mStartX = event.getRawX(); mStartY = event.getRawY(); } break; case MotionEvent.ACTION_MOVE: scrollTo((int) (mStartX - event.getRawX()), (int) (mStartY - event.getRawY()); break; case MotionEvent.ACTION_UP: //第一次移动完成 isFirstFinish = true; break; } return true; } /** * 测试 startScroll */ public void startScroll() { /** * 注意 Scroller 移动方向, */ mScroller.startScroll(20, 20, -500, -500, 5000); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } super.computeScroll(); } }
二、使用动画实现 View 的移动。
这里包括 View 的 Tween Animation/Frame Animation,以及3在 0.0 之后加入的 Property Animation。它移动的是 View 的一个映像,View 本身的位置及大小并没有发生任何改变。
三、设置 View 的 LayoutParams 来移动 View
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams(); layoutParams.leftMargin = 50; textView.requestLayout();
总结
以上就是总结 Android View 移动的3这里包含了所有种方式的全部内容,希望本文的内容对大家在开发 Android 的时候有所帮助,如果有疑问大家可以留言交流。