Demo series of custom View (III) and windmill demo

Source: Internet
Author: User

Demo series of custom View (III) and windmill demo

The experience of the big windmill series from version 1.0 to version 3.0 is very poor: the radians of the windmill rotate are manually written to death and won't be fast and fast based on the speed of finger movement. Version 4.0 will solve this problem with the following ideas:

1) take the center of the windmill image as the coordinate origin. Resume a Cartesian coordinate system, capture the finger press event, that is, the MotionEvent. ACTION_DOWN event, and record the coordinate point of the finger at this time and the angle between the x coordinate axis of the Cartesian coordinate system.

2) obtain the angle between the coordinate point of the current finger and the x axis of the Cartesian coordinate system when the finger moves.

3) calculate the difference between the two angle values of step 1 and step 2, that is, the radian that the finger moves at this time. It is not written as before version 3.0.

The specific code design is as follows: The SpeedControl class of the speed controller is provided, and the method for obtaining the angle between the current coordinate point and the x axis is provided. The code for this class is as follows:

Package rotation. demo. bean; public class SpeedControl {/** radians when fingers are pressed **/private float down_rad;/** radians of the current coordinate when fingers are moved **/private float current_move_rad; /** radian increment. The value is equal to current_move_rad-down_rad **/private float △rad;/** center origin of the image **/private float x0, y0; public SpeedControl (float x0, float y0) {this. x0 = x0; this. y0 = y0;}/***** calculate the radian represented by the angle between the current coordinate point and the X axis. The radian formula is 1rad = 180/Math. PI, <br> * Note that the Cartesian coordinate system is divided into four quadrants, when calculating the coordinate between the coordinate point of each quadrant and the X axis, You need to calculate ** @ param current_x * The coordinate point of the current coordinate point * @ param current_y * The ordinate point of the current coordinate point * @ return */public float computeRad (float current_x, float current_y) {final float △x = current_x-x0; final float △y = current_y-y0; double θ = 0f; // angle // returns the absolute value float tan θ = Math. abs (△y/△x); if (△x> 0) {// when the coordinate point is in the 1 or 4 quadrant, if (△y> = 0) {// coordinate point in the first quadrant θ = Math. atan (tan θ);} else {// when the coordinate point is in the fourth quadrant θ = 2 * Math. PI-Math. atan (tan θ) ;}} else {// when the coordinate point is in the 2 or 3 Quadrant if (△y> = 0) {// located in the second quadrant θ = Math. PI-Math. atan (tan θ);} else {// located in the third quadrant θ = Math. PI + Math. atan (tan θ) ;}/// note a radian = 180/Math. PIfloat 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;} // This method works with Matrix. preRotate uses public float get Delta rad () {return Delta rad;} public void set Delta rad (float Delta rad) {Delta rad = delta rad ;}}

The RotationView code is changed as follows, mainly reflected in onTouchEvent and onDraw:

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;/*** the first two versions of verson3.0 stop rotating immediately when the finger leaves the screen. The current version allows the windmill to continue turning when the finger is lifted. Take a moment. * Idea: Listen to the finger lifting event and re-draw ** @ author YanQiu **/public class RotationView extends View {/** image to be rotated **/private Bitmap bitMap; /** The radian of a windmill **/private int degree = 0;/** width of the image: The square image is provided here, so the width and height are the same **/private int width = 0;/*** Image Height: here we provide a square image, so the width and height are the same **/private int height = 0;/** define a Paint brush **/private paint = new Paint (); /** time when the finger is lifted **/private long upTime = 0;/** the time when the wind continues to rotate when the finger is lifted **/private fin Al long stopTimeDuration = 5000;/** speed controller **/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 = "";/*** calculate the center of the image */public void initSize () {width = bit Map. 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 on Draw (Canvas canvas) {Matrix matrix = new Matrix (); // sets the Axis Position matrix. setTranslate (float) width/2, (float) height/2); // starts to convert to the radian matrix that the finger turns. preRotate (speedControl. get △rad (); // restores matrix from a pivot. preTranslate (-(float) width/2,-(float) height/2); canvas. drawBitmap (bitMap, matrix, paint); super. onDraw (canvas) ;}@ Overridepublic boolean onTouchEvent (MotionEvent event) {int action = event. getAction (); switch (Action) {case MotionEvent. ACTION_DOWN: // obtain the radian final float down_rad = speedControl between the coordinate point pressed by the finger and the angle between the X axis. computeRad (event. getX (), event. getY (); speedControl. setDown_rad (down_rad); break; case MotionEvent. ACTION_MOVE: // re-paint final float current_move_rad = speedControl as your fingers move. computeRad (event. getX (), event. getY (); final float △rad = current_move_rad-speedControl. getDown_rad (); // calculates the radian difference speedControl between fingers. set △Rad (△rad); // This method uses postInvalidate (); break; case MotionEvent In the UI thread itself. ACTION_UP: // re-paint with the move of the finger. upTime = System. currentTimeMillis (); post (new Runnable () {@ Overridepublic void run () {long duration = System. currentTimeMillis ()-upTime; if (duration = stopTimeDuration) {return;} else if (duration <stopTimeDuration) {post (this) ;}// used in a non-UI thread. Invalidate () ;}}); break ;}return true ;}}
After testing, this version allows the windmill to change with the speed at which the fingers move, but there is still a problem, that is, when the fingers are lifted, the same windmill will stop rotating, this will be solved in the final version. For details, see the big windmill series of custom view (4)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.