欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 自定義閃屏頁廣告倒計時view效果

 更新時間:2017年05月20日 07:58:52   作者:fanxudonggreat  
這篇文章主要介紹了Android 自定義閃屏頁廣告倒計時view效果,需要的朋友可以參考下

如今APP越來越多,我們每天所使用的的軟件也越來越多,可是在我們不付費的情況下,App制造商如何實現(xiàn),實現(xiàn)收入甚至是盈利呢?答案就是在我們打開軟件所必須經(jīng)過的地方穿插廣告,當然為了顧及用戶的感受,一般都會以倒計時的形式展示給用戶,用戶可以選擇跳過.可能是因為自己的強迫癥,總想著是怎么做的,自己就嘗試了一下,分享給大家的同時,順便加深自己的理解.效果如圖:

這里寫圖片描述
這里寫圖片描述 

1.為了滿足產(chǎn)品和設(shè)計,先搞幾個自定義屬性

1)內(nèi)層背景
2)數(shù)字的顏色
3)外層圓環(huán)寬度
4)文字大小
5)外層圓環(huán)顏色
6)圓的半徑

 這里,我的外環(huán)顏色和文字顏色相同,具體的自定義屬性如下:

<declare-styleable name="AdTimePickView">
  <attr name="mSmallCircleBg" format="color"></attr>
  <attr name="mTextSize1" format="dimension"></attr>
  <attr name="mTextColor1" format="color"></attr>
  <attr name="mProgressWidth" format="dimension"></attr>
  <attr name="mRadius" format="dimension"></attr>
 </declare-styleable>

--------------------------------------------------------------------------------

2.在自定義View的構(gòu)造方法中讀取自定義屬性:

mProgressViewWidth = typedArray.getDimensionPixelSize(R.styleable.AdTimePickView_mProgressWidth, DEFAULT_PROGRESS_WIDTH);
  mRadius = typedArray.getDimensionPixelSize(R.styleable.AdTimePickView_mRadius1, DEFAULT_RADIUS);
  mSmallCircleBg = typedArray.getColor(R.styleable.AdTimePickView_mSmallCircleBg, Color.parseColor(DEFAULT_BG_COLOR));
  mTextSize = typedArray.getDimensionPixelSize(R.styleable.AdTimePickView_mTextSize1, DEFAULT_TEXT_SIZE);
  mTextColor = typedArray.getColor(R.styleable.AdTimePickView_mTextColor1, Color.parseColor(DEFAULT_TEXT_COLOR));

--------------------------------------------------------------------------------

3.重寫onMeasure()方法,

根據(jù)寬高得出半徑,為什么不適用自定義半徑呢?因為根據(jù)寬高得出的半徑才是這個View的內(nèi)切圓半徑,自定義半徑只是為了在根據(jù)寬高無法得出半徑的情況下才使用的.

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  mWidth = getViewSize(widthMeasureSpec, 0);
  mHeight = getViewSize(heightMeasureSpec, 1);
  mRadius = Math.min(mWidth, mHeight) / 2;
  setMeasuredDimension(mWidth, mHeight);
 }

    getViewSize方法如下:

 private int getViewSize(int viewMeasureSpec, int type) {
  int viewValue = 0;
  int viewSize = MeasureSpec.getSize(viewMeasureSpec);
  int viewMode = MeasureSpec.getMode(viewMeasureSpec);
  if (MeasureSpec.EXACTLY == viewMode) {
   viewValue = viewSize;
   if (type == 0) {
    mCirCleX = viewSize / 2;
   } else {
    mCircleY = viewSize / 2;
   }
  } else {
   if (type == 0) {
    mCirCleX = mRadius;
   } else {
    mCircleY = mRadius;
   }
   viewValue = 2 * (mRadius + mProgressViewWidth);
  }
  return viewValue;
 }

--------------------------------------------------------------------------------

4.onDraw方法進行繪制

1)繪制內(nèi)層圓

canvas.drawCircle(mCirCleX, mCircleY, (float) (mRadius - 1.5 * mProgressViewWidth), mPaint);

2)繪制文字,要計算好文字的位置,保持居中

 Rect textRect = getTextRect(String.valueOf(mAdTIme));
  Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
  int baseLine = (int) (mHeight / 2 + (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent);
  int x = mWidth / 2 - textRect.width() / 2;
  canvas.drawText(String.valueOf(mAdTIme), x, baseLine, mTextPaint);
//獲取繪制內(nèi)容的Rect  
private Rect getTextRect(String centerContent) {
  Rect rect = new Rect();
  mTextPaint.getTextBounds(centerContent, 0, centerContent.length(), rect);
  return rect;
 }

3)繪制外層不斷刷新的圓環(huán) 

 原理:從360度開始每隔一段時間進行圓弧繪制,角度分別為:360,359,1,0,因此需要一個輪詢器,不斷的去繪制刷新.
繪制圓弧的代碼:    

 //保存Canvans的狀態(tài),因為繪制其他地方時,Canvas坐標系不需要變化
  canvas.save();
  //將坐標系圍繞View的中心逆時針旋轉(zhuǎn)90度數(shù),為了從正上方開始繪制
  canvas.rotate(-90, mCirCleX, mCircleY);
  //計算圓弧的RectF
  RectF rectF = new RectF(mCirCleX - mRadius + mProgressViewWidth, mCirCleX - mRadius + mProgressViewWidth, mCirCleX + mRadius - mProgressViewWidth, mCirCleX + mRadius - mProgressViewWidth);
  //第四個參數(shù)表示逆時針還是順時針繪制
  canvas.drawArc(rectF, 0, -mCurrentAngle, false, mPaint);
  //恢復(fù)坐標系
  canvas.restore();

--------------------------------------------------------------------------------

5.刷新的輪詢器

1)使用RxAndroid和lambda實現(xiàn)

//interval操作符:從1開始每隔一段時間發(fā)射遞增的數(shù)
Observable.interval(1, TIME_DIFF, TimeUnit.MILLISECONDS)
    //map操作符將發(fā)射的數(shù)據(jù)轉(zhuǎn)換成我們需要的數(shù)據(jù)
    .map(value -> {
     return countAngel - value.intValue();
    })
    //限制發(fā)射的數(shù)據(jù)個數(shù),讓其停止,負責會一直發(fā)射下去
    .limit(361)
    //接收結(jié)果并處理
    .subscribe(action -> {
     if (action % 72 == 0) {
      mAdTIme = action / 72;
     }
     mCurrentAngle = action;
     AdTimePickView.this.postInvalidate();
    });

2)使用線程的方式實現(xiàn)

new Thread(new Runnable() {
   @Override
   public void run() {
    for (int i = 360; i>=0;i--){
     try {
      Thread.sleep(100);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     if (i % 72 == 0) {
      mAdTIme = i / 72;
     }
     mCurrentAngle = i;
     AdTimePickView.this.postInvalidate();
    }
   }
  }).start();

OK,這樣我們的廣告倒計時View就完成了,歡迎大家指正.

附:整個自定義View的代碼

public class AdTimePickView extends View {
private Paint mPaint;
private Paint mTextPaint;
//大圓半徑
private int mRadius = 200;
//內(nèi)層小圓背景
private int mSmallCircleBg = Color.parseColor("#66f1679b");
//小圓外層線條寬度
private int mProgressViewWidth = 10;
private float mCurrentAngle;
private static final int TIME_DIFF = 25;
//圓心坐標
private int mCirCleX;
private int mCircleY;
//測量之后View的寬高,繪制中心文字時需要用到
private int mWidth;
private int mHeight;
//中心文字的大小與樣式
private int mTextSize;
private int mTextColor;
//廣告總時間
private int mAdTIme = 5;
private Context mContext;
public AdTimePickView(Context context) {
 this(context, null);
}
public AdTimePickView(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
}
public AdTimePickView(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AdTimePickView, defStyleAttr, 0);
 mProgressViewWidth = typedArray.getDimensionPixelSize(R.styleable.AdTimePickView_mProgressWidth, 10);
 mRadius = typedArray.getDimensionPixelSize(R.styleable.AdTimePickView_mRadius1, 100);
 mSmallCircleBg = typedArray.getColor(R.styleable.AdTimePickView_mSmallCircleBg, Color.parseColor("#66f1679b"));
 mTextSize = typedArray.getDimensionPixelSize(R.styleable.AdTimePickView_mTextSize1, 20);
 mTextColor = typedArray.getColor(R.styleable.AdTimePickView_mTextColor1, Color.parseColor("#333333"));
 //注意資源的回收
 typedArray.recycle();
 this.mContext = context;
 init();
}
private void init() {
 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setAntiAlias(true);
 mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mTextPaint.setColor(mTextColor);
 mTextPaint.setTextSize(mTextSize);
 mTextPaint.setStyle(Paint.Style.FILL);
 mTextPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 mWidth = getViewSize(widthMeasureSpec, 0);
 mHeight = getViewSize(heightMeasureSpec, 1);
 //大半徑
 mRadius = Math.min(mWidth, mHeight) / 2;
 setMeasuredDimension(mWidth, mHeight);
}
private int getViewSize(int viewMeasureSpec, int type) {
 int viewValue = 0;
 int viewSize = MeasureSpec.getSize(viewMeasureSpec);
 int viewMode = MeasureSpec.getMode(viewMeasureSpec);
 if (MeasureSpec.EXACTLY == viewMode) {
  viewValue = viewSize;
  if (type == 0) {
   mCirCleX = viewSize / 2;
  } else {
   mCircleY = viewSize / 2;
  }
 } else {
  if (type == 0) {
   mCirCleX = mRadius;
  } else {
   mCircleY = mRadius;
  }
  viewValue = 2 * (mRadius + mProgressViewWidth);
 }
 return viewValue;
}
@Override
protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 mPaint.setColor(mSmallCircleBg);
 mPaint.setStyle(Paint.Style.FILL);
 canvas.drawCircle(mCirCleX, mCircleY, (float) (mRadius - 1.5 * mProgressViewWidth), mPaint);
 //設(shè)置畫筆狀態(tài)
 mPaint.setColor(mTextColor);
 mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setStrokeWidth(mProgressViewWidth);
 //保存Canvans的狀態(tài)
 canvas.save();
 //將坐標系圍繞View的中心逆時針旋轉(zhuǎn)90度數(shù)
 canvas.rotate(-90, mCirCleX, mCircleY);
 RectF rectF = new RectF(mCirCleX - mRadius + mProgressViewWidth, mCirCleX - mRadius + mProgressViewWidth, mCirCleX + mRadius - mProgressViewWidth, mCirCleX + mRadius - mProgressViewWidth);
 //第四個參數(shù)表示逆時針還是順時針繪制
 canvas.drawArc(rectF, 0, -mCurrentAngle, false, mPaint);
 canvas.restore();
 Rect textRect = getTextRect(String.valueOf(mAdTIme));
 Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
 int baseLine = (int) (mHeight / 2 + (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent);
 int x = mWidth / 2 - textRect.width() / 2;
 canvas.drawText(String.valueOf(mAdTIme), x, baseLine, mTextPaint);
}
private Rect getTextRect(String centerContent) {
 Rect rect = new Rect();
 mTextPaint.getTextBounds(centerContent, 0, centerContent.length(), rect);
 return rect;
}
public void refresh() {
 final int countAngel = 360;
 Observable.interval(1, TIME_DIFF, TimeUnit.MILLISECONDS)
   .map(value -> {
    return countAngel - value.intValue();
   })
   .limit(361)
   .subscribe(action -> {
    if (action % 72 == 0) {
     mAdTIme = action / 72;
    }
    mCurrentAngle = action;
    AdTimePickView.this.postInvalidate();
   });
}
}

以上所述是小編給大家介紹的Android 自定義閃屏頁廣告倒計時view效果,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復(fù)大家的,在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Android實現(xiàn)動態(tài)高斯模糊效果

    Android實現(xiàn)動態(tài)高斯模糊效果

    在Android開發(fā)中常常會用到高斯模糊,但有的時候我們可能會需要一個圖片以不同的模糊程度展現(xiàn)出來,那如何實現(xiàn)呢,一起通過本文來學習學習吧。
    2016-08-08
  • Android編程實現(xiàn)顯示在標題上的進度條功能【附源碼下載】

    Android編程實現(xiàn)顯示在標題上的進度條功能【附源碼下載】

    這篇文章主要介紹了Android編程實現(xiàn)顯示在標題上的進度條功能,涉及Android界面布局及相關(guān)組件屬性設(shè)置技巧,并附帶完整實例源碼供讀者下載參考,需要的朋友可以參考下
    2018-01-01
  • Android6.0指紋識別開發(fā)實例詳解

    Android6.0指紋識別開發(fā)實例詳解

    這篇文章主要介紹了Android6.0指紋識別開發(fā)實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Android DrawLayout結(jié)合ListView用法實例

    Android DrawLayout結(jié)合ListView用法實例

    這篇文章主要介紹了Android DrawLayout結(jié)合ListView用法實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Android實現(xiàn)引導頁的圓點指示器

    Android實現(xiàn)引導頁的圓點指示器

    這篇文章主要為大家詳細介紹了Android實現(xiàn)引導頁的圓點指示器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Android 超詳細深刨Activity Result API的使用

    Android 超詳細深刨Activity Result API的使用

    這篇文章主要介紹了Android開發(fā)中Activity Result API的使用,掌握了它以后你就可以放棄startActivityForResult了,感興趣的朋友一起來看看吧
    2022-03-03
  • Flutter?GridView顯示隨機單詞效果

    Flutter?GridView顯示隨機單詞效果

    這篇文章主要為大家詳細介紹了Flutter?GridView顯示隨機單詞效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Android實現(xiàn)原生鎖屏頁面音樂控制

    Android實現(xiàn)原生鎖屏頁面音樂控制

    這篇文章主要介紹了Android實現(xiàn)原生鎖屏頁面音樂控制,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Android判斷應(yīng)用程序退到后臺的方法(示例代碼)

    Android判斷應(yīng)用程序退到后臺的方法(示例代碼)

    判斷手機是否退到后臺,這是我們在Android開發(fā)中實現(xiàn)一些功能時,經(jīng)常會考慮的問題,這篇文章主要介紹了android判斷應(yīng)用程序退到后臺的方法,需要的朋友可以參考下
    2023-03-03
  • Android 自動完成文本框的實例

    Android 自動完成文本框的實例

    下面小編就為大家分享一篇Android 自動完成文本框的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01

最新評論