The Definitive Guide to Self Programming Andrews (26)

This chapter is used to understand the custom view and touch events

Here there will be a program in response to a user's touch and drag to draw a rectangle in the project

(1) Create an activity class to inherit SingleFragmentActivity, thereby instantiate only a single layout fragment, and modify the code to create the object and returns a DragAndDrawFragment

(2) In order to prepare the layout DragAndDrawFragment, rename activity_drag_and_draw.xml to fragment - draw_and_draw.xml

Then create classes DragAndDrawFragment then covered onCreateView () method, used to instantiate fragment_drag_and_draw.xml

(3) Custom View

There are two kinds of custom view for a very simple view, a simple view has no child view, it is always one is used to draw the polymerization process custom views, other views by aggregation view object composition, the polymerization is generally used to view management sub-view, without graphics rendering

Below are three major steps required to create a customized view

(1) Select the superclass, for the simple view, we can choose View as a superclass, it is a blank canvas, so use it as a superclass of the most common, for an aggregate view, we should choose the super-class layout such as FrameLayout

(2) the selected superclass inheritance, covering superclass constructor

(3) covering other key method, used to customize the behavior of the view

 

BoxDrawingView here is a simple view, it can be directly inherited View, and then to add two constructors

public class BoxDrawingView extends View {

public BoxDrawingView(Context context) {

this(context,null);

}

public BoxDrawingView(Context context,AttributeSet attrs) {

super(context,attrs);

}

}

The reason here add two constructors, because the code can be instantiated from code or layout file from the layout file instantiated views will receive a AttributeSet instance that contains the XML layout file named XML attribute even if do not intend to use a constructor method, according to custom, but also added two constructors

With custom view class, we need to update the layout in the layout file to use it

Add fragment_drag_and_draw.xml

<com.bignerdranch.android.draganddraw.BoxDrawingView

     xmln:android="http://schemas.android.com/apk/res/android"

     android:layout_width = "match_parent"

     android:layout_height = "match_parent"/>

Note that you should give BoxDrawingView the full path name of the class, so the layout inflater be able to find it, layout inflater parse layout xml file, and create the View instance in accordance with the view definition, if you do not give the full path, then the inflater and will turn in android.view android.widget package to find similar name, can not find the will collapse

At this point it will run an empty view appears

(4) handle touch events

Listen for the touch event is using the following method View, set up a touch listener:

setOnTouchListener(View.OnTouchListener l) 

Realization of the above interfaces, providing only called when the event is sent to the touch

But here because it is a subclass of View, so we directly cover the following method can be used

public boolean onTouchEvent(MotionEvent event) {

}

The method receives a MotionEvent instance of this class can be used to describe the location and operation of the touch event, description of the operation of the stage for the event

ACTION_CANCEL: parent view to intercept the touch events

In MotionEvent method may be used to view the operation of the getAction value () method

public boolean onTouchEvent(MotionEvent event) {

PointF current = new PointF(event.getX(),event.getY());

String action = "";

switch(event.getAction()) {

case MotionEvent.ACTION_DOWN:

action  = "ACTION_DOWN";

break;

}

return true;

}

Here x and y coordinates of the object which has been packaged into a PointF, we need to pass two coordinate values, the containers just for

(5) track the movement of events

In addition to recording the coordinates, BoxDrawingView mainly used to draw a rectangular box on the screen, to achieve this goal need to know (1) the original coordinate point defined rectangle, the current coordinate point (2) defines a rectangular box, we also need to come from multi-track recording a MotionEvent of data that will be stored in the Box object

public class Box {

private PointF mOrigin;

private PointF mCurrent;

public Box(PointF origin) {

mOrigin = origin;

mCurrent = origin;

}

public PointF getCurrent(){

return mCurrent;

}

public void setCurrent(PointF current){

mCurrent = current;

}

public PonintF getOrigin () {

return mOrigin;

}

}

So that when a user interface when the touch view, the new objects will be added to the existing Box rectangle to

Now back BoxDrawingView, a new Box object to keep track drawing state

private Box mCurrentBox;

private List<Box> mBoxen = new ArrayList<>();

switch(event.getAction()) {

case MotionEvent.ACTION_DOWN:

action  = "ACTION_DOWN";

mCurrentBox = new Box(current);

mBoxen.add(mCurrentBox);

break;

case MotionEvent.ACTION_MOVE:

action = "dd";

if(mCurrentBox !=null) {

mCurrentBox.setCurrent(current);

invalidate (); // this will make BoxDrawingView failure, which would make it self-re-draw, and called again onDraw (Canvas) method

break;

}

case:MotionEvent.ACTION_UP:

action= "";

mCurrentBox = null;

break;

}

case MotionEvent.ACTION_CANCEL:

action = ""

mCurrentBox = null;

return true;

}

Now just received coordinates ACTION_DOWN of action, with regard to events of the original coordinate the establishment of a new object and assign mCurrentBox Box, and then adding it to the rectangular array to

(6) onDraw () method to draw a pattern

After the application starts, all views are in the inactive state, that view has not been drawn up to the screen, in order to solve this problem, Android calls the draw top View view () method, which causes top to bottom called chain reaction, first of all view complete self-draw, then draw the child views, and then draw the child is self-view of a child view, to the end of this call inheritance structure, when all the views themselves are drawn, most view top view has also been in force

Was added to this drawing, the following method may be covered

protected void onDraw(Canvas canvas) {

 

}

There are two categories draw in Android

Canvas class has drawn all the operations we need, the method can decide where to draw, and what to draw, such as round

Paint class decide how to draw, it can specify the method of rendering graphics features, such as graphics is not filled, what font rendering

(7) Creating Paint

private Paint mBoxPaint;

private Paint mBackgroundPaint;

In BoxDrawingView (Context AttributeSet) method to instantiate

public BoxDrawingView(Context context,AttributeSet attrs) {

super(context,attrs);

mBoxPaint = new Paint();

mBoxPaint.setColor();

mBackgroundPaint.setColor();

}

With Paint object, then you can draw a rectangle on the screen

(8) covering onDraw (Canvas) Method

protected void onDraw(Canvas canvas) {

canvas.drawPaint(mBackgroundPaint);

for(Box box:mBoxen) {

float left = Math.min(box.getOrigin().x,boxgetCurrent().x);

float right = Math.max(box.getOrigin().x,boxgetCurrent().x);

float top  = Math.min(box.getOrigin().y,boxgetCurrent().y);

float bottom = Math.max(box.getOrigin().y,boxgetCurrent().y);

canvas.drawRect(left,top,right,bottom,mBoxPaint);

}

}

Now you can draw a rectangle of some

Guess you like

Origin blog.csdn.net/weixin_41673515/article/details/90400670