久久r热视频,国产午夜精品一区二区三区视频,亚洲精品自拍偷拍,欧美日韩精品二区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Android實(shí)現(xiàn)啟動(dòng)頁(yè)倒計(jì)時(shí)效果

瀏覽:5日期:2022-09-19 11:45:33

今天介紹一個(gè)很簡(jiǎn)單的倒計(jì)時(shí)動(dòng)畫(huà),仿酷狗音樂(lè)的啟動(dòng)頁(yè)倒計(jì)時(shí)效果,也是大多數(shù)APP在用的一個(gè)動(dòng)畫(huà),來(lái)看看效果圖:

Android實(shí)現(xiàn)啟動(dòng)頁(yè)倒計(jì)時(shí)效果

整體的思路就是用一個(gè)平滑的幀動(dòng)畫(huà)來(lái)畫(huà)圓弧就行了。

這篇文章學(xué)到什么?

了解屬性動(dòng)畫(huà)ValueAnimator的用法

了解動(dòng)畫(huà)屬性插值Interpolator,讓動(dòng)畫(huà)過(guò)度得更自然

如何畫(huà)圓弧

開(kāi)始準(zhǔn)備

新建一個(gè)類(lèi)繼承TextView,因?yàn)橹虚g還有跳過(guò)的文本,所以選擇用TextView來(lái)畫(huà)個(gè)動(dòng)起來(lái)的背景圖。

/** * 倒計(jì)時(shí)文本 */@SuppressLint('AppCompatCustomView')public class CountDownTextView extends TextView { // 倒計(jì)時(shí)動(dòng)畫(huà)時(shí)間 private int duration = 5000; // 動(dòng)畫(huà)掃過(guò)的角度 private int mSweepAngle = 360; // 屬性動(dòng)畫(huà) private ValueAnimator animator; // 矩形用來(lái)保存位置大小信息 private final RectF mRect = new RectF(); // 圓弧的畫(huà)筆 private Paint mBackgroundPaint; public CountDownTextView(Context context) {this(context, null); } public CountDownTextView(Context context, AttributeSet attrs) {this(context, attrs, 0); } public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(); } private void init() {// 設(shè)置畫(huà)筆平滑mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// 設(shè)置畫(huà)筆顏色mBackgroundPaint.setColor(Color.WHITE);// 設(shè)置畫(huà)筆邊框?qū)挾萴BackgroundPaint.setStrokeWidth(5);// 設(shè)置畫(huà)筆樣式為邊框類(lèi)型mBackgroundPaint.setStyle(Paint.Style.STROKE); }}開(kāi)始動(dòng)畫(huà)

原理:利用圓的360度角來(lái)做屬性動(dòng)畫(huà),讓它平滑的分配做每幀動(dòng)畫(huà)的角度值,然后調(diào)用invalidate()來(lái)重繪自己本身,從而進(jìn)入到本身的onDraw()方法來(lái)畫(huà)圖。

/** * 開(kāi)始倒計(jì)時(shí) */ public void start() {// 在動(dòng)畫(huà)中if (mSweepAngle != 360) return;// 初始化屬性動(dòng)畫(huà)animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration);// 設(shè)置插值animator.setInterpolator(new LinearInterpolator());// 設(shè)置動(dòng)畫(huà)監(jiān)聽(tīng)animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {// 獲取屬性動(dòng)畫(huà)返回的動(dòng)畫(huà)值mSweepAngle = (int) animation.getAnimatedValue();// 重繪自己invalidate(); }});// 開(kāi)始動(dòng)畫(huà)animator.start(); }畫(huà)圓弧

畫(huà)圓弧比較簡(jiǎn)單, 從效果圖來(lái)看,有的同學(xué)可能剛開(kāi)始以為要畫(huà)兩個(gè)圓,一個(gè)背景的內(nèi)圓和一個(gè)白色邊框的大圓,其實(shí)這里可以利用畫(huà)筆設(shè)置畫(huà)筆樣式paint.setStyle()和寬度大小paint.setStrokeWidth()的特性來(lái)實(shí)現(xiàn)。代碼很簡(jiǎn)單,開(kāi)始的角度選擇-90,從頭頂開(kāi)始畫(huà)。這樣實(shí)現(xiàn)的是一個(gè)順時(shí)針的倒計(jì)時(shí)效果。如果你想實(shí)現(xiàn)酷狗的逆時(shí)針效果,就控制mSweepAngle的值用mSweepAngle = 360 - mSweepAngle開(kāi)始就可以了。

@Override protected void onDraw(Canvas canvas) {int padding = dp2px(4);mRect.top = padding;mRect.left = padding;mRect.right = getWidth() - padding;mRect.bottom = getHeight() - padding;// 畫(huà)倒計(jì)時(shí)線內(nèi)圓canvas.drawArc(mRect, //弧線所使用的矩形區(qū)域大小-90, //開(kāi)始角度mSweepAngle, //掃過(guò)的角度f(wàn)alse, //是否使用中心mBackgroundPaint); // 設(shè)置畫(huà)筆super.onDraw(canvas); }

什么是插值動(dòng)畫(huà)?

為了讓動(dòng)畫(huà)過(guò)度的更加自然或者添加一些動(dòng)畫(huà)效果,比如勻速運(yùn)動(dòng)、加速運(yùn)動(dòng)、減速運(yùn)動(dòng)、彈跳運(yùn)動(dòng)等等,這些的動(dòng)畫(huà)的效果就是靠插值來(lái)實(shí)現(xiàn)的。在Android中系統(tǒng)內(nèi)置了一些插值,更加直觀的展示下面介紹的動(dòng)畫(huà)效果。

插值 說(shuō)明 LinearInterpolator 以常量速率改變 BounceInterpolator 動(dòng)畫(huà)結(jié)束的時(shí)候彈起 CycleInterpolator 動(dòng)畫(huà)循環(huán)播放特定的次數(shù),速率改變沿著正弦曲線 DecelerateInterpolator 在動(dòng)畫(huà)開(kāi)始的地方快然后慢 OvershootInterpolator 向前甩一定值后再回到原來(lái)位置 AccelerateInterpolator 在動(dòng)畫(huà)開(kāi)始的地方速率改變比較慢,然后開(kāi)始加速 AnticipateInterpolator 開(kāi)始的時(shí)候向后然后向前甩 AccelerateDecelerateInterpolator 在動(dòng)畫(huà)開(kāi)始與介紹的地方速率改變比較慢,在中間的時(shí)候加速 AnticipateOvershootInterpolator 開(kāi)始的時(shí)候向后然后向前甩一定值后返回最后的值

項(xiàng)目使用

這里要定義文本的寬高,因?yàn)闆](méi)有畫(huà)底部的黑色圓背景,還要設(shè)置一下背景圖。

<com.example.viewdemo.CountDownTextViewandroid: android:layout_width='40dp'android:layout_height='40dp'android:layout_gravity='center'android:background='@drawable/bg_count_down'android:text='跳過(guò)'android:textColor='#ffffff'android:textSize='12sp'android:visibility='visible' />背景圖

<?xml version='1.0' encoding='utf-8'?><selector xmlns:android='http://schemas.android.com/apk/res/android'> <item android:state_pressed='true'><shape android:shape='oval'> <solid android:color='#302d2d2d' /></shape> </item> <item><shape android:shape='oval'> <solid android:color='#7F2d2d2d' /></shape> </item></selector>完整代碼

/** * 倒計(jì)時(shí)文本 */@SuppressLint('AppCompatCustomView')public class CountDownTextView extends TextView { // 倒計(jì)時(shí)動(dòng)畫(huà)時(shí)間 private int duration = 5000; // 動(dòng)畫(huà)掃過(guò)的角度 private int mSweepAngle = 360; // 屬性動(dòng)畫(huà) private ValueAnimator animator; // 矩形用來(lái)保存位置大小信息 private final RectF mRect = new RectF(); // 圓弧的畫(huà)筆 private Paint mBackgroundPaint; public CountDownTextView(Context context) {this(context, null); } public CountDownTextView(Context context, AttributeSet attrs) {this(context, attrs, 0); } public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(); } @Override protected void onDraw(Canvas canvas) {int padding = 5;mRect.top = padding;mRect.left = padding;mRect.right = getWidth() - padding;mRect.bottom = getHeight() - padding;// 畫(huà)倒計(jì)時(shí)線內(nèi)圓canvas.drawArc(mRect, //弧線所使用的矩形區(qū)域大小-90, //開(kāi)始角度mSweepAngle, //掃過(guò)的角度f(wàn)alse, //是否使用中心mBackgroundPaint); // 設(shè)置畫(huà)筆start();super.onDraw(canvas); } private void init() {// 設(shè)置畫(huà)筆平滑mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// 設(shè)置畫(huà)筆顏色mBackgroundPaint.setColor(Color.WHITE);// 設(shè)置畫(huà)筆邊框?qū)挾萴BackgroundPaint.setStrokeWidth(5);// 設(shè)置畫(huà)筆樣式為邊框類(lèi)型mBackgroundPaint.setStyle(Paint.Style.STROKE); } /** * 開(kāi)始倒計(jì)時(shí) */ public void start() {// 在動(dòng)畫(huà)中if (mSweepAngle != 360) return;// 初始化屬性動(dòng)畫(huà)animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration);// 設(shè)置插值animator.setInterpolator(new LinearInterpolator());// 設(shè)置動(dòng)畫(huà)監(jiān)聽(tīng)animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {// 獲取屬性動(dòng)畫(huà)返回的動(dòng)畫(huà)值mSweepAngle = (int) animation.getAnimatedValue();// 重繪自己invalidate(); }});// 開(kāi)始動(dòng)畫(huà)animator.start(); }}

以上就是Android實(shí)現(xiàn)啟動(dòng)頁(yè)倒計(jì)時(shí)效果的詳細(xì)內(nèi)容,更多關(guān)于Android 啟動(dòng)頁(yè)倒計(jì)時(shí)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 镇雄县| 彭水| 曲松县| 牙克石市| 景泰县| 丰宁| 卢龙县| 务川| 南溪县| 罗源县| 克什克腾旗| 平远县| 资溪县| 江城| 莒南县| 图片| 遂川县| 绵阳市| 方正县| 谷城县| 乌鲁木齐县| 宝兴县| 五家渠市| 龙州县| 明水县| 昂仁县| 喀喇沁旗| 合山市| 桂阳县| 钟祥市| 福清市| 汤原县| 海伦市| 临泽县| 靖西县| 溧水县| 建水县| 大姚县| 昆山市| 若尔盖县| 东港市|