English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Questo articolo introduce la creazione di una View personalizzata con animazioni di proprietà per ottenere l'effetto seguente
L'idea di implementazione è piuttosto semplice:
Prima di tutto, guardiamo la parte di disegno del cerchio semi-trasparente
public class ClickCircleView extends View { private Bitmap bitmap; private Paint paint; private Canvas canvas; private boolean isSpreadFlag = false;// Segnala se l'emissione è completata 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); // Imposta le dimensioni 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); } }
puoi vedere che le proprietà pertinenti sono impostate sulla penna, quindi si chiama direttamente il metodo drawCircle() del canvas per disegnare un cerchio trasparente, infine si chiama invalidate() per aggiornare la View
è assolutamente necessario sovrascrivere il metodo onDraw() della superclasse, altrimenti la View personalizzata non funzionerà
abbiamo impostato un flag isSpreadFlag, il cui scopo è quello di indicare se l'animazione di espansione è stata completata
quindi implementiamo due effetti di animazione
quando cliccato, l'animazione di espansione
<set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1.0" android:valueTo="1.8" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1.0" android:valueTo="1.8" android:valueType="floatType" /> </set>
è molto semplice, si tratta solo di modificare il valore di scale, aumentandolo di 1.8 volte
quando non cliccato, l'animazione di espansione e recupero
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="1.0" android:valueTo="1.2" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="1.0" android:valueTo="1.2" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:startOffset="1000" android:valueFrom="1.2" android:valueTo="1.0" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:startOffset="1000" android:valueFrom="1.2" android:valueTo="1.0" android:valueType="floatType" /> </set>
Simile all'animazione precedente, il parametro startOffset può essere utilizzato per controllare l'ordine di esecuzione dell'animazione, ad esempio in Android:startOffset=”1000” significa che l'animazione viene eseguita con un ritardo di 1 secondo
Poi è la parte in cui si eseguono animazioni e logica tramite thread
parte dell'animazione quando non si clicca
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(); // Carica l'animazione 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(); // Esegui l'animazione in modo ciclico } } }); anim.setTarget(clickCircleView); anim.start(); } });
Dopo aver inizializzato clickCircleView, aggiungi questo view alla layout padre, carica l'animazione e impostala per essere eseguita in modo ciclico, infine utilizza postInvalidate() per aggiornare il view nella thread figlia
parte dell'animazione quando si clicca
mXiuyixiuButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { clickCircleView.setVisibility(View.GONE); // Nasconde il View del cerchio di click,View dell'animazione di ciclo 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);//动画执行完成,标记一下 } }); spreadAnim.setTarget(item); spreadAnim.start(); clickCircleViewList.add(item); mXiuyixiuLayout.addView(item); mXiuyixiuLayout.invalidate(); handler.post(circleViewRunnable); } });
隐藏不点击动画,初始化好ClickCircleView后将该view加入List中并添加到父布局中,然后加载动画并在动画结束时添加isSpreadFlag标记,最后调用invalidate()方法刷新view并开启线程
线程部分
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); } };
Esegui l'iterazione sulla lista, rimuovi i view con il flag isSpreadFlag dalla lista e dal layout genitore, aggiornare la view, infine, se la lista è vuota, visualizza l'animazione non cliccata
Infine, ricorda di rimuovere il thread in onDestroy()
@Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacks(circleViewRunnable); }
L'uso di View personalizzati con animazioni di proprietà ha una alta coerenza, ma rispetto all'uso completo di View personalizzati, questo metodo è più fluido, la maggior parte del codice è basato su blog di altri, ma se si utilizza semplicemente senza sintetizzare non diventerà la tua conoscenza, quindi è nato questo blog.
Riferimento: alcuni metodi e idee per implementare支付宝咻一咻 in Android
Questo è tutto il contenuto dell'articolo, speriamo che sia utile per la tua apprendimento, e speriamo che tutti sosteniate il tutorial di urla.
Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il diritto d'autore è dell'autore originale, il contenuto è stato contribuito autonomamente dagli utenti di Internet e caricato autonomamente, il sito web non detiene i diritti di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare e fornire prove pertinenti. Una volta verificata, il sito web eliminerà immediatamente il contenuto sospetto di violazione del copyright.