Android仿水波纹流量球进度条控制器

Android仿水波纹流量球进度条控制器,第1张

概述仿水波纹流球进度条控制器,Android实现高端大气的主流特效,供大家参考,具体内容如下

仿水波纹流球进度条控制器,AndroID实现高端大气的主流特效,供大家参考,具体内容如下

效果图:

CircleVIEw

这里主要是实现中心圆以及水波特效

package com.lgl.circlevIEw;import androID.content.Context;import androID.graphics.Canvas;import androID.graphics.color;import androID.graphics.Paint;import androID.graphics.Path;import androID.graphics.RectF;import androID.os.Handler;import androID.os.Parcel;import androID.os.Parcelable;import androID.util.AttributeSet;import androID.vIEw.VIEw;import androID.Widget.Progressbar;/** * 水波圆 *  * @author lgl *  */public class CircleVIEw extends VIEw { private Context mContext; private int mScreenWIDth; private int mScreenHeight; private Paint mRingPaint; private Paint mCirclePaint; private Paint mWavePaint; private Paint linePaint; private Paint flowPaint; private Paint leftPaint; private int mRingstrokeWIDth = 15; private int mCirclestrokeWIDth = 2; private int mlinestrokeWIDth = 1; private int mCirclecolor = color.WHITE; private int mRingcolor = color.WHITE; private int mWavecolor = color.WHITE; private Handler mHandler; private long c = 0L; private boolean mStarted = false; private final float f = 0.033F; private int mAlpha = 50;// 透明度 private float mAmplitude = 10.0F; // 振幅 private float mWaterLevel = 0.5F;// 水高(0~1) private Path mPath; // 绘制文字显示在圆形中间,只是我没有设置,我觉得写在布局上也挺好的 private String flowNum = ""; private String flowleft = "还剩余"; /**  * @param context  */ public CircleVIEw(Context context) {  super(context);  // Todo auto-generated constructor stub  mContext = context;  init(mContext); } /**  * @param context  * @param attrs  */ public CircleVIEw(Context context,AttributeSet attrs) {  super(context,attrs);  // Todo auto-generated constructor stub  mContext = context;  init(mContext); } /**  * @param context  * @param attrs  * @param defStyleAttr  */ public CircleVIEw(Context context,AttributeSet attrs,int defStyleAttr) {  super(context,attrs,defStyleAttr);  // Todo auto-generated constructor stub  mContext = context;  init(mContext); } public voID setmWaterLevel(float mWaterLevel) {  this.mWaterLevel = mWaterLevel; } private voID init(Context context) {  mRingPaint = new Paint();  mRingPaint.setcolor(mRingcolor);  mRingPaint.setAlpha(50);  mRingPaint.setStyle(Paint.Style.stroke);  mRingPaint.setAntiAlias(true);  mRingPaint.setstrokeWIDth(mRingstrokeWIDth);  mCirclePaint = new Paint();  mCirclePaint.setcolor(mCirclecolor);  mCirclePaint.setStyle(Paint.Style.stroke);  mCirclePaint.setAntiAlias(true);  mCirclePaint.setstrokeWIDth(mCirclestrokeWIDth);  linePaint = new Paint();  linePaint.setcolor(mCirclecolor);  linePaint.setStyle(Paint.Style.stroke);  linePaint.setAntiAlias(true);  linePaint.setstrokeWIDth(mlinestrokeWIDth);  flowPaint = new Paint();  flowPaint.setcolor(mCirclecolor);  flowPaint.setStyle(Paint.Style.FILL);  flowPaint.setAntiAlias(true);  flowPaint.setTextSize(36);  leftPaint = new Paint();  leftPaint.setcolor(mCirclecolor);  leftPaint.setStyle(Paint.Style.FILL);  leftPaint.setAntiAlias(true);  leftPaint.setTextSize(36);  mWavePaint = new Paint();  mWavePaint.setstrokeWIDth(1.0F);  mWavePaint.setcolor(mWavecolor);  mWavePaint.setAlpha(mAlpha);  mPath = new Path();  mHandler = new Handler() {   @OverrIDe   public voID handleMessage(androID.os.Message msg) {    if (msg.what == 0) {     invalIDate();     if (mStarted) {      // 不断发消息给自己,使自己不断被重绘      mHandler.sendEmptyMessageDelayed(0,60L);     }    }   }  }; } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) {  int wIDth = measure(wIDthMeasureSpec,true);  int height = measure(heightmeasureSpec,false);  if (wIDth < height) {   setMeasuredDimension(wIDth,wIDth);  } else {   setMeasuredDimension(height,height);  } } /**  * @category 测量  * @param measureSpec  * @param isWIDth  * @return  */ private int measure(int measureSpec,boolean isWIDth) {  int result;  int mode = MeasureSpec.getMode(measureSpec);  int size = MeasureSpec.getSize(measureSpec);  int padding = isWIDth ? getpaddingleft() + getpaddingRight()    : getpaddingtop() + getpaddingBottom();  if (mode == MeasureSpec.EXACTLY) {   result = size;  } else {   result = isWIDth ? getSuggestedMinimumWIDth()     : getSuggestedMinimumHeight();   result += padding;   if (mode == MeasureSpec.AT_MOST) {    if (isWIDth) {     result = Math.max(result,size);    } else {     result = Math.min(result,size);    }   }  }  return result; } @OverrIDe protected voID onSizeChanged(int w,int h,int olDW,int oldh) {  // Todo auto-generated method stub  super.onSizeChanged(w,h,olDW,oldh);  mScreenWIDth = w;  mScreenHeight = h; } @OverrIDe protected voID onDraw(Canvas canvas) {  // Todo auto-generated method stub  super.onDraw(canvas);  // 得到控件的宽高  int wIDth = getWIDth();  int height = getHeight();  setBackgroundcolor(mContext.getResources().getcolor(R.color.main_bg));  // 计算当前油量线和水平中线的距离  float centerOffset = Math.abs(mScreenWIDth / 2 * mWaterLevel    - mScreenWIDth / 4);  // 计算油量线和与水平中线的角度  float horiAngle = (float) (Math.asin(centerOffset / (mScreenWIDth / 4)) * 180 / Math.PI);  // 扇形的起始角度和扫过角度  float startAngle,sweepAngle;  if (mWaterLevel > 0.5F) {   startAngle = 360F - horiAngle;   sweepAngle = 180F + 2 * horiAngle;  } else {   startAngle = horiAngle;   sweepAngle = 180F - 2 * horiAngle;  }  canvas.drawline(mScreenWIDth * 3 / 8,mScreenHeight * 5 / 8,mScreenWIDth * 5 / 8,linePaint);  float num = flowPaint.measureText(flowNum);  canvas.drawText(flowNum,mScreenWIDth * 4 / 8 - num / 2,mScreenHeight * 4 / 8,flowPaint);  float left = leftPaint.measureText(flowleft);  canvas.drawText(flowleft,mScreenWIDth * 4 / 8 - left / 2,mScreenHeight * 3 / 8,leftPaint);  // 如果未开始(未调用startWave方法),绘制一个扇形  if ((!mStarted) || (mScreenWIDth == 0) || (mScreenHeight == 0)) {   // 绘制,即水面静止时的高度   RectF oval = new RectF(mScreenWIDth / 4,mScreenHeight / 4,mScreenWIDth * 3 / 4,mScreenHeight * 3 / 4);   canvas.drawArc(oval,startAngle,sweepAngle,false,mWavePaint);   return;  }  // 绘制,即水面静止时的高度  // 绘制,即水面静止时的高度  RectF oval = new RectF(mScreenWIDth / 4,mScreenHeight * 3 / 4);  canvas.drawArc(oval,mWavePaint);  if (this.c >= 8388607L) {   this.c = 0L;  }  // 每次onDraw时c都会自增  c = (1L + c);  float f1 = mScreenHeight * (1.0F - (0.25F + mWaterLevel / 2))    - mAmplitude;  // 当前油量线的长度  float waveWIDth = (float) Math.sqrt(mScreenWIDth * mScreenWIDth / 16    - centerOffset * centerOffset);  // 与圆半径的偏移量  float offsetWIDth = mScreenWIDth / 4 - waveWIDth;  int top = (int) (f1 + mAmplitude);  mPath.reset();  // 起始振动X坐标,结束振动X坐标  int startX,endX;  if (mWaterLevel > 0.50F) {   startX = (int) (mScreenWIDth / 4 + offsetWIDth);   endX = (int) (mScreenWIDth / 2 + mScreenWIDth / 4 - offsetWIDth);  } else {   startX = (int) (mScreenWIDth / 4 + offsetWIDth - mAmplitude);   endX = (int) (mScreenWIDth / 2 + mScreenWIDth / 4 - offsetWIDth + mAmplitude);  }  // 波浪效果  while (startX < endX) {   int startY = (int) (f1 - mAmplitude     * Math.sin(Math.PI       * (2.0F * (startX + this.c * wIDth * this.f))       / wIDth));   canvas.drawline(startX,startY,startX,top,mWavePaint);   startX++;  }  canvas.drawCircle(mScreenWIDth / 2,mScreenHeight / 2,mScreenWIDth / 4    + mRingstrokeWIDth / 2,mRingPaint);  canvas.drawCircle(mScreenWIDth / 2,mScreenWIDth / 4,mCirclePaint);  canvas.restore(); } @OverrIDe public Parcelable onSaveInstanceState() {  Parcelable superState = super.onSaveInstanceState();  SavedState ss = new SavedState(superState);  ss.progress = (int) c;  return ss; } @OverrIDe public voID onRestoreInstanceState(Parcelable state) {  SavedState ss = (SavedState) state;  super.onRestoreInstanceState(ss.getSuperState());  c = ss.progress; } @OverrIDe protected voID onAttachedToWindow() {  super.onAttachedToWindow();  // 关闭硬件加速,防止异常unsupported operation exception  this.setLayerType(VIEw.LAYER_TYPE_SOFTWARE,null); } @OverrIDe protected voID onDetachedFromWindow() {  super.onDetachedFromWindow(); } /**  * @category 开始波动  */ public voID startWave() {  if (!mStarted) {   this.c = 0L;   mStarted = true;   this.mHandler.sendEmptyMessage(0);  } } /**  * @category 停止波动  */ public voID stopWave() {  if (mStarted) {   this.c = 0L;   mStarted = false;   this.mHandler.removeMessages(0);  } } /**  * @category 保存状态  */ static class SavedState extends BaseSavedState {  int progress;  /**   * Constructor called from {@link Progressbar#onSaveInstanceState()}   */  SavedState(Parcelable superState) {   super(superState);  }  /**   * Constructor called from {@link #CREATOR}   */  private SavedState(Parcel in) {   super(in);   progress = in.readInt();  }  @OverrIDe  public voID writetoParcel(Parcel out,int flags) {   super.writetoParcel(out,flags);   out.writeInt(progress);  }  public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {   public SavedState createFromParcel(Parcel in) {    return new SavedState(in);   }   public SavedState[] newArray(int size) {    return new SavedState[size];   }  }; }}

我们运行一下

其实他是十分的空旷的,所以也值得我们去定制,我们在中间加个流量显示,再加个进度条
activity_main.xml

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:tools="http://schemas.androID.com/tools" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@color/main_bg" > <TextVIEw  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content"  androID:layout_alignParenttop="true"  androID:layout_centerHorizontal="true"  androID:layout_margintop="10dp"  androID:text="流量"  androID:textcolor="@androID:color/white"  androID:textSize="18sp" /> <com.lgl.circlevIEw.CircleVIEw  androID:ID="@+ID/wave_vIEw"  androID:layout_wIDth="fill_parent"  androID:layout_height="fill_parent"  androID:layout_centerInParent="true" /> <TextVIEw  androID:ID="@+ID/power"  androID:layout_wIDth="wrap_content"  androID:layout_height="wrap_content"  androID:layout_centerInParent="true"  androID:textcolor="@androID:color/white" /> <Seekbar  androID:ID="@+ID/seekbar"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:layout_alignParentBottom="true"  androID:layout_marginBottom="150dp" /></relativeLayout>

我们要实现这个,就要调用它的初始化以及start方法

 mCircleVIEw = (CircleVIEw) findVIEwByID(R.ID.wave_vIEw);  // 设置多高,float,0.1-1F  mCircleVIEw.setmWaterLevel(0.1F);  // 开始执行  mCircleVIEw.startWave();别忘了activity销毁的时候把它回收哦@OverrIDe protected voID onDestroy() {  // Todo auto-generated method stub  mCircleVIEw.stopWave();  mCircleVIEw = null;  super.onDestroy(); }

我们再运行一遍

但是我们要怎么让水波纹随着进度条一起上升下降尼?,这里我们就要用到我们刚才写的Seekbar了,我们实现它的

setonSeekbarchangelistener来监听,这样我们就要复写他的三个方法,这里我们只要用到一个public voID onProgressChanged(Seekbar seekbar,int progress,boolean fromUser) {    //跟随进度条滚动    mCircleVIEw.setmWaterLevel((float) progress / 100);    }

这里,我们要这样算的,我们设置高度的单位是float,也就是从0-1F,而我们的进度是int progress,从0-100,我们就要用(float) progress / 100)并且强转来得到单位,好了,我们现在水波纹的高度就是随着我们的进度条一起变化了,我们再来运行一下

好的,这样的话,我们就只剩下一个了,就是让大小随着我们的进度条变化了,这里我们因为更新UI不能再主线程中 *** 作,所以我们需要用到我们的老伙计Handler了,但是用到handler还不够,我们的进度条数值也是在内部类里面,所以这里我们需要用到Handler来传值了,这里我们用的是Bundle,我们还是在onProgressChanged方法中 *** 作了

 //创建一个消息    Message message = new Message();    Bundle bundle = new Bundle();    //put一个int值    bundle.putInt("progress",progress);    //装载    message.setData(bundle);    //发送消息    handler.sendMessage(message);    //创建表示    message.what = 1;

消息发送过去了,我们就在前面写个Handler去接收就是了

 private Handler handler = new Handler() {  public voID handleMessage(androID.os.Message msg) {   if (msg.what == 1) {    int num = msg.getData().getInt("progress");    Log.i("num",num + "");    power.setText((float) num / 100 * max + "M/" + max + "M");   }  } };

这里的计算公式尼,是当前的数值/100得到百分比再去*最大值。我们现在可以完整的运行一下了,其实和最上面运行的图片是一样的

MainActivity

package com.lgl.circlevIEw;import androID.app.Activity;import androID.os.Bundle;import androID.os.Handler;import androID.os.Message;import androID.util.Log;import androID.Widget.Seekbar;import androID.Widget.TextVIEw;public class MainActivity extends Activity { private CircleVIEw mCircleVIEw; private Seekbar mSeekbar; private TextVIEw power; private int max = 1024; private int min = 102; private Handler handler = new Handler() { public voID handleMessage(androID.os.Message msg) {  if (msg.what == 1) {  int num = msg.getData().getInt("progress");  Log.i("num",num + "");  power.setText((float) num / 100 * max + "M/" + max + "M");  } } }; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getActionbar().hIDe(); setContentVIEw(R.layout.activity_main); power = (TextVIEw) findVIEwByID(R.ID.power); power.setText(min + "M/" + max + "M"); mCircleVIEw = (CircleVIEw) findVIEwByID(R.ID.wave_vIEw); // 设置多高,float,0.1-1F mCircleVIEw.setmWaterLevel(0.1F); // 开始执行 mCircleVIEw.startWave(); mSeekbar = (Seekbar) findVIEwByID(R.ID.seekbar); mSeekbar.setonSeekbarchangelistener(new Seekbar.OnSeekbarchangelistener() {  @OverrIDe  public voID onProgressChanged(Seekbar seekbar,boolean fromUser) {  mCircleVIEw.setmWaterLevel((float) progress / 100);  // 创建一个消息  Message message = new Message();  Bundle bundle = new Bundle();  // put一个int值  bundle.putInt("progress",progress);  // 装载  message.setData(bundle);  // 发送消息  handler.sendMessage(message);  // 创建表示  message.what = 1;  }  @OverrIDe  public voID onStartTrackingtouch(Seekbar seekbar) {  }  @OverrIDe  public voID onStopTrackingtouch(Seekbar seekbar) {  } }); } @OverrIDe protected voID onDestroy() { // Todo auto-generated method stub mCircleVIEw.stopWave(); mCircleVIEw = null; super.onDestroy(); }}

代码下载:Android仿水波纹流量球进度条

以上就是本文的全部内容,希望对大家学习AndroID软件编程有所帮助。

总结

以上是内存溢出为你收集整理的Android仿水波纹流量球进度条控制器全部内容,希望文章能够帮你解决Android仿水波纹流量球进度条控制器所遇到的程序开发问题。

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存