時間管理的基礎是精力管理,精力的高低、正負分影響到咱們的效率java
而時間是沒法管理的,可以管理的只有本身,透過管理本身的習慣,管理本身的事件來達成對時間的管理。android
而在每一天中,人生不豐於作多少事,而在於把重要的事情專一作、用心作,把它作到極致。canvas
private void init(Context context) { //繪製圓形的 Paint mCicrlPaint = new Paint(); mCicrlPaint.setAntiAlias(true); mCicrlPaint.setColor(Color.BLUE); //繪製進度的 Paint mProgressPaint = new Paint(); mProgressPaint.setAntiAlias(true); mProgressPaint.setColor(Color.RED); //設置只繪製重疊的部分 mProgressPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); //繪製文字的 Paint mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setColor(Color.WHITE); mTextPaint.setTextSize(20); //繪製進度的Path mPath = new Path(); /** * 手勢識別監聽 */ final GestureDetector gestureDetector = new GestureDetector(listener); /** * 將觸摸識別事件傳遞給 GestureDetector */ this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return gestureDetector.onTouchEvent(event); } }); this.setClickable(true); //設置佈局加載監聽 this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //更新控件的大小 viewHeight = ProgressView.this.getHeight(); viewWidth = ProgressView.this.getWidth(); //建立 bitmap 與 canvas bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(bitmap); /** * 更新默認設置 */ updateDefaulBuildValue(); } }); } GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { /** * 單擊點擊監聽 * @param e * @return */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { System.out.println("sing click "); if (clickListener != null) { clickListener.onSingleClick(e); return true; } return super.onSingleTapConfirmed(e); } /** * 雙擊點擊監聽 * @param e * @return */ @Override public boolean onDoubleTap(MotionEvent e) { if (clickListener != null) { clickListener.onDoubleClick(e); } return super.onDoubleTap(e); } /** * 常按事件監聽 * @param e */ @Override public void onLongPress(MotionEvent e) { if (clickListener != null) { clickListener.onLongPressClick(e); } super.onLongPress(e); } };
同時設置了點擊事件的監聽接口回調app
/** * 控件 點擊事件監聽 回調 */ public interface OnWaveProgressClickListener { /** * 單擊回調接口 * @param e */ public void onSingleClick(MotionEvent e); /** * 雙擊回調接口 * @param e */ public void onDoubleClick(MotionEvent e); /** * 找按回調接口 * @param e */ public void onLongPressClick(MotionEvent e); } private OnWaveProgressClickListener clickListener; /** * 設置控件的點擊事件 * * @param listener */ public void setWaveOnClickListener(OnWaveProgressClickListener listener) { this.clickListener = listener; }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); /** * 繪製的爲正方形進度條,測量比較較小的長度爲圓形的直徑長度 */ int width; int height; width = Math.min(widthSize, heightSize); height = Math.min(widthSize, heightSize); setMeasuredDimension(width, height); }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //繪製總體圓形 mCanvas.drawCircle(viewWidth / 2, viewWidth / 2, viewWidth / 2, mCicrlPaint); //繪製進度圖形 mPath.reset(); //進度圖形的高度 隨着加載進度的改變 float y = (1 - (float) currentProgress / maxProgress) * viewHeight; mPath.moveTo(viewWidth, y); mPath.lineTo(viewWidth, viewHeight); mPath.lineTo(0, viewHeight); mPath.lineTo(0, y); // /** * 計算振幅的比例 * 振幅 的大小 是隨着進度的大小動態改變的 */ int amplitude = (int) ((1 - (float) currentProgress / maxProgress) * mDefaulAmplitude); if (currentProgress % 2 == 0) { for (int i = 0; i < mquadLineDrawCount; i++) { mPath.rQuadTo(mDefaulPriodic / 2, -amplitude, mDefaulPriodic, 0); mPath.rQuadTo(mDefaulPriodic / 2, amplitude, mDefaulPriodic, 0); } } else { for (int i = 0; i < mquadLineDrawCount; i++) { mPath.rQuadTo(mDefaulPriodic / 2, amplitude, mDefaulPriodic, 0); mPath.rQuadTo(mDefaulPriodic / 2, -amplitude, mDefaulPriodic, 0); } } mPath.close(); mCanvas.drawPath(mPath, mProgressPaint); // //繪製 中間顯示的百分比文字 String text = "" + (int) (((float) currentProgress / maxProgress) * 100); //獲取繪製文字的寬度 float textWidth = mTextPaint.measureText(text); //獲取繪製文字的高度 Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); //Descent是baseline之下至字符最低處的距離 //Ascent是baseline之上至字符最高處的距離 //ascent + descent 就是測量文字的高度 float textHeight = fontMetrics.ascent + fontMetrics.descent; //計算繪製中間顯示進度文字的座標 float textY = viewHeight / 2 - textHeight / 2; float textX = viewWidth / 2 - textWidth / 2; //繪製顯示進度的文字 mCanvas.drawText(text, textX, textY, mTextPaint); canvas.drawBitmap(bitmap, 0, 0, null); }
繪製分析ide
曲線分析 一佈局
曲線分析 二post
曲線分析三ui
繪製:this
/** * 計算振幅的比例 * 振幅 的大小 是隨着進度的大小動態改變的 */ int amplitude = (int) ((1 - (float) currentProgress / maxProgress) * mDefaulAmplitude); if (currentProgress % 2 == 0) { for (int i = 0; i < mquadLineDrawCount; i++) { mPath.rQuadTo(mDefaulPriodic / 2, -amplitude, mDefaulPriodic, 0); mPath.rQuadTo(mDefaulPriodic / 2, amplitude, mDefaulPriodic, 0); } } else { for (int i = 0; i < mquadLineDrawCount; i++) { mPath.rQuadTo(mDefaulPriodic / 2, amplitude, mDefaulPriodic, 0); mPath.rQuadTo(mDefaulPriodic / 2, -amplitude, mDefaulPriodic, 0); } }
效果 spa
上面的圖形中繪製了四組正反曲線,也就是說分別繪製了四個開口向上的曲線,四個開口向下的曲線,
這裏採用的繪製思想是每一次都 繪製一個開口向上的曲線 和一個開口向下的曲線,而後造成一個完整的相似正弦曲線的線形,這裏繪製了四次,也就是在FOR循環中循環了四次,具體的循環次數是不定的,依據控件的大小來動態設置
//獲取繪製文字的寬度 float textWidth = mTextPaint.measureText(text); //獲取繪製文字的高度 Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); //Descent是baseline之下至字符最低處的距離 //Ascent是baseline之上至字符最高處的距離 //ascent + descent 就是測量文字的高度 float textHeight = fontMetrics.ascent + fontMetrics.descent; //計算繪製中間顯示進度文字的座標 float textY = viewHeight / 2 - textHeight / 2; float textX = viewWidth / 2 - textWidth / 2; //繪製顯示進度的文字 mCanvas.drawText(text, textX, textY, mTextPaint);
其中涉及到一些文本測量
六、完整源碼
package com.animation.androidlongs.a360animationapplication.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; /** * Created by androidlongs on 16/8/9. */ public class WaveProgressView extends View { private Paint mCicrlPaint; private Paint mProgressPaint; private Paint mTextPaint; private Canvas mCanvas; private Path mPath; private Bitmap bitmap; public WaveProgressView(Context context) { super(context); init(context); } public WaveProgressView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public WaveProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { //繪製圓形的 Paint mCicrlPaint = new Paint(); mCicrlPaint.setAntiAlias(true); mCicrlPaint.setColor(Color.BLUE); //繪製進度的 Paint mProgressPaint = new Paint(); mProgressPaint.setAntiAlias(true); mProgressPaint.setColor(Color.RED); //設置只繪製重疊的部分 mProgressPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); //繪製文字的 Paint mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setColor(Color.WHITE); mTextPaint.setTextSize(20); //繪製進度的Path mPath = new Path(); /** * 手勢識別監聽 */ final GestureDetector gestureDetector = new GestureDetector(listener); /** * 將觸摸識別事件傳遞給 GestureDetector */ this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return gestureDetector.onTouchEvent(event); } }); this.setClickable(true); //設置佈局加載監聽 this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //更新控件的大小 viewHeight = WaveProgressView.this.getHeight(); viewWidth = WaveProgressView.this.getWidth(); //建立 bitmap 與 canvas bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(bitmap); /** * 更新默認設置 */ updateDefaulBuildValue(); } }); } GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { /** * 單擊點擊監聽 * @param e * @return */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { System.out.println("sing click "); if (clickListener != null) { clickListener.onSingleClick(e); return true; } return super.onSingleTapConfirmed(e); } /** * 雙擊點擊監聽 * @param e * @return */ @Override public boolean onDoubleTap(MotionEvent e) { if (clickListener != null) { clickListener.onDoubleClick(e); } return super.onDoubleTap(e); } /** * 常按事件監聽 * @param e */ @Override public void onLongPress(MotionEvent e) { if (clickListener != null) { clickListener.onLongPressClick(e); } super.onLongPress(e); } }; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); /** * 繪製的爲正方形進度條,測量比較較小的長度爲圓形的直徑長度 */ int width; int height; width = Math.min(widthSize, heightSize); height = Math.min(widthSize, heightSize); setMeasuredDimension(width, height); } /** * 默認控件的 寬 高 * 默認的 當前的進度 總的進度 */ public int viewWidth = 150; public int viewHeight = 150; public int currentProgress = 0; public int maxProgress = 100; /** * 計算振幅大小 所用的比例數 默認爲10 */ private int mAplitudeCunt = 10; /** * 默認振幅的大小 爲控件高度的 1/10 */ private int mDefaulAmplitude = viewHeight / mAplitudeCunt; /** * 計算週期長度使用的比例數 默認爲8 */ private int mPriodicCount = 8; /** * 曲線默認的週期長度 */ private int mDefaulPriodic = viewHeight / mPriodicCount; /** * 曲線的繪製次數 */ private int mquadLineDrawCount = (int) ((float) viewWidth / mDefaulPriodic); /** * 更新默認的設置 */ private void updateDefaulBuildValue() { if (viewHeight < 400) { mPriodicCount = 8; mAplitudeCunt = 10; } else if (viewHeight < 600 && viewHeight >= 400) { mPriodicCount = 14; mAplitudeCunt = 16; } else if (viewHeight < 1000 && viewHeight >= 600) { mPriodicCount = 20; mAplitudeCunt = 20; } else if (viewHeight < 1400 && viewHeight >= 100) { mAplitudeCunt = 24; mPriodicCount = 26; } else { mPriodicCount = 30; mAplitudeCunt = 30; } /** * 默認振幅的大小 爲控件高度的 1/10 */ mDefaulAmplitude = viewHeight / mAplitudeCunt; /** * 曲線默認的週期長度 */ mDefaulPriodic = viewHeight / 8; /** * 曲線的繪製次數 */ mquadLineDrawCount = (int) ((float) viewWidth / mDefaulPriodic); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //繪製總體圓形 mCanvas.drawCircle(viewWidth / 2, viewWidth / 2, viewWidth / 2, mCicrlPaint); //繪製進度圖形 mPath.reset(); //進度圖形的高度 隨着加載進度的改變 float y = (1 - (float) currentProgress / maxProgress) * viewHeight; mPath.moveTo(viewWidth, y); mPath.lineTo(viewWidth, viewHeight); mPath.lineTo(0, viewHeight); mPath.lineTo(0, y); // /** * 計算振幅的比例 * 振幅 的大小 是隨着進度的大小動態改變的 */ int amplitude = (int) ((1 - (float) currentProgress / maxProgress) * mDefaulAmplitude); if (currentProgress % 2 == 0) { for (int i = 0; i < mquadLineDrawCount; i++) { mPath.rQuadTo(mDefaulPriodic / 2, -amplitude, mDefaulPriodic, 0); mPath.rQuadTo(mDefaulPriodic / 2, amplitude, mDefaulPriodic, 0); } } else { for (int i = 0; i < mquadLineDrawCount; i++) { mPath.rQuadTo(mDefaulPriodic / 2, amplitude, mDefaulPriodic, 0); mPath.rQuadTo(mDefaulPriodic / 2, -amplitude, mDefaulPriodic, 0); } } mPath.close(); mCanvas.drawPath(mPath, mProgressPaint); // //繪製 中間顯示的百分比文字 String text = "" + (int) (((float) currentProgress / maxProgress) * 100); //獲取繪製文字的寬度 float textWidth = mTextPaint.measureText(text); //獲取繪製文字的高度 Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics(); //Descent是baseline之下至字符最低處的距離 //Ascent是baseline之上至字符最高處的距離 //ascent + descent 就是測量文字的高度 float textHeight = fontMetrics.ascent + fontMetrics.descent; //計算繪製中間顯示進度文字的座標 float textY = viewHeight / 2 - textHeight / 2; float textX = viewWidth / 2 - textWidth / 2; //繪製顯示進度的文字 mCanvas.drawText(text, textX, textY, mTextPaint); canvas.drawBitmap(bitmap, 0, 0, null); } /** * 控件 點擊事件監聽 回調 */ public interface OnWaveProgressClickListener { /** * 單擊回調接口 * * @param e */ public void onSingleClick(MotionEvent e); /** * 雙擊回調接口 * * @param e */ public void onDoubleClick(MotionEvent e); /** * 找按回調接口 * * @param e */ public void onLongPressClick(MotionEvent e); } private OnWaveProgressClickListener clickListener; /** * 控件 加載進度回調接口 */ public interface OnWaveProgressListener { public void onProgresUpdate(int progress); public void onFinish(); } private OnWaveProgressListener progressListener; /** * 設置更新當前進度 * * @param progress */ public void updateProgress(int progress) { if (progress <= 0) { progress = 0; } else if (progress > this.maxProgress) { progress = maxProgress; } this.currentProgress = progress; //進度更新接口回調 if (progressListener != null) { progressListener.onProgresUpdate(currentProgress); } if (progress == maxProgress) { if (progressListener != null) { progressListener.onFinish(); } } //重繪 invalidate(); } /** * 設置最大進度 * * @param max */ public void setMaxProgress(int max) { if (max <= 0) { max = 100; } this.setMaxProgress(max); } /** * 設置控件的點擊事件 * * @param listener */ public void setWaveOnClickListener(OnWaveProgressClickListener listener) { this.clickListener = listener; } /** * 加載進度監聽設置 * * @param listener */ public void setWaveOnProgressListener(OnWaveProgressListener listener) { this.progressListener = listener; } }
package com.animation.androidlongs.a360animationapplication; import android.content.Intent; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import com.animation.androidlongs.a360animationapplication.view.WaveProgressView; public class MainActivity extends AppCompatActivity { private WaveProgressView customWaveProgressView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(MainActivity.this, FloatViewService.class); //startService(intent); customWaveProgressView = (WaveProgressView) findViewById(R.id.progress); handler.postDelayed(runnable,2000); //設置點擊事件監聽 customWaveProgressView.setWaveOnClickListener(new WaveProgressView.OnWaveProgressClickListener() { @Override public void onSingleClick(MotionEvent e) { System.out.println("onSingleClick"); } @Override public void onDoubleClick(MotionEvent e) { System.out.println("onDoubleClick"); } @Override public void onLongPressClick(MotionEvent e) { System.out.println("onLongPressClick"); } }); //設置進度更新監聽 customWaveProgressView.setWaveOnProgressListener(new WaveProgressView.OnWaveProgressListener() { @Override public void onProgresUpdate(int progress) { } @Override public void onFinish() { } }); } private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { currentNum++; customWaveProgressView.updateProgress(currentNum); if (currentNum<maxNum){ handler.postDelayed(runnable,200); }else { handler.removeCallbacks(runnable); currentNum = 0; } } }; private int maxNum = 100; private int currentNum =0; }