Android 自定义闪屏页广告倒计时view效果

Android 自定义闪屏页广告倒计时view效果,第1张

概述如今APP越来越多,我们每天所使用的的软件也越来越多,可是在我们不付费的情况下,App制造商如何实现,实现收入甚至是盈利呢?答案就是在我们打开软件所必须经过的地方穿插广告,当然为了顾及用户的感受,一般都会以倒计

如今APP越来越多,我们每天所使用的的软件也越来越多,可是在我们不付费的情况下,App制造商如何实现,实现收入甚至是盈利呢?答案就是在我们打开软件所必须经过的地方穿插广告,当然为了顾及用户的感受,一般都会以倒计时的形式展示给用户,用户可以选择跳过.可能是因为自己的强迫症,总想着是怎么做的,自己就尝试了一下,分享给大家的同时,顺便加深自己的理解.效果如图:


 

1.为了满足产品和设计,先搞几个自定义属性

1)内层背景
2)数字的颜色
3)外层圆环宽度
4)文字大小
5)外层圆环颜色
6)圆的半径

 这里,我的外环颜色和文字颜色相同,具体的自定义属性如下:

<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的构造方法中读取自定义属性:

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()方法,

根据宽高得出半径,为什么不适用自定义半径呢?因为根据宽高得出的半径才是这个VIEw的内切圆半径,自定义半径只是为了在根据宽高无法得出半径的情况下才使用的.

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)绘制内层圆

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);//获取绘制内容的Rect  private Rect getTextRect(String centerContent) {  Rect rect = new Rect();  mTextPaint.getTextBounds(centerContent,centerContent.length(),rect);  return rect; }

3)绘制外层不断刷新的圆环 

 原理:从360度开始每隔一段时间进行圆弧绘制,角度分别为:360,359,1,因此需要一个轮询器,不断的去绘制刷新.
绘制圆弧的代码:    

 //保存Canvans的状态,因为绘制其他地方时,Canvas坐标系不需要变化  canvas.save();  //将坐标系围绕VIEw的中心逆时针旋转90度数,为了从正上方开始绘制  canvas.rotate(-90,mCirCleX,mCircleY);  //计算圆弧的RectF  RectF rectF = new RectF(mCirCleX - mRadius + mProgressVIEwWIDth,mCirCleX - mRadius + mProgressVIEwWIDth,mCirCleX + mRadius - mProgressVIEwWIDth,mCirCleX + mRadius - mProgressVIEwWIDth);  //第四个参数表示逆时针还是顺时针绘制  canvas.drawArc(rectF,-mCurrentAngle,false,mPaint);  //恢复坐标系  canvas.restore();

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

5.刷新的轮询器

1)使用RxAndroID和lambda实现

//interval *** 作符:从1开始每隔一段时间发射递增的数Observable.interval(1,TIME_DIFF,TimeUnit.MILliSECONDS)    //map *** 作符将发射的数据转换成我们需要的数据    .map(value -> {     return countAngel - value.intValue();    })    //限制发射的数据个数,让其停止,负责会一直发射下去    .limit(361)    //接收结果并处理    .subscribe(action -> {     if (action % 72 == 0) {      mAdTIme = action / 72;     }     mCurrentAngle = action;     AdTimePickVIEw.this.postInvalIDate();    });

2)使用线程的方式实现

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;//内层小圆背景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,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);}@OverrIDeprotected 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;}@OverrIDeprotected voID onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setcolor(mSmallCircleBg); mPaint.setStyle(Paint.Style.FILL); canvas.drawCircle(mCirCleX,mPaint); //设置画笔状态 mPaint.setcolor(mTextcolor); mPaint.setStyle(Paint.Style.stroke); mPaint.setstrokeWIDth(mProgressVIEwWIDth); //保存Canvans的状态 canvas.save(); //将坐标系围绕VIEw的中心逆时针旋转90度数 canvas.rotate(-90,mCircleY); RectF rectF = new RectF(mCirCleX - mRadius + mProgressVIEwWIDth,mCirCleX + mRadius - mProgressVIEwWIDth); //第四个参数表示逆时针还是顺时针绘制 canvas.drawArc(rectF,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),mTextPaint);}private Rect getTextRect(String centerContent) { Rect rect = new Rect(); mTextPaint.getTextBounds(centerContent,rect); return rect;}public voID refresh() { final int countAngel = 360; Observable.interval(1,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效果,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的,在此也非常感谢大家对编程小技巧网站的支持!

总结

以上是内存溢出为你收集整理的Android 自定义闪屏页广告倒计时view效果全部内容,希望文章能够帮你解决Android 自定义闪屏页广告倒计时view效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1146213.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存