Custom Controls (2)-drag and drop for switch switching

Source: Internet
Author: User

Here, our main work is based on the original code, add a rewrite of the Ontouchevent method, just add it when it looks like:

@Override      Public Boolean ontouchevent (Motionevent event) {        returnSuper. Ontouchevent (event);    }

For touch events, the general return value is true , then represents the consumption of this touch here, and return false , in the current position of this touch does not do processing or can not be fully processed, It is also necessary to continue to distribute this event to subsequent view or viewgroup responses, where the switch button we have defined is already a child view, so it is OK to return true here, and now it looks like we will return Super.ontouchevent directly ( event); This sentence is deleted and added to return true; Will it be possible to produce any problems? Let's deal with this for the time being.

After the work is relatively simple, we need to according to the type of event.getaction () to do the corresponding treatment, that we basically use every day:Motionevent.action_down, Motionevent.action_ Move and Motionevent.action_up;

Since theAction_move, we want the slider to move as the position of our fingers moves, because it's just moving horizontally, so we just need to record the X-direction position and need two values:int FirstxAndint SecondxFirstxResponsible for recording the lastAction_moveThe x value of the time,SecondxResponsible for recording this timeAction_moveTime ofxValue, and then subtract the two values, you can get the finger two timesAction_moveThe distance to move in the time of the trigger, after which theFirstxAdjusts to the current value for the next use. The distance difference is then summed with the position of our slider so that we can adjust the position of our slider to move with the finger, of courseThe position of the slider is there is a range, here should be [0,max_left_distance]max_left_distance = backgroundbitmap.getwidth () -Slidebutton.getwidth ();, so we need to make a judgment to limit the slider, not let it draw the boundary, OK, the basic logic here, look at the code:

/*** Get screen click events * Similar to the Touchbegan method in iOS*/@Override Public Booleanontouchevent (Motionevent event) {/*** Handle Touch gestures * recognizer.state * Uigesturerecognizerstatebegan * uigesturerecognizersta techanged * Uigesturerecognizerstateend*/        Switch(Event.getaction ()) { CaseMotionevent.action_down:/*** Get the x-coordinate of the touch point * similar to cgpoint in iOS = [recognizer LocationInView:recogznier.view]; */Firsttouchx= Secondtouchx = (int) Event.getx (); Isdrag=false; LOG.I ("Test", "Action_down ....");  Break;  CaseMotionevent.action_move://when moving, calculate the distance the finger moves on the screen            intDistancex = (int) (Event.getx ()-Secondtouchx); if(Math.Abs (Distancex) > 5) {Isdrag=true; } Secondtouchx= (int) Event.getx (); //increments the sliding distance to the x value of the slide buttonSwitchbtnx = switchbtnx+Distancex; //make a judgment to prevent the slider from exceeding the bounds, the range of the slider should be in [0,max_left_distance]            if(Switchbtnx < 0) {switchbtnx= 0; } Else {                if(Switchbtnx > Switchbtnmaxslidedistance) {//if the x-coordinate of the button exceeds the maximum distance that the button can moveSwitchbtnx =switchbtnmaxslidedistance; }} log.i ("Test", "Action_move ....");  Break;  Casemotionevent.action_up://when lifting, determine where the release is, thus determining the state of the switch            if(Switchbtnx < SWITCHBTNMAXSLIDEDISTANCE/2) {switchbtnx= 0; } Else if(Switchbtnx >= SWITCHBTNMAXSLIDEDISTANCE/2) {switchbtnx=switchbtnmaxslidedistance; }             Break; default:             Break; } invalidate (); //refreshes the current state, similar to the Setneeddisplay method in iOS        return true; }

Write now this will cause only the drag effect, and the Click Effect does not work ...

Where is the problem, in fact, for a view , when the Click event is passed in, the ontouchevent method is called first, then the OnClick and Onlongclick are called. and so on, but we don't see how the OnClick method can be called in this method? In fact, the secret was erased before us.

return Super.ontouchevent (event); This sentence inside.

We may as well enter into the super.ontouchevent (event); Inside, find the core code of switch (event.getaction ()) {} :

 if((viewflags & clickable) = = Clickable | |(ViewFlags& long_clickable) = =long_clickable)) {            Switch(Event.getaction ()) { Casemotionevent.action_up: ...if(!post (Mperformclick))                                {PerformClick (); }            ...         Break;  CaseMotionevent.action_down: ...Else {                            //Not inside a scrolling container, so show the feedback right awaySetpressed (true); Checkforlongclick (0); }            ...         Break;    ...    } ...}

And in PerformClick () we can find:

 Public Boolean PerformClick () {    ...    Li.mOnClickListener.onClick (this);    ...}

It's basically clear here that theonclick and Onlongclick are called in the super.ontouchevent method, and theonclick is in Action_up may be called while Onlongclick is called at Action_down . So here we have removed the return super.ontouchevent (event); This sentence, but super.ontouchevent (event); Need to be preserved.

After this step we will find that we can respond to the OnClick method, but still some imperfect We hope that after the drag will not have a click action, click also do not have the drag effect (click of course there is no drag effect ...), because the onclick click is only a simple detection action Whether there is a action_up after _down, if there is, then it is judged as a click event, as to whether the middle process is sliding, it does not matter. So here we need to add a boolean type of judgment flag Isdrag , Action_down when it is set to False if Action_move , set it to true . Then in the OnClick method, add a condition if Isdrag The corresponding action of the click is performed for the fake, otherwise it is skipped. This is more perfect ... Take a look at the final ontouchevent and How the OnClick is written:

Private BooleanIsdrag =false; /*** Get screen click events * Similar to the Touchbegan method in iOS*/@Override Public Booleanontouchevent (Motionevent event) {/*** Handle Touch gestures * recognizer.state * Uigesturerecognizerstatebegan * uigesturerecognizersta techanged * Uigesturerecognizerstateend*/        Switch(Event.getaction ()) { CaseMotionevent.action_down:/*** Get the x-coordinate of the touch point * similar to cgpoint in iOS = [recognizer LocationInView:recogznier.view]; */Firsttouchx= Secondtouchx = (int) Event.getx (); Isdrag=false; LOG.I ("Test", "Action_down ....");  Break;  CaseMotionevent.action_move://when moving, calculate the distance the finger moves on the screen            intDistancex = (int) (Event.getx ()-Secondtouchx); if(Math.Abs (Distancex) > 5) {Isdrag=true; } Secondtouchx= (int) Event.getx (); //increments the sliding distance to the x value of the slide buttonSwitchbtnx = switchbtnx+Distancex; //make a judgment to prevent the slider from exceeding the bounds, the range of the slider should be in [0,max_left_distance]            if(Switchbtnx < 0) {switchbtnx= 0; } Else {                if(Switchbtnx > Switchbtnmaxslidedistance) {//if the x-coordinate of the button exceeds the maximum distance that the button can moveSwitchbtnx =switchbtnmaxslidedistance; }} log.i ("Test", "Action_move ....");  Break;  Casemotionevent.action_up://when lifting, determine where the release is, thus determining the state of the switch            if(Switchbtnx < SWITCHBTNMAXSLIDEDISTANCE/2) {switchbtnx= 0; } Else if(Switchbtnx >= SWITCHBTNMAXSLIDEDISTANCE/2) {switchbtnx=switchbtnmaxslidedistance; }             Break; default:             Break; } invalidate (); //refreshes the current state, similar to the Setneeddisplay method in iOS        return Super. Ontouchevent (event); }
/***/    privatevoid  Switchbtnclick ()        {if ( Switchbtnx = = 0)            {= switchbtnmaxslidedistance        ; Else {            = 0;        }                 // similar to [self Setneeddisplay] method in iOS    }

Final effect:

Custom Controls (2)-drag and drop for switch switching

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.