自訂View之大風車系列demo(四),大風車demo

來源:互聯網
上載者:User

自訂View之大風車系列demo(四),大風車demo

版本4.0有個問題當手指抬起的時候風車停止了,現在就解決這個問題,手指抬起的時候繼續讓風車由於慣性而繼續旋轉一段時間。思路如下

1)需要擷取手指抬起時風車轉動的瞬間速度,這個難度不小,在我的demo裡面我只是簡單的計算了手指按下到抬起經過的時間和弧度差,用弧度差除以時間來類比下速度。

具體的還真不好用語言描述,所以偷個懶,直接上代碼吧速度控制器添加了speed變數,並根據弧度差和經過的時間來計算速度


package rotation.demo.bean;import android.util.Log;/*** * 當手指移動的時候,補貨手指抬起時風車轉動的瞬間的速度:在這裡暫且類比為手指按下到抬起時的弧度減去按下時的弧度,除以經過的時間 * @author YanQiu * */public class SpeedControl {/** 手指按下時候的弧度 **/private float down_rad;/** 手指move時當前座標的弧度 **/private float current_move_rad;/** 弧度增量,它的值等於current_move_rad - down_rad**/private float Δrad;/** 圖片的中心原點 **/private float x0, y0;/**手指抬起時的速度**/private float speed;public SpeedControl(float x0, float y0) {this.x0 = x0;this.y0 = y0;}/**//** * 判斷是否是順時針 * @param current_move_x 手指 * @param current_move_y * @param up_x * @param up_y * @return *//*public boolean isClockWise(float current_move_x,float current_move_y,float up_x,float up_y) {return false;}*//*** * 計算當前座標點與x軸的夾角所代表的弧度,弧度計算公式為 1rad = 180/Math.PI,<br> * 需要注意的是直角座標系分四個象限,每個象限的座標點與x軸的夾角計算時需要計算一下 *  * @param current_x *            當前座標點的橫座標點 * @param current_y *            當前座標點的縱座標點 * @return */public float computeRad(float current_x, float current_y) {final float Δx = current_x - x0;final float Δy = current_y - y0;double θ = 0f;// 夾角// 求夾角的正切的絕對值float tanθ = Math.abs(Δy / Δx);if (Δx > 0) {// 當座標點在1或者4象限的情況if (Δy >= 0) {// 座標點位於第一象限θ = Math.atan(tanθ);} else {// 當座標點位於第四象限θ = 2 * Math.PI - Math.atan(tanθ);}} else {// 當座標點位於2或3象限if (Δy >= 0) {// 位於第二象限θ = Math.PI - Math.atan(tanθ);} else {// 位於第三象限θ = Math.PI + Math.atan(tanθ);}}float result = (float) ((180 * θ) / Math.PI);return result;}public float getDown_rad() {return down_rad;}public void setDown_rad(float down_rad) {this.down_rad = down_rad;}public float getCurrent_move_rad() {return current_move_rad;}public void setCurrent_move_rad(float current_move_rad) {this.current_move_rad = current_move_rad;}public float getΔrad() {return Δrad;}public void setΔrad(float δrad) {Δrad = δrad;}public float getSpeed() {return speed;}public void setSpeed(float δrad,long duration) {δrad = 1000*Math.abs(δrad);Log.e("", "δrad==="+δrad + "---duration=="+duration + " speed =="+Math.abs(δrad/duration));this.speed = Math.abs(δrad/duration);}}

RotationView代碼修改如下,主要修改了action_up事件和post的Ruannable方法:

package rotation.demo.view;import rotation.demo.bean.SpeedControl;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;/** * verson3.0 前兩個版本都是手指離開螢幕的時候就會立即停止轉動,現在這個版本讓當手指抬起的時候,由於慣性讓風車繼續轉動一點時間。 * 思路:監聽手指抬起事件,然後重繪 *  * @author YanQiu * */public class RotationView extends View {/** 要轉動的圖片 **/private Bitmap bitMap;/** 風車每次轉動的弧度 **/private int degree = 0;/** 圖片的寬度:在這裡提供的是正方形的圖片,所以寬度和高度是一樣的 **/private int width = 0;/*** 圖片的高度:在這裡提供的是正方形的圖片,所以寬度和高度是一樣的 **/private int height = 0;/** 定義一個畫筆 **/private Paint paint = new Paint();/**手指抬起的時間**/private long upTime = 0;/**手指抬起的時候風車持續轉動的時間**/private final long stopTimeDuration = 5000;private SpeedControl speedControl;public RotationView(Context context, AttributeSet attrs) {super(context, attrs);}public RotationView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public RotationView(Context context) {super(context);}private String tag = "";/** * 計算圖片的圓心 */public void initSize() {width = bitMap.getWidth();height = bitMap.getHeight();speedControl = new SpeedControl(width/2,height/2);postInvalidate();}public void setBitMap(Bitmap bitMap) {this.bitMap = bitMap;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(width, width);}@Overrideprotected void onDraw(Canvas canvas) {Matrix matrix = new Matrix();// 設定轉軸位置matrix.setTranslate((float) width / 2, (float) height / 2);    matrix.preRotate(speedControl.getΔrad());// 轉軸還原matrix.preTranslate(-(float) width / 2, -(float) height / 2);canvas.drawBitmap(bitMap, matrix, paint);super.onDraw(canvas);}/**手指滑動時此時的時間**/private long current_move_time;@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch (action) {case MotionEvent.ACTION_DOWN:final float down_rad = speedControl.computeRad(event.getX(), event.getY());speedControl.setDown_rad(down_rad);current_move_time = System.currentTimeMillis();break;case MotionEvent.ACTION_MOVE:// 隨著手指的move而不斷進行重繪final float current_move_rad = speedControl.computeRad(event.getX(), event.getY());final float Δrad = current_move_rad - speedControl.getDown_rad();speedControl.setΔrad(Δrad);//該方法在UI線程自身中使用postInvalidate();break;case MotionEvent.ACTION_UP:// 隨著手指的move而不斷進行重繪final float up_rad = speedControl.computeRad(event.getX(), event.getY());//手指抬起和按下經過的弧度差final float δrad = up_rad - speedControl.getDown_rad();upTime = System.currentTimeMillis();final long  duration = upTime - current_move_time;//設定手指離開時的速度speedControl.setSpeed(δrad, duration);post(new Runnable() {@Overridepublic void run() {long stopDuration = System.currentTimeMillis()-upTime;//long  //speedControl.setSpeed(duration);if(stopDuration == stopTimeDuration) {return;}else if(stopDuration<stopTimeDuration){post(this);}//計算此時轉過的弧度speedControl.setΔrad(speedControl.getSpeed()*1000/stopDuration);invalidate();}});break;}//此處必須返回true,否則不會執行此處的事件,詳見部落格return true;}}

到此為止,搗鼓了半天的小demo終於完成了,不過還有個問題:經過這一修改,不知道怎麼判斷手指是否是逆時針還是順時針轉動了,查了好些資料好些解決不了問題,希望有好的建議或者思路的給留個言.還有計算慣性轉動的弧度不是很好,只是簡單的類比,風車逐漸停止的效果不是很理想

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.