最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2022年02月10日 11:27:32   作者:細(xì)嗅v薔薇  
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)APP啟動(dòng)頁(yè)倒計(jì)時(shí)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Android自定義View實(shí)現(xiàn)APP啟動(dòng)頁(yè)倒計(jì)時(shí)效果,供大家參考,具體內(nèi)容如下

之前也是做過(guò)APP啟動(dòng)頁(yè)的倒計(jì)時(shí)效果,但是只有文字變化,沒(méi)有動(dòng)畫(huà)效果,這次通過(guò)使用自定義View控件來(lái)制作一個(gè)帶有動(dòng)畫(huà)效果的倒計(jì)時(shí)。

倒計(jì)時(shí)效果的基本思路如下:

Canvas提供了繪制弧形的方法,drawArc(),使用這個(gè)方法通過(guò)定時(shí)刷新計(jì)算當(dāng)前弧形的角度,就可以模擬出倒計(jì)時(shí)的動(dòng)畫(huà)效果,同時(shí)借助drawText()方法可以實(shí)現(xiàn)倒計(jì)時(shí)文字。
(1)繼承View
(2)使用canvas的drawArc()來(lái)繪制弧形,模擬動(dòng)畫(huà)效果
(3)使用canvas的drawText()來(lái)繪制倒計(jì)時(shí)文字
(4)向外部(Activity或者Fragment)提供接口,倒計(jì)時(shí)結(jié)束之后通過(guò)接口告訴外部

具體看代碼:

首先定義當(dāng)前view的寬度和高度的默認(rèn)值,并重寫(xiě)onMeasure()方法,否則在布局文件中即使使用wrap_content當(dāng)前view也會(huì)布滿(mǎn)全屏

?//當(dāng)前view高度和寬度的默認(rèn)值
?private static final int DEFAULT_WIDTH = 100;
?private static final int DEFAULT_HEIGHT = 100;

定義三個(gè)變量,分別是倒計(jì)時(shí)總長(zhǎng)度,當(dāng)前剩余倒計(jì)時(shí)長(zhǎng)度,以及剩余時(shí)間比例,根據(jù)這個(gè)比例繪制弧形劃過(guò)的角度

private int countDownTime = 5000;//倒計(jì)時(shí)的時(shí)間,默認(rèn)是5秒
private int countDownNow = 5000;//當(dāng)前的時(shí)間,默認(rèn)也是5秒
private float timeTatio = 1f;//剩余時(shí)間比例,默認(rèn)為1

定義畫(huà)筆以及向外部提供的接口

使用Android提供的倒計(jì)時(shí)類(lèi),如果不使用這個(gè)類(lèi),也可以通過(guò)thread+handler實(shí)現(xiàn),初始化這個(gè)類(lèi)需要傳入兩個(gè)參數(shù),第一個(gè)參數(shù)是倒計(jì)時(shí)總長(zhǎng)度,第二個(gè)參數(shù)是倒計(jì)時(shí)間隔,也就是每隔多長(zhǎng)時(shí)間停止一次。這個(gè)類(lèi)重寫(xiě)了兩個(gè)方法,第一個(gè)方法是倒計(jì)時(shí)暫停的時(shí)候需要執(zhí)行的操作,第二個(gè)方法是倒計(jì)時(shí)完全結(jié)束之后需要執(zhí)行的操作,在這里,我設(shè)置了每隔10ms暫停一次,計(jì)算剩余時(shí)間的比例并重新繪制整個(gè)view,倒計(jì)時(shí)完全結(jié)束后通過(guò)接口告訴外部。

private Paint paint;
? ? private ViewCountDownFinishListener viewCountDownFinishListener;
? ? //倒計(jì)時(shí),每隔100毫秒倒計(jì)時(shí)一次
? ? private CountDownTimer countDownTimer = new CountDownTimer(countDownTime,10) {
? ? ? ? @Override
? ? ? ? public void onTick(long l) {
? ? ? ? ? ? LogUtils.logI("倒計(jì)時(shí):"+l);
? ? ? ? ? ? countDownNow = (int) l;
? ? ? ? ? ? //計(jì)算比例
? ? ? ? ? ? timeTatio = (float) countDownNow / (float)countDownTime;
? ? ? ? ? ? invalidate();
? ? ? ? }

? ? ? ? @Override
? ? ? ? public void onFinish() {
? ? ? ? ? ? countDownTimer.cancel();
? ? ? ? ? ? if(viewCountDownFinishListener != null){
? ? ? ? ? ? ? ? viewCountDownFinishListener.countDownFinish();
? ? ? ? ? ? }
? ? ? ? }
? ? };

在構(gòu)造方法中調(diào)用init()方法以啟動(dòng)倒計(jì)時(shí)

private void init(){
? ? ? ? if(countDownTimer != null) {
? ? ? ? ? ? countDownTimer.start();
? ? ? ? }
? ? }
//設(shè)置倒計(jì)時(shí)完成的接口
? ? public void setViewCountDownFinishListener(ViewCountDownFinishListener viewCountDownFinishListener){
? ? ? ? this.viewCountDownFinishListener = viewCountDownFinishListener;
? ? }

重寫(xiě)onDraw()方法,根據(jù)
canvas.drawArc(float left,float top,float right,float bottom,float startAngle,float sweepAngle,boolean useCenter, Paint paint)
參數(shù)說(shuō)明:
前四個(gè)參數(shù)表明當(dāng)前的弧形所在的橢圓,只要設(shè)置橢圓寬度和高度一樣,就是一個(gè)圓了,
startAngle是開(kāi)始繪制的角度,以正右方向(X軸正方向)為0都,順時(shí)針為正度數(shù),逆時(shí)針為負(fù)度數(shù),這里我設(shè)置從-90°(也就是Y軸負(fù)方向)開(kāi)始,
sweep是指弧形劃過(guò)的角度,這里我設(shè)置的是從0開(kāi)始一直劃過(guò)360度,剛好畫(huà)一個(gè)圓,但是其實(shí)并沒(méi)有完全到360度,因?yàn)槲以O(shè)置了每隔10ms執(zhí)行一次,最后并不會(huì)完全是360度,但是非常接近,幾乎看不出來(lái)。
useCenter表示是否連接到圓心,如果連接到圓心,就是扇形,這里需要弧形,就選擇false

繪制完弧形后開(kāi)始繪制倒計(jì)時(shí)文字,這個(gè)比較簡(jiǎn)單,就是計(jì)算倒計(jì)時(shí)剩余時(shí)間就可以了,然后繪制出來(lái)。

protected void onDraw(Canvas canvas) {
? ? ? ? LogUtils.logI("onDraw()方法執(zhí)行");
? ? ? ? super.onDraw(canvas);
? ? ? ? paint = new Paint();
? ? ? ? paint.setStyle(Paint.Style.STROKE);
? ? ? ? paint.setColor(Color.BLACK);
? ? ? ? paint.setAntiAlias(true);
? ? ? ? paint.setStrokeWidth(2);
? ? ? ? paint.setAntiAlias(true);
? ? ? ? //根據(jù)比例繪制一個(gè)扇形,也就是一個(gè)圓形
? ? ? ? //當(dāng)前的弧度
? ? ? ? float currentRadian = 360 - 360 * timeTatio;


? ? ? ? canvas.drawArc(10,10,60,60,-90,currentRadian,false,paint);
? ? ? ? //繪制文字
? ? ? ? paint.reset();
? ? ? ? paint.setStyle(Paint.Style.FILL);
? ? ? ? paint.setColor(Color.parseColor("#3399ff"));
? ? ? ? paint.setAntiAlias(true);
? ? ? ? paint.setTextSize(30);
? ? ? ? canvas.drawText(String.valueOf((int) (countDownNow/1000)),27,45,paint);
? ? }

重寫(xiě)onMeasure()方法,為了將View顯示在正確的位置上。

//重寫(xiě)onMeasure方法
? ? @Override
? ? protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
? ? ? ? //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
? ? ? ? setMeasuredDimension(measureSpecHandler(widthMeasureSpec,DEFAULT_WIDTH),measureSpecHandler(heightMeasureSpec,DEFAULT_HEIGHT));
? ? }

? ? //計(jì)算高度和寬度的具體值
? ? private int measureSpecHandler(int measureSpec,int defaultSize){
? ? ? ? int result = defaultSize;
? ? ? ? int specModel = MeasureSpec.getMode(measureSpec);
? ? ? ? int specSize = MeasureSpec.getSize(measureSpec);
? ? ? ? switch(specModel){
? ? ? ? ? ? case MeasureSpec.EXACTLY:
? ? ? ? ? ? ? ? result = specSize;
? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case MeasureSpec.AT_MOST:
? ? ? ? ? ? ? ? result = Math.min(result,specSize);
? ? ? ? ? ? ? ? break;

? ? ? ? ? ? default:
? ? ? ? ? ? ? ? result = defaultSize;
? ? ? ? ? ? ? ? break;

? ? ? ? }
? ? ? ? return result;
? ? }

定義接口,向外部提供倒計(jì)時(shí)完成的通知信息

?//定義一個(gè)接口,當(dāng)?shù)褂?jì)時(shí)完成之后通知activity做出相應(yīng)改變
? ? public interface ViewCountDownFinishListener{
? ? ? ? void countDownFinish();
? ? }

在xml中直接使用:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:app="http://schemas.android.com/apk/res-auto"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? tools:context="com.fanjuan.project.wisdomclass.activity.ActivityMain">

? ? <com.fanjuan.project.wisdomclass.view.CountDownView
? ? ? ? android:id="@+id/cv_count_down"
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:layout_gravity="right"
? ? ? ? android:layout_marginRight="20dp"
? ? ? ? android:layout_marginTop="20dp" />

</FrameLayout>

在activity中使用:

?protected void initView() {
? ? ? ? countDownView = findViewById(R.id.cv_count_down);
? ? }

? ? @Override
? ? protected void initListener() {
? ? ? ? super.initListener();
? ? ? ? countDownView.setViewCountDownFinishListener(new CountDownView.ViewCountDownFinishListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void countDownFinish() {
? ? ? ? ? ? ? ? ToastUtils.toastInfo("倒計(jì)時(shí)結(jié)束");
? ? ? ? ? ? }
? ? ? ? });
? ? }

最后的效果:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

阳江市| 绵阳市| 武胜县| 启东市| 三明市| 太保市| 平定县| 永胜县| 隆子县| 仙游县| 巴彦县| 沾化县| 辽源市| 衡阳县| 磐石市| 高阳县| 纳雍县| 张家川| 巴塘县| 大足县| 汶上县| 林周县| 聂荣县| 鄯善县| 德化县| 南陵县| 锦州市| 张北县| 报价| 塔河县| 涞源县| 玉龙| 阿瓦提县| 北川| 常德市| 额济纳旗| 柳林县| 宜良县| 旌德县| 桃园市| 罗山县|