English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Este artigo introduz um exemplo de animação de carregamento de emulação do iQIYI para Android, o código específico é o seguinte:
Efeito visual:
Conhecimentos usados:
Se você ainda não está familiarizado com Path e ValueAnimator, recomendo que você veja esses blogs de grandes gênios: Artigos mais adequados para mim sobre como criar view personalizados, Tutorial detalhado sobre como criar view personalizados e prática, este também é um tutorial e prática, obrigado pelo seu esforço! (Espero que você possa ler com atenção e obter muitas inspirações).
Animação desmontada
O ponto difícil aqui é a cálculo das coordenadas, e eu vou explicar em detalhes a seguir:
espero que esta imagem tenha sido extraída, combinando as funções seno e cosseno, p1,p2,p3as coordenadas também são determinadas.
p1.x = -(int) ((radius / 2 * Math.tan(30 * Math.PI / 180)));
p1.y = -radius / 2;
p2.x = p1.x;
p2.y = radius / 2;
p3.x = (int) (radius / 2 / Math.sin(60 * Math.PI / 180));
p3.y = 0;
definir algumas propriedades
private static final String DEFAULT_COLOR = "#00ba9b"; private static final int DEFAULT_SIZE = 50; //tamanho padrão private static final int DRAW_CIRCLE = 10001; //marca de estado Desenhar o círculo e o triângulo Executar a animação de desenho do círculo private static final int ROTATE_TRIANGLE = 10002; //marca de estado Executar a animação de rotação do triângulo e de recuo do círculo private Context mContext; private Paint trianglePaint; //pincel do triângulo private Paint circlePaint; //pincel circular private float paintStrokeWidth = 1; // definir a largura do círculo private long duration = 800; //tempo de execução private int mWidth; //largura e altura da View private int mHeight; private Path trianglePath; //o caminho do triângulo private Path circlePath; //o caminho circular private Path dst; //o path calculado pelo pathMeasure private Point p1, p2, p3; //os três pontos do triângulo private ValueAnimator animator; //animação de propriedade principalmente para obter 0-1usar o valor para executar a animação private float mAnimatorValue = 0; //armazenar os 0 obtidos-1o valor private int mCurrentState = 0; //o estado atual private int radius = 0; //o raio do círculo private float startSegment; //a comprimento inicial do círculo desenhado private PathMeasure mMeasure; //medir o path private int triangleColor = -1; private int circleColor = -1;
definir o path
1Porque o triângulo sempre existe, primeiro desenhamos o triângulo, usando o path para desenhar, já sabemos as coordenadas dos três vértices do triângulo, desenhar o triângulo torna-se fácil.
trianglePath = new Path(); p1 = new Point(); p2 = new Point(); p3 = new Point(); trianglePath.moveTo(p1.x, p1.y); trianglePath.lineTo(p2.x, p2.y); trianglePath.lineTo(p3.x, p3.y); trianglePath.close();
Desta forma, o path do triângulo está configurado, basta chamar canvans.drawPath() para desenhar o triângulo na tela.
2. Em seguida, é desenhar a circunferência, como já mencionado, a circunferência tem um buraco, aqui também adicionamos a circunferência ao path, porque ainda precisamos calcular o comprimento da circunferência da circunferência, essas operações são ajudadas pelo path,
circlePath = new Path(); RectF circleRect = new RectF(-raio, -raio, raio, raio); circlePath.addArc(circleRect, 268, 358); // isto é da circunferência da268°começar a desenhar, desenhar258°deixar um espaço de dois graus
configurar a animação de atributos
devido ao fato de que a animação precisa de um conjunto de 0-1dos dados
aqui usamos os valores fornecidos pela animação de atributos para realizar a animação.
private void initAnimation() { TimeInterpolator timeInterpolator = new AccelerateDecelerateInterpolator(); animator = ValueAnimator.ofFloat(0, 1).setDuration(duration); animator.setInterpolator(timeInterpolator); animator.setRepeatMode(ValueAnimator.RESTART); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mAnimatorValue = (float) animation.getAnimatedValue(); //aqui vamos obter um 0-1o valor invalidate(); // aqui é feita a redesenhar } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { //Aqui ocorre a conversão de estado, executando diferentes animações switch (mCurrentState) { Aqui é o que chamamos de primeiro estado mCurrentState = ROTATE_TRIANGLE; break; case ROTATE_TRIANGLE: mCurrentState = DRAW_CIRCLE; break; default: break; } } }); }
onDraw
Analisar o método onDraw
protected void onDraw(Canvas canvas) { super.onDraw(canvas); //Mover o origem para a posição central canvas.translate(mWidth / 2, mHeight / 2); // Resetar o caminho path dst dst.reset(); //Determinar o estado atual switch (mCurrentState) { //Aqui é o primeiro estado mencionado Aqui é o que chamamos de primeiro estado //case DRAW_CIRCLE: //Esta linha é para obter a posição de início do caminho a ser cortado (dst), observando cuidadosamente a animação, o início da circunferência é uma posição que se move1/5desenhando nos extremos, essa posição é aproximadamente no centro da circunferência //, quando se chega ao ponto de início da circunferência, começa a desenhar a partir do ponto de início da circunferência, eu executei essa animação-1 do tempo é aproximadamente definido como 03da posição. A 0. startSegment = (float) (mMeasure.getLength() / 5 * ((0.3 - mAnimatorValue) > 0 ? (0.3 - mAnimatorValue) : 0)); //Aqui não há nada, é apenas para desenhar um triângulo trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawPath(trianglePath, trianglePaint); //Este método é para obter o fragmento que você deseja cortar, o primeiro parâmetro é a posição de início, o segundo parâmetro é a posição de fim, o terceiro parâmetro //O número é o caminho cortado, adicionado ao caminho (dst), note que é adicionado e não substituído, portanto, antes é necessário resetar, o quarto parâmetro é //Deseja mover o ponto de início para o ponto de início da rota atual, mantendo inalterada a rota em dst (por exemplo, se antes dst tinha um path, aqui //Definido como falso, isso garante a contiguidade de dst ao mover o ponto de início da rota adicionada após dst, mantendo assim a contiguidade) mMeasure.getSegment(startSegment, mMeasure.getLength()) * mAnimatorValue, dst, true); canvas.drawPath(dst, circlePaint); break; //Segunda animação case ROTATE_TRIANGLE: //Salve o canvas, porque vamos executar duas animações, salve o estado inicial do canvas canvas.save(); //Depois disso, execute primeiro a rotação do triângulo trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.rotate(360 * mAnimatorValue); canvas.drawPath(trianglePath, trianglePaint); //Restaurar o canvas canvas.restore(); //Depois disso, é a vez do círculo externo desaparecer, o efeito de desaparecer é o mesmo que desenhar um círculo, aqui temos um grupo de 0-1do valor que muda, precisamos apenas //Quando cortamos um pedaço, fazemos com que o ponto de partida se aproxime constantemente da comprimento total, então aparecerá o efeito de desaparecer mMeasure.getSegment(mMeasure.getLength(), * mAnimatorValue, mMeasure.getLength(), dst, true); canvas.drawPath(dst, circlePaint); break; default: break; } }
Isso é tudo o que há no artigo, esperamos que ajude na sua aprendizagem e que você apoie mais o tutorial de clamor.
Declaração: O conteúdo deste artigo foi extraído da Internet, pertence ao respectivo autor, o conteúdo foi contribuído e carregado voluntariamente pelos usuários da Internet, este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidades legais relacionadas. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#w3Declaração: O conteúdo deste artigo foi extraído da Internet, pertence ao respectivo autor, o conteúdo foi contribuído e carregado voluntariamente pelos usuários da Internet, este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidades legais relacionadas. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie um e-mail para: notice#w