English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Movimento de View no Android3Resumo de várias maneiras

Prefácio

No desenvolvimento Android, o View sempre foi uma dor de cabeça para os desenvolvedores Android, de um lado, desejando avançar, e do outro, temendo avançar, pode-se dizer que o View do Android é a maior armadilha no caminho de avançar, pois envolve muitas coisas, como a movimentação do View que escrevemos nessa vez, além disso, inclui a transmissão de eventos de toque do View, a criação de View personalizados, que são problemas extremamente importantes e que não podem ser evitados. Mas de qualquer forma, dificuldades que não forem superadas agora serão superadas no futuro.

Antes disso, vamos entender as regras de definição do sistema de coordenadas do Android e alguns parâmetros de posição do View.

Sistema de coordenadas do Android

A posição e o tamanho do View são determinados por quatro parâmetros, ou seja, left, top, right, bottom, e esses quatro parâmetros são relativos ao View pai.

int width = right-left;
 int height = bottom-top;

Após a conclusão da layout no Activity, podemos obter essas informações de alguns métodos do View:

//Obtenção dos valores left, top, right, bottom
 int left = getLeft();
 int top = getTop();
 int right = getRight();
 int bottom = getBottom();

Além do Android 3.0 após a adição de x, y, translationX, translationY etc. (x, y) representa os valores x, y do View no canto superior esquerdo do ViewGroup. translationX, translationY são usados para deslocar um View. O padrão é que ambos sejam 0, após a chamada de setTranslationX()/após a chamada de setTranslationY() ocorre a alteração.

//Obtenção dos parâmetros x, y, translationX, translationY
 int x = getX();
 int y = getY();
 int translationX = getTranslationX();
 int translationY = getTranslationY();

PS: A chamada dos métodos setTranslationX() e setTranslationY() do View permite que o View se mova uma distância específica, mas esse processo é concluído instantaneamente. Para tornar o movimento do View mais suave, pode-se usar a animação de propriedades do View para especificar translationX e translationY.

ObjectAnimator valueAnimator = ObjectAnimator.ofFloat(textView, "translationX", 200);
 valueAnimator.setDuration(2000);
 valueAnimator.start();

Além disso, se o View for configurado com setTranslationX() e setTranslationY() e o valor configurado não mudar, ele se moverá apenas uma vez, ou seja, a distância de movimento especificada pela primeira vez. Após verificar o código-fonte, descobrimos a razão: originalmente, após a configuração, ele compara o valor configurado com o translationX e translationY atuais, e move apenas quando eles não forem idênticos.

Depois de entender alguns parâmetros básicos do View, vamos ver sobre os três métodos de movimento do View.

Um, usar scrollTo() fornecido pelo sistema Android/O método scrollBy() realiza o movimento do View.

Independentemente de scrollTo() ou scrollBy(), a essência do movimento é View/Conteúdo do ViewGroup. E seu processo de movimento é concluído instantaneamente, portanto, para implementar um efeito de movimento melhor, ele precisa ser usado em conjunto com a classe Scroller. Além disso, é diferente do Translation acima, que move o próprio View, isso precisa ser compreendido bem.

scrollTo() e scrollBy() são métodos de View, não métodos de Scroller, mas o controle do movimento suave da View está profundamente ligado à classe Scroller.

scrollTo() : se refere ao deslocamento da posição absoluta, se a posição não mudar, várias chamadas não terão efeito.

Diagrama de processo de scrollTo

scrollBy() : sua essência continua a ser a chamada scrollTo(), que se refere ao deslocamento da posição atual em uma distância relativa (cada vez que é necessário somar a posição atual e a distância configurada para chamar scrollTo(), então se você chamar várias vezes, você notará que cada vez move uma distância, isso é a diferença essencial entre scrollTo() e scrollBy()).

Diagrama de processo de scrollBy

PS:Sobre as duas figuras acima, na verdade, eu nunca entendi completamente o que é relativo e absoluto, então as duas figuras manuais podem facilitar a compreensão. Além disso, há o problema de direção de movimento de scrollTo() e scrollBy(), acima já desenhamos o sistema de coordenadas do Android, o eixo x esquerda→direita é positivo, o eixo y de cima→baixo é positivo. Mas isso não se aplica a scrollTo e scrollBy, scrollTo e scrollBy são exatamente o contrário, ou seja, o eixo x esquerda→direita é negativo, o eixo y de cima→baixo é negativo, é literalmente um pouco chato.

Análise da classe Scroller: e por que usar os métodos da classe Scroller para o View/Como mover o conteúdo do ViewGroup? Vamos tentar analisar isso.

Primeiro

criamos um objeto da classe Scroller chamado mScroller.

Depois que

Para que a View se mova para uma posição específica dentro de um período de tempo determinado, chamamos o método startScroll(), que é um método da classe Scroller. Além disso, a classe Scroller também possui um método muito usado chamado fluent(), que é usado principalmente para criar movimentos suaves, geralmente criando um efeito de inércia após o deslize, tornando o movimento da View mais realista. Vamos ver o código-fonte do startScroll() a seguir:

//ele recebe quatro/Cinco parâmetros. Se duration não for configurado, será o padrão. Esses quatro parâmetros não são difíceis de entender, então não explicaremos aqui.
 public void startScroll(int startX, int startY, int dx, int dy, int duration) { 
 ...
 }

Geralmente, após chamar esse método, precisamos chamar invalidate() do View, que pode acionar o método draw() do View. E o draw() chama computeScroll(), onde vemos que computeScroll() é um método vazio, isso é a razão pela qual precisamos sobrescrever o método computeScroll(). Porque a operação de movimentação real ocorre dentro de computeScroll().

@Override
 public void computeScroll() {
 if (mScroller.computeScrollOffset()) {
  scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
  //É necessário chamar postInvalidate() do View/invalidate(), se não for adicionado, causará que a movimentação da View ocorra apenas na primeira quadro.
  postInvalidate();
 }
 super.computeScroll();
 }

Nós vimos acima que a classe Scroller também possui um método computeScrollOffset(), mas qual é sua função? Sua principal função é determinar se mCurrX e mCurrY mudaram, retornando true se houver mudança e false se não houver. Através dessa decisão, podemos indicar se é necessário chamar continuamente scrollTo() para mover a View. Aqui está um exemplo de como usar scrollTo() para mover a View conforme o movimento do dedo:

public class CuView extends LinearLayout {
 private float mStartX;
 private float mStartY;
 private Scroller mScroller;
 /**
 * Se a primeira deslize for concluída
 */
 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);
 }
 /**
 * Deixe a View seguir o seu dedo
 * @param event
 * @return
 */
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 int action = event.getAction();
 switch (action) {
  case MotionEvent.ACTION_DOWN:
  /**
   * Após a primeira movimentação ser concluída, não precisamos mais pegar a posição inicial, senão causará a View a se mover novamente desde a posição inicial.
   */
  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:
  //A primeira movimentação foi concluída
  isFirstFinish = true;
  break;
 }
 return true;
 }
 /**
 * Teste startScroll
 */
 public void startScroll() {
 /**
  * Atenção à direção de movimento do Scroller
  */
 2 2 -500, -500, 5000);
 invalidate();
 }
 @Override
 public void computeScroll() {
 if (mScroller.computeScrollOffset()) {
  scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
  invalidate();
 }
 super.computeScroll();
 }
}

Dois, use animações para mover o View

Isso inclui a Tween Animation do View/Frame Animation, além de3A Property Animation adicionada após o .0 move uma imagem do View, a posição e o tamanho do View em si não mudaram.

Três, ajuste os LayoutParams do View para mover o View

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
 layoutParams.leftMargin = 50;
 textView.requestLayout();

Conclusão

Isso é uma conclusão do movimento do Android View3Este é o conteúdo completo de várias maneiras, espero que o conteúdo deste artigo ajude você a desenvolver Android. Se tiver alguma dúvida, você pode deixar um comentário para trocar.

Você também pode gostar