国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿水波紋流量球進度條控制器

2019-12-12 06:25:54
字體:
來源:轉載
供稿:網友

仿水波紋流球進度條控制器,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, mScreenHeight * 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 / 4,    mScreenWidth * 3 / 4, mScreenHeight * 3 / 4);  canvas.drawArc(oval, startAngle, sweepAngle, false, 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, mScreenHeight / 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, int progress,   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軟件編程有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 出国| 郴州市| 河源市| 长汀县| 瑞丽市| 马龙县| 中方县| 乳源| 鹤山市| 股票| 新营市| 信丰县| 九寨沟县| 禄劝| 深州市| 柘荣县| 德保县| 阳新县| 茌平县| 东阳市| 东丽区| 威信县| 山东| 永吉县| 阳朔县| 论坛| 出国| 巨鹿县| 马关县| 普定县| 桦川县| 油尖旺区| 昆明市| 喀喇| 普宁市| 南澳县| 安达市| 新宁县| 南漳县| 石台县| 布拖县|