Android Developer's Custom view feature (iv): Custom ViewGroup

Source: Internet
Author: User

Sometimes we have the need to have two or more interface switches in an activity, just like Viewpager. But in these interfaces you need to be able to have listview,gridview and other components. If it is longitudinal, it seems OK, no effect, then if it is horizontal, then there will be something. Because Viewpager will intercept touch events. And if the Viewpager touch event is intercepted to the child control inside, then Viewpager cannot respond to the sliding event. So how can the interface be able to switch back and forth, but also can let the inside of the child control touch events can have no effect on the response, this time, we need to customize a viewgroup, rewrite the inside of the touch interception method can be.

Blogger Custom ViewGroup is similar to Slidemenu, which contains two interfaces to switch back and forth, the blogger deliberately put a sliding item in the ListView component in the interface experiment, this ListView control is also the blogger to find out from the Internet, It's a nice control. Detailed View:




All right, the ritual. Complete project:

http://download.csdn.net/detail/victorfreedom/8329667

Interested students can download and study.

Custom ViewGroup Detail Code:




Package Com.freedom.slideviewgroup.ui;import Android.content.context;import Android.util.attributeset;import Android.view.motionevent;import Android.view.velocitytracker;import Android.view.view;import Android.view.viewconfiguration;import Android.view.viewgroup;import Android.view.animation.accelerateinterpolator;import Android.widget.scroller;import Com.freedom.slideviewgroup.freedomapplication;import com.freedom.slideviewgroup.utils.dptopxutil;/** * @ClassName : Slidemenu * @author victor_freedom ([email protected]) * @createddate 2015-1-5 PM 8:00:36 * @Description: TODO */pub Lic class Slidemenu extends ViewGroup {private Context mcontext;//default First private int currentscreen = 0;//current screen//Mobile controller Priva Te Scroller Mscroller = null;//Determines whether the private Boolean canscroll = false;//intercepts the Click event, false means intercept, and true means that the click event is passed to the child control private Boolean tochild = false;//handles Touch event move rate standard public static int snap_velocity = 600;//trigger move minimum sliding distance private int mtouchslop = 0;/ /last point x-coordinate private float Mlastionmotionx = 0;// Rate of processing the touch private velocitytracker Mvelocitytracker = null;//The listener for the child controls private Leftlistener Leftlistener;private Rightlistener rightlistener;//Touch State private static final int touch_state_rest = 0;private static final int Touch_state_scro lling = 1;private int mtouchstate = touch_state_rest;//The margin decision distance in response to touch events (this is based on a custom response) public static int tohch_left = 140;public static int tohch_right = freedomapplication.mscreenwidth;public static final String TAG = "Slidemenu";p ublic slidemenu (Co ntext context) {super (context); mcontext = Context;init ();} Public Slidemenu (context context, AttributeSet Attrs) {Super (context, attrs); mcontext = Context;init ();} /** * @Title: Init * @Description: Initialize sliding related stuff * @throws */private void init () {Mscroller = new Scroller (Mcontext, New ACCE Lerateinterpolator ()); mtouchslop = Viewconfiguration.get (GetContext ()). Getscaledtouchslop (); /** * @Title: Onmeasure * @Description: Set viewgroup size * @param widthmeasurespec * @param heightmeasurespec * @throws * * @Ov errideprotected void OnmeaSure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (Widthmeasurespec, heightmeasurespec); int width = Measurespec.getsize (widthmeasurespec); int height = measurespec.getsize (heightmeasurespec); Setmeasureddimension ( width, height); for (int i = 0; i < Getchildcount (); i++) {Getchildat (i). Measure (Widthmeasurespec, heightmeasurespec);} }/** * @Title: OnLayout * @Description: Set distribution location of child controls * @param changed * @param l * Left * @param t * t OP * @param r * Right * @param b * Bottom * @throws */@Overrideprotected void OnLayout (Boolean Chang  Ed, int L, int t, int r, int b) {int startleft = 0;//start layout coordinate of each child view int childCount = Getchildcount (); for (int i = 0; i < ChildCount; i++) {View child = Getchildat (i); Child.layout (startleft, 0, Startleft + getwidth (), getheight ()); startleft = Startleft + G Etwidth (); Calibrate the starting layout position for each sub-view}}/** * @Title: Onintercepttouchevent * @Description: Touch event intercept judgment * @param EV * @return * @throws * * @Overri Depublic Boolean ONintercepttouchevent (motionevent ev) {final int action = Ev.getaction ();//If the current slide state is being blocked, the event if (action = = Motionevent.action_move) && (mtouchstate! = touch_state_rest)) {return true;} Final float x = ev.getx (); switch (action) {Case MotionEvent.ACTION_DOWN:mLastionMotionX = x;//determines the current state mtouchstate = Mscroll Er.isfinished ()? touch_state_rest:touch_state_scrolling;//determine if a sliding event can be responded to if (Ev.getx () < dptopxutil.dip2px (Mcontext, Tohch_left) && Currentscreen = = 1) | | (Ev.getx () > tohch_right-dptopxutil.dip2px (Mcontext, $) && Currentscreen = = 0)) {CanScroll = True;tochild = False;return super.onintercepttouchevent (EV);} else {//If the event cannot be intercepted canscroll = False;tochild = True;return false;} Case MotionEvent.ACTION_MOVE:if (Tochild) {return false;}  Final int differentx = (int) math.abs (mlastionmotionx-x),//If the minimum sliding distance is exceeded, and no event is passed to the child control, change the status if (Differentx > Mtouchslop) {mtouchstate = touch_state_scrolling;} Break;case MotionEvent.ACTION_UP:if (Tochild) {return false;} MtouchstaTe = Touch_state_rest;break;} return super.onintercepttouchevent (EV);} /** * @Title: Ontouchevent * @Description: Touch Event Response * @param event * @return * @throws */public boolean ontouchevent (Motione Vent event) {if (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain ();} Gets the rate of movement mvelocitytracker.addmovement (event); Super.ontouchevent (event);//finger position location Float x = event.getx (); switch ( Event.getaction ()) {case motionevent.action_down://If the screen animation is not over, you press it, we end the animation if (Mscroller! = null) {if (! Mscroller.isfinished ()) {mscroller.abortanimation ();}} Mlastionmotionx = X;break;case MotionEvent.ACTION_MOVE:if (canscroll) {int detax = (int) (mlastionmotionx-x); Mlastionmo Tionx = x;//Moving distance scrollby (detax, 0);} Break;case MotionEvent.ACTION_UP:final Velocitytracker velocitytracker = Mvelocitytracker; Velocitytracker.computecurrentvelocity (+), int velocityx = (int) velocitytracker.getxvelocity ();//sliding rate reached a standard ( Swipe to the right to go back to the previous screen) do a screen cut immediately if (Velocityx > snap_velocity && currentscreen > 0 && CanScroll) {changedscreen (currentScreen-1);} Quick to Zoshi, return to next screen) else if (Velocityx <-snap_velocity&& Currentscreen < (Getchildcount ()-1) && can Scroll) {Changedscreen (currentscreen + 1);} The above is fast moving, forced to toggle screen else {//If moving slowly, then first determine whether to remain on this screen or to the next screen snaptodestination ();} if (mvelocitytracker! = null) {mvelocitytracker.recycle (); mvelocitytracker = null;} Mtouchstate = Touch_state_rest;break;case MotionEvent.ACTION_CANCEL:mTouchState = touch_state_rest;break;} Return Super.onintercepttouchevent (event);} @Overridepublic void Computescroll () {if (Mscroller.computescrolloffset ()) {///If True, represents the data being simulated, False indicates that the analog data has been stopped Scrollto (Mscroller.getcurrx (), Mscroller.getcurry ());//Update offset postinvalidate ();}}  /** * @Title: Startmove * @Description: This is a quick way to jump from the first screen to a second screen * @throws */public void Startmove () {if (Currentscreen = = 1) {return;} if (Currentscreen = = 0 && Rightlistener! = null) {New Thread (new Runnable () {@Overridepublic void run () {rightlist Ener.postnotifydatachAnge ();}}). Start ();} Currentscreen++;mscroller.startscroll ((currentScreen-1) * getwidth (), 0, getwidth (), 0, 600);//Refresh interface invalidate ();// Invalidate, Drawchild, Child.draw, computescroll}/** * @Title: Startmoves * @Description: Jump to first screen * @throw s */public void Startmoves () {changedscreen (0);} /** * @Title: Snaptodestination * @Description: When moving slowly, determine the jump screen * @throws */private void snaptodestination () {int Destscre En = (GETSCROLLX () + getwidth ()/3)/getwidth (); Changedscreen (Destscreen);} /** * @Title: Changedscreen * @Description: Jump screen * @param whichscreen * @throws */private void changedscreen (int whichscre EN) {Currentscreen = Whichscreen;if (Currentscreen > Getchildcount ()-1) {Currentscreen = Getchildcount ()-1;} if (Currentscreen = = 0 && Leftlistener! = null) {Leftlistener.notifydatachange ();} if (Currentscreen = = 1 && rightlistener! = null) {Rightlistener.notifydatachange ();} Getscrollx gets the offset of the current view relative to the parent control. The initial value is 0,int dx = currentscreen * getwidth ()- GETSCROLLX ();//When DX is positive, the screen slides to the right and DX is negative, the screen slides to the left Mscroller.startscroll (GETSCROLLX (), 0, DX, 0, +);p ostinvalidate ();} Public interface Leftlistener {public void Notifydatachange ();} Public interface Rightlistener {public void Notifydatachange ();p ublic void Postnotifydatachange (); public void Setleftlistener (Leftlistener leftlistener) {this.leftlistener = Leftlistener;} public void Setrightlistener (Rightlistener rightlistener) {this.rightlistener = Rightlistener;}}


Since this custom view topic has been explained, I believe everyone has a preliminary understanding of custom view, which is basically a few steps. One more step for custom viewgroup than for custom view is to override the OnLayout method to place the child controls contained inside, and the rest is similar.

All right, the ritual. Complete project:

http://download.csdn.net/detail/victorfreedom/8329667

Interested students can download and study.

Custom ViewGroup Detail Code:

Android Developer's Custom view feature (iv): Custom ViewGroup

Related Article

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.