Demo series of custom View (1) and windmill demo
Every time I write a blog, I hate the beginning of my blog. I don't know what to write. Now I am, too. I feel like writing a eight hundred-character essay. The reason why I wrote this series of demos is that when I watched the source code of an image circled on the Internet the day before yesterday
Do you want to play tricks on your own? By the way, you can learn about view! Do what you do. Of course, when you write it yourself, you can't help writing code by referring to others. After all, the custom view and my level are indeed challenging, through the small demo of these columns, I have gained a lot. Although some of the more powerful functions cannot be achieved by myself, my goal is also achieved. Let's talk about the general situation of the big windmill series of small demos: There are five versions in total, which means that this series will write four to five short blogs, each version is a modification to the previous version or a function improvement. Note: This is a demo with few codes, but it can be learned by beginners, if you see a blog with no level, you can leave some comments or comments on android-related knowledge. In short, you are welcome to criticize and correct the content:
Major windmill version 1.0) provides the following functions and considerations:
1) The Windmill image rotates with the finger, and the rotation speed is fixed.
2) the rotation of the image must be designed to reproduce the androidview. Therefore, the postInvalidate and invalidate methods are prepared.
3) since the image rotates as the finger moves, the MotionEvent. action_move event will be replenished and processed in onTouchEvent.
4) The required windmill image materials are as follows:
5) the picture of the windmill is a square image with the same width and height. The center of the square line needs to be calculated, and the center is rotated as the rotation axis.
The custom View code is as follows:
Package rotation. demo. view; 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;/* verson 1.0 * the idea of a windmill * Rotating with its fingers * 1) the windmill Rotation involves the picture re-painting process * 2) listen to the move event of the finger. When the move event is listened to, call the relevant method for re-painting * 3) use matrix transformation to achieve windmill rotation * @ author xiaobenxiong **/public class RotationView extends View {/** image to be rotated **/private Bitmap bitMap; /** radians of a windmill **/private int rad = 30;/** 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 Paint = new Paint (); 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);}/*** get the width and height of the image */public void initSize () {width = bitMap. getWidth (); height = bitMap. getHeight (); postInvalidate ();} public void setBitMap (Bitmap bitMap) {this. bitMap = bitMap;} // set the width and height of a custom View. Because the width and height of a square are the same, @ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper. onMeasure (widthMeasureSpec, heightMeasureSpec); setMeasuredDimension (width, width);}/*** the onDraw method draws the windmill image and the rotating effect of the windmill, use Matrix to control */@ Override protected void onDraw (Canvas canvas) {Matrix matrix = new Matrix (); // set the Axis Position matrix. setTranslate (float) width/2, (float) height/2); rad-= 3; // The radian increment of each rotation is 3 of course, the larger the number, the faster the rotation speed. // starts to convert to matrix. preRotate (rad); // restores matrix. preTranslate (-(float) width/2,-(float) height/2); // draw the windmill image canvas. drawBitmap (bitMap, matrix, paint); super. onDraw (canvas) ;}@ Overridepublic boolean onTouchEvent (MotionEvent event) {int action = event. getAction (); switch (action) {case MotionEvent. ACTION_MOVE: // re-paint continuously with the move of the finger, and then let the windmill rotate postInvalidate (); // call the method to re-paint break;} return true ;}}
The above code is very simple. It mainly captures the MotionEvent. ACTION_MOVE event, and calls the postInvalidate method to implement re-painting. In the onDraw method, the rotation effect of the windmill is achieved through the change of Martix. Note:
1) The onTouchEvent must return true. Otherwise, the program you wrote in this method will not be executed. For details, see android event interception mechanism.
Use the following in the configuration file:
<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="#ffffffff" > <rotation.demo.view.RotationView android:id="@+id/rotationView" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_centerInParent="true"> </rotation.demo.view.RotationView ></RelativeLayout>
public class MainActivity extends Activity { @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RotationView rotation = (RotationView)findViewById(R.id.rotationView);BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.drawable.fengche);rotation.setBitMap(drawable.getBitmap());rotation.initSize();}}
After running, you will find a problem: whether the finger is clockwise or counterclockwise, the wind is always clockwise. After testing, we found that when the three points in matrix. preRotate gradually become larger
It is clockwise rotation. If the primary key is small, it is counter-clockwise. So I simply added two buttons to select whether it is counter-clockwise. When it is counter-clockwise, the rad variable is decreased, clockwise increments. Therefore, the clockWise Boolean variable is added to the RotationView, and the value of clockWise is changed by clicking the variables of the two buttons. As follows:
The onDraw method code is changed as follows:
Private boolean clockWise = false; @ Overrideprotected void onDraw (Canvas canvas) {Matrix matrix = new Matrix (); // set the Axis Position matrix. setTranslate (float) width/2, (float) height/2); if (clockWise) {// if it is clockWise rad + = 30 ;} else {rad-= 30;} // starts to convert to matrix. preRotate (degree); // restores the matrix. preTranslate (-(float) width/2,-(float) height/2); // send the position to the center of the view // matrix. postTranslate (float) (width)/2, (float) (height)/2); canvas. drawBitmap (bitMap, matrix, paint); super. onDraw (canvas );}
After a simple modification, version 2 was born. Of course, version 2.0 still has some problems and is left for Version 3 to solve. For details, see the demo series of custom View (2)