These days have been watching the "Android Development art exploration" and "Android Elite Biography" in the chapter on Custom view, combined with some of the online great God's experience to share, feel the custom view this piece of benefit, here to do a note, the main record of the view and user interaction of some knowledge.
Custom view and user interaction with the most is the click event, followed by double-click events, long-press events, sliding events, etc., so you need to do a good view of the event monitoring.
If we inherit the view, also draw the control, but do not rewrite the Ontouchevent () method, set the Click event is generally useless, but it is not necessarily useless, the following first introduced a relatively simple click event implementation, but also from the Zhang Hongyang of the Great God of a blog to see.
To set the view's Click event Implementation method One:
In the view construction method directly Setonclicklistener, the following code:
Public Toucheventtest (Context context) {This
(context, NULL);
}
Public Toucheventtest (context context, AttributeSet attrs) {This
(context, attrs, 0);
}
Public Toucheventtest (context context, AttributeSet attrs, int defstyleattr) {
Super (context, attrs, defstyleattr);
This.setonclicklistener (New Onclicklistener () {
@Override public
void OnClick (View v) {
LOGGER.E (" View internal settings Onclicklistener "," ");
}
);}
such as the code can implement the custom view of the click-Listen, but there are a lot of limitations, first of all, such a setup monitoring is very rigid, not for external calls, followed by testing, if you write the code, and then rewrite the view of the Ontouchevent () method, So no matter whether your Ontouchevent method is direct return super.ontouchevent () or any other logic, you cannot trigger this listener event, which means that setting up a listener in this way is useless. This directly affects the extensibility of our custom view, so it is recommended not to use it, although simple, but there are many problems, but this way also has a case, that is, if the custom view really only need to own internal processing logic, do not need external participation, then this setting is OK, However, it is not recommended to use this method unless the business logic allows it.
The second way to listen to custom view settings is described below, which is also a way for individuals to think that they are more normal and common.
That is, override the Ontouchevent method, and then determine whether the clicked coordinates are inside a custom view. If you are inside a custom view, the callback clicks on the listener interface, otherwise it is ignored.
Before saying this way, first popularize a variety of coordinate knowledge, after all, will need to use.
As shown above: clearly reflects the meaning of the various coordinates.
Next, we need to rewrite the Setonclicklistener () method with the following code:
@Override public
void Setonclicklistener (Onclicklistener l) {
mlistener = l;
}
is to assign the Onclicklistener, of course, we can not use the override annotation, or we can customize the interface and methods, and provide a way to set up a custom listener, the code is as follows:
public void Setonviewclick (Onviewclick click) {
this.mviewclick = click;
}
Public interface Onviewclick {
/**
* @param scrollx distance from press to lift, x-axis movement
* @param scrolly distance
from press to lift, y-axis direction *
/void OnClick (float scrollx, float scrolly);
}
Then we rewrite the Ontouchevent method, which is a generic set of Click event Template methods,
@Override Public
Boolean ontouchevent (Motionevent event) {
int x = (int) event.getx ();
int y = (int) event.gety ();
int action = Event.getaction ();
Switch (action) {case
motionevent.action_down: Break
;
Case Motionevent.action_move: Break
;
Case MOTIONEVENT.ACTION_UP:
if (x + getLeft () < GetRight () && y + getTop () < Getbottom ()) {
Mliste Ner.onclick (this);
Mviewclick.onclick (X-startx, Y-starty);
}
break;
}
return true;
}
Note that it is important to return true or to decide whether to return true or false based on your business logic. According to the view's event distribution process, if the custom view does not handle the Action_down event, then all subsequent events will not be processed for him, in conjunction with the code: when the user presses, enter into the Motionevent.action_down case statement, Then break off, then return true, the point is here, if you return false here, the view does not handle the event, so later states such as Action_move and ACTION_UP will no longer trigger, Because the event has been processed by one of the view's parent classes, it is no longer passed to the child view. If True is returned, the view takes over all subsequent operations, and the view processes the corresponding event.
Another point: The handling of click events is generally done at action_up, while the processing of sliding and the like are generally action_move ...
Here we verify in the code is valid, the code is as follows (the layout file is not affixed):
public class Toucheventtestactivity extends Appcompatactivity {
@Override
protected void OnCreate (Bundle Savedinstancestate) {
super.oncreate (savedinstancestate);
Setcontentview (r.layout.activity_touch_event_test);
Toucheventtest TestView = (toucheventtest) Findviewbyid (r.id.toucheventtest);
Testview.setonclicklistener (New View.onclicklistener () {
@Override public
void OnClick (View v) {
LOGGER.E ("Setonclicklistener,view.getclass ():" + v.getclass () + "");
}
});
Testview.setonviewclick (New Toucheventtest.onviewclick () {
@Override public
void OnClick (float scrollx, Float scrolly) {
LOGGER.E ("x axis moved:" + scrollx + "Px,y Axis moved:" + scrolly + "px", "");}}
);}
}
Let's look at the printed log information:
Finally, put out the complete code, so that everyone better understand:
Package com.lanma.customviewproject.views;
Import Android.content.Context;
Import Android.util.AttributeSet;
Import android.view.MotionEvent;
Import Android.view.View;
/** * Author Qiang_xi on 2016/8/23 15:05.
*/public class Toucheventtest extends View {private Onclicklistener mlistener;
Private Onviewclick Mviewclick;
private int startrawx;
private int Startrawy;
Public Toucheventtest (Context context) {This (context, NULL);
} public Toucheventtest (context context, AttributeSet Attrs) {This (context, attrs, 0); } public Toucheventtest (context context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, defsty
LEATTR); This.setonclicklistener (New Onclicklistener () {//@Override//public void OnClick (View V
) {//LOGGER.E ("View internal settings Onclicklistener", "");
// }
// }); } @Override public boolean ontouchevent (Motionevent event) {int x = (int) event.getx ();
int y = (int) event.gety ();
int rawx = (int) event.getrawx ();
int rawy = (int) Event.getrawy ();
int action = Event.getaction ();
Switch (action) {case MotionEvent.ACTION_DOWN:startRawX = rawx;
Startrawy = Rawy;
Break
Case MotionEvent.ACTION_MOVE:break;
Case MotionEvent.ACTION_UP:if (x + getLeft () < GetRight () && y + getTop () < Getbottom ()) {
Mlistener.onclick (this);
Mviewclick.onclick (RAWX-STARTRAWX, Rawy-startrawy);
} break;
} return true;
} @Override public void Setonclicklistener (Onclicklistener l) {mlistener = l;
} public void Setonviewclick (Onviewclick click) {this.mviewclick = click; } public interface Onviewclick {/** * @paraM scrollx distance from press to lift, x-axis movement * @param scrolly from Press to lift, y-axis direction of movement */void OnClick (float scrollx, Floa
T scrolly);
}
}