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

Implementación del efecto 'Chui-yi-chui' personalizado en Android View

Este artículo introduce cómo implementar efectos como los siguientes utilizando View personalizado y animación de atributos

La idea de implementación es bastante sencilla:

  • Dibujar un círculo semitransparente
  • Implementar dos efectos de animación: expansión al hacer clic y recuperación al no hacer clic
  • Combine los dos pasos anteriores utilizando un hilo

Primero, echemos un vistazo a la parte de dibujar el círculo semitransparente

public class ClickCircleView extends View {
 private Bitmap bitmap;
 private Paint paint;
 private Canvas canvas;
 private boolean isSpreadFlag = false;//marcar si se ha completado la emisión
 public boolean isSpreadFlag() {
  return isSpreadFlag;
 }
 public void setIsSpreadFlag(boolean isSpreadFlag) {
  this.isSpreadFlag = isSpreadFlag;
 }
 public ClickCircleView(Context context, int width, int height, int screenWidth, int screenHeight) {
  super(context);
  bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888); // Establecer el ancho y la altura del bitmap
  canvas = new Canvas();
  canvas.setBitmap(bitmap);
  paint = new Paint(Paint.DITHER_FLAG);
  paint.setAntiAlias(true);
  paint.setColor(Color.WHITE);
  paint.setStyle(Paint.Style.FILL);
  paint.setAlpha(50);
  canvas.drawCircle(screenWidth / 2, screenHeight / 2, width / 2 + 10, paint);
  invalidate();
 }
 @Override
 protected void onDraw(Canvas canvas) {
  canvas.drawBitmap(bitmap, 0, 0, null);
 }
}

Puede ver que las propiedades relacionadas se configuran en el pincel, luego se llama directamente al método drawCircle() del lienzo para dibujar un círculo semitransparente, y finalmente se llama al método invalidate() para refrescar el View
Es necesario sobrescribir el método onDraw() de la clase padre, de lo contrario el View personalizado no funcionará
Establecimos un indicador de bandera isSpreadFlag, que se utiliza para marcar si la animación de expansión se ha completado

Luego implementamos dos efectos de animación

Hacer clic para expandir la animación

<set xmlns:android="http://schemas.android.com/apk/res/android">
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleY"
  android:valueFrom="1.0"
  android:valueTo="1.8"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleX"
  android:valueFrom="1.0"
  android:valueTo="1.8"
  android:valueType="floatType" />
</set>

Es muy simple, es cambiar el valor de scale, aumentando a1.8vez

No hacer clic para expandir y recoger la animación

<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:ordering="together">
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleX"
  android:valueFrom="1.0"
  android:valueTo="1.2"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleY"
  android:valueFrom="1.0"
  android:valueTo="1.2"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleX"
  android:startOffset="10"00"
  android:valueFrom="1.2"
  android:valueTo="1.0"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleY"
  android:startOffset="10"00"
  android:valueFrom="1.2"
  android:valueTo="1.0"
  android:valueType="floatType" />
</set>

Similar a la animación anterior, el parámetro startOffset se puede usar para controlar el orden de ejecución de la Animation, por ejemplo, en Android:startOffset=""10"00" indica la configuración del retraso de la animación para este atributo1Segundos de ejecución

Luego viene la parte de ejecutar animaciones y lógica con hilos

Parte de la animación al no hacer clic

mXiuyixiuButton.post(new Runnable() {
   @Override
   public void run() {
    clickCircleView = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth()
      , mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getMeasuredWidth(),
      mXiuyixiuLayout.getMeasuredHeight());
    clickCircleView.setVisibility(View.VISIBLE);
    mXiuyixiuLayout.addView(clickCircleView);
    mXiuyixiuLayout.postInvalidate();
    // Cargar animación
    final Animator anim = AnimatorInflater.loadAnimator(CustomView1.this,
      R.animator.circle_scale_animator);
    anim.addListener(new AnimatorListenerAdapter() {
     @Override
     public void onAnimationEnd(Animator animation) {
      if (anim != null) {
       anim.start();//Ejecutar animación en bucle
      }
     }
    });
    anim.setTarget(clickCircleView);
    anim.start();
   }
  });

Después de inicializar clickCircleView, agregar este view al layout padre, luego cargar la animación y configurar su ejecución en bucle, finalmente usar postInvalidate() para actualizar el view en un hilo secundario

Parte de la animación al hacer clic

mXiuyixiuButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    clickCircleView.setVisibility(View.GONE);//Disparar el círculo de lanzamiento, ocultar el View de animación en bucle
    final ClickCircleView item = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth()
      , mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getWidth(),
      mXiuyixiuLayout.getHeight());
    Animator spreadAnim = AnimatorInflater.loadAnimator(CustomView1.this,
      R.animator.circle_spread_animator);
    spreadAnim.addListener(new AnimatorListenerAdapter() {
     @Override
     public void onAnimationEnd(Animator animation) {
      item.setIsSpreadFlag(true);//Marcar que la animación se ha completado
     }
    });
    spreadAnim.setTarget(item);
    spreadAnim.start();
    clickCircleViewList.add(item);
    mXiuyixiuLayout.addView(item);
    mXiuyixiuLayout.invalidate();
    handler.post(circleViewRunnable);
   }
  });


Ocultar la animación de no hacer clic, después de inicializar ClickCircleView, agregar este view a la lista y agregarlo al diseño padre, luego cargar la animación y agregar la marca isSpreadFlag al finalizar la animación, finalmente llamar al método invalidate() para refrescar el view y comenzar el hilo

parte del hilo

private Runnable circleViewRunnable = new Runnable() {
  public void run() {
   for (int i = 0; i < clickCircleViewList.size(); i++) {
    if (clickCircleViewList.get(i).isSpreadFlag()) {
     mXiuyixiuLayout.removeView(clickCircleViewList.get(i));
     clickCircleViewList.remove(i);
     mXiuyixiuLayout.postInvalidate();
    }
   }
   if (clickCircleViewList.size() <= 0) {
    clickCircleView.setVisibility(View.VISIBLE);
   }
   handler.postDelayed(this, 100);
  }
 };

Recorrer la lista, eliminar la vista con el marcador isSpreadFlag de la lista y el diseño padre y actualizar la vista, finalmente, si la lista está vacía, mostrar el animación al no hacer clic

Recuerde eliminar la hilera en onDestroy() por última vez

@Override
 protected void onDestroy() {
  super.onDestroy();
  handler.removeCallbacks(circleViewRunnable);
 }

Utilizar View personalizado junto con animación de atributos para lograr una alta coherencia, este método es más fluido en comparación con el uso completo de View personalizado, la mayoría de los códigos se implementan referenciando blogs de otros, pero si solo se usa sin resumir no se convertirá en conocimiento propio, por lo que se escribió este blog.

Referencia: varias ideas y métodos para implementar el efecto de 'Zhuangyixiu' en Android

Esto es todo el contenido del artículo, espero que ayude a su aprendizaje y que todos los amigos apoyen el tutorial de gritos.

Declaración: el contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga espontáneamente por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado una edición humana y no asume la responsabilidad legal correspondiente. Si encuentra contenido sospechoso de copyright, le invitamos a enviar un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @) para denunciar y proporcionar evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará