Version 4.0 There's a problem. When the finger is lifted, the windmill stops, and now it's time to fix the problem and keep the windmill spinning for a while while the finger is lifted. Ideas are as follows
1) need to get the finger lift when the speed of the windmill rotation, this difficulty is not small, in my demo I just simple calculation of the finger press to lift the elapsed time and the arc difference, the radian difference divided by the time to simulate the next speed.
Specific is really not good language description, so steal a lazy, directly on the code bar speed controller adds speed variable, and calculates the velocity based on the radian difference and elapsed time.
Package Rotation.demo.bean;import android.util.log;/*** * When the finger is moving, the speed at which the windmill rotates when the finger is lifted: here for the moment, the arc of the finger pressed to lift is subtracted, divided by elapsed time * @author Yanqiu * */public class Speedcontrol {/** finger press the radian **/private float down_rad;/** The current coordinates in radians **/priv ate float current_move_rad;/** radians increment, whose value equals Current_move_rad-down_rad**/private floatδrad;/** The center origin of the picture **/private float x0 , y0;/** finger lift speed **/private float speed;public speedcontrol (float x0, float y0) {this.x0 = X0;this.y0 = y0;} /**//** * Determine if it is clockwise * @param current_move_x finger * @param current_move_y * @param up_x * @param up_y * @return *//*public Boo Lean isclockwise (float current_move_x,float current_move_y,float up_x,float up_y) {return false;} *//*** * Calculates the radian represented by the angle between the current coordinate point and the x-axis, the radian is calculated as 1rad = 180/math.pi,<br> * It is important to note that the Cartesian coordinate system is divided into four quadrants, and the coordinates of each quadrant and the angle of the x-axis need to be calculated * * @param current_x * Horizontal point of the current coordinate point * @param current_y * Ordinate point of the current coordinate point * @return */public float Computerad (float CU rrent_x, float current_y) {final floatδx = current_x-x0;final Floatδy = current_y-y0;doubleθ= 0f;//angle//To find the absolute value of the tangent of the angle float tanθ= math.abs (Δy/δx); if (Δx > 0) {//when the coordinate point is in 1 or 4 quadrants if (Δy ; = 0) {//coordinate points are located in the first Quadrant θ= Math.atan (tanθ);} else {//when the coordinate point is in Quadrant four θ= 2 * Math.pi-math.atan (tanθ);}} else {//when the coordinate point is in 2 or 3 quadrant if (Δy >= 0) {//is located in the second Quadrant θ= Math.pi-math.atan (tanθ);} else {//in the third quadrant θ= 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;}}
The Rotationview code modifies the following, mainly modifies the Action_up event and post Ruannable method:
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 The first two versions of the finger leave the screen immediately when the rotation will stop, and now this version lets the finger lift, as the inertia of the windmill to continue to rotate a little time. * Idea: Monitor your finger to lift the event, then redraw * * @author Yanqiu * */public class Rotationview extends View {/** to rotate the picture **/private Bitmap bitmap;/** The **/private int degree = 0;/** the width of the picture: here is a square picture, so the width and height are the same **/private int width = 0;/*** the height of the picture: Here is a picture of a square , so the width and height are the same **/private int height = 0;/** defines a brush **/private paint paint = new Paint ();/** finger lift time **/private long upTime = 0;/** finger lifted when the windmill continued to turn the time **/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 = "";/** * Calculates the center of the picture */public void Initsize () {width = bitmap.getwidth (); height = bitmap.getheight (); Spee Dcontrol = new Speedcontrol (WIDTH/2,HEIGHT/2);p ostinvalidate (); 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 ();//Set Hinge position matrix.settranslate ((float) WIDTH/2 , (float) HEIGHT/2); Matrix.prerotate (Speedcontrol.getδrad ());//axis Restore Matrix.pretranslate (-(float) WIDTH/2,-(float) HEIGHT/2); Canvas.drawbitmap (BitMap, Matrix, paint); Super.ondraw (canvas);} /** the time when the finger slips **/private long current_move_time; @Overridepublic boolean ontouchevent (Motionevent event) {intAction = 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://continues to redraw the final float Current_move_rad = Speedcontrol.computerad with the MOVE of the finger ( Event.getx (), Event.gety ()), Final floatδrad = Current_move_rad-speedcontrol.getdown_rad (); Speedcontrol.setδrad ( Δrad);//The method uses Postinvalidate () in the UI thread itself; break;case motionevent.action_up://continuously redraws the final float Up_rad with the move of the finger Speedcontrol.computerad (Event.getx (), event.gety ());//The finger is lifted up and pressed through the radian difference final Floatδrad = Up_rad-speedcontrol.getdown_ Rad (); upTime = System.currenttimemillis (); final long duration = uptime-current_move_time;// Set the speed of the finger away Speedcontrol.setspeed (Δrad, duration);p OST (new Runnable () {@Overridepublic void run () {Long stopduration = System.currenttimemillis ()-uptime;//long//speedcontrol.setspeed (duration); if (stopduration = = StoptimeduratiOn) {return;} else if (stopduration<stoptimeduration) {post (this);} Calculates the Radian Speedcontrol.setδrad (Speedcontrol.getspeed () *1000/stopduration) that was turned at this time; invalidate ();}); break;} You must return true here, otherwise the event will not be executed, see blog return true;}}
So far, tinkering with a half-day of the small demo finally finished, but there is a problem: after this modification, do not know how to determine whether the finger is counterclockwise or clockwise rotation, check a lot of information can not solve the problem, Hope to have good suggestions or ideas to leave a message. There is also the calculation of inertia rotation of the arc is not very good, just simple simulation, the effect of the gradual stop of the windmill is not very ideal
Custom view of the Big Windmill Series Demo (iv)