Effect
Main steps:
1. Place content in the XML layout. Include
2. In the custom viewgroup, perform measure measurements, layout layouts
3. Responding to User touch events
4. int scrollx = (int) (Downx-movex);
5. GETSCROLLX () Gets the position currently scrolled to
6. Smooth Animation
First look at the layout
Layout_left
<?xml version= "1.0" encoding= "Utf-8"? ><scrollview xmlns:android= "Http://schemas.android.com/apk/res/android"Android:layout_width= "240DP"Android:layout_height= "Match_parent" > <LinearLayout android:layout_width= "240DP"Android:layout_height= "Match_parent"android:orientation= "Vertical"Android:background= "@drawable/menu_bg" > <TextView android:layout_width= "Match_parent"Android:layout_height= "Wrap_content"android:padding= "8DP"Android:background= "@drawable/selector_bg"android:drawablepadding= "10DP"android:gravity= "Center_vertical"Android:text= "News"android:clickable= "true"Android:textcolor= "#ADCFD6"Android:drawableleft= "@drawable/tab_news"android:textsize= "18sp"/> </LinearLayout></ScrollView>
Layout_content
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"Android:layout_width= "Match_parent"Android:layout_height= "Match_parent"Android:background= "#FFFFFF" > <LinearLayout android:layout_width= "Match_parent"Android:layout_height= "Wrap_content"android:orientation= "Horizontal"Android:background= "@drawable/top_bar_bg" > <ImageButton android:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"android:src= "@drawable/main_back"Android:background= "@null"/> <View android:layout_width= "1DP"Android:layout_height= "Match_parent"Android:background= "@drawable/top_bar_divider"/> <TextView android:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"Android:text= "Daily News"android:textsize= "25SP"android:layout_gravity= "Center"/> </LinearLayout></LinearLayout>
Activity_main
<?xml version= "1.0" encoding= "Utf-8"?><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" tools: Context= "Com.example.xw.mystudeydemo.MainActivity" ><com.example.mystudydemo.SlideMeun Android:layout_width= "Match_parent" android:layout_height= "Match_parent" > < Include layout= "@layout/layout_left"/> <include layout= "@layout/layoit_content"/></ Com.example.mystudydemo.slidemeun></relativelayout>
It is important to note in the layout that we set the overall layout background to android:background= "#FFFFFF" in layout_content, because we need him to completely cover the layer below Layout_left.xml
Status selector for Layout_left
<?xml version= "1.0" encoding= "Utf-8"? ><selector xmlns:android= "http://schemas.android.com/apk/res/ Android "> <item android:state_pressed=" true "android:drawable=" @color/bg_pressed "/> <item Android:drawable= "@android: Color/transparent"/></selector>
Second, write the custom control
PackageCom.example.mystudydemo;ImportAndroid.content.Context;ImportAndroid.util.AttributeSet;Importandroid.view.MotionEvent;ImportAndroid.view.View;ImportAndroid.view.ViewGroup;ImportAndroid.widget.Scroller;/*** Created by XW on 2016/8/6.*/ Public classSlidemeunextendsviewgroup{Private floatDownx; Private floatMoveX; PrivateScroller Scroller; /*** Slide Panel control, drawer panel. *@authorPoplar * * Measurement placement draw measure, layout, Draw | | | Onmeasure, OnLayout, OnDraw override these methods to implement a custom control view process Onmeasure () (Specify your own width in this method), OnDraw () (Draw your own Content) ViewGroup Process onmeasure () (Specify its own width, width of all sub-view), OnLayout () (All Child view), OnDraw () (Draw content) * */ PublicSlidemeun (Context context) {Super(context); Init (context); } PublicSlidemeun (Context context, AttributeSet attrs) {Super(context, attrs); Init (context); } PublicSlidemeun (context context, AttributeSet attrs,intdefstyleattr) { Super(context, attrs, defstyleattr); Init (context); } Private voidinit (Context context) {//Initialize the scrollScroller=NewScroller (context); } /*** measure and set the width of all sub-view * widthmeasurespec: Width measurement rule for current control * heightmeasurespec: Height measurement rule for current control*/@Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec) { //Specifies the width height of the left panelView Leftmenu=getchildat (0); Leftmenu.measure (Leftmenu.getlayoutparams (). Width,heightmeasurespec); //Specify the width height of the main panelView Mainmenu=getchildat (1); Mainmenu.measure (Mainmenu.getlayoutparams (). Width,heightmeasurespec); Super. Onmeasure (Widthmeasurespec, Heightmeasurespec); } @Overrideprotected voidOnLayout (BooleanChangedintLintTintRintb) {//display contents, left panel, hideView Leftmenu=getchildat (0); Leftmenu.layout (-leftmenu.getmeasuredwidth (), 0,0, B); //main panelView Mainmenu=getchildat (1); Mainmenu.layout (L,T,R,B); } @Override Public Booleanontouchevent (Motionevent event) {Switch(Event.getaction ()) { CaseMotionEvent.ACTION_DOWN:downX=Event.getx (); Break; CaseMotionEvent.ACTION_MOVE:moveX=Event.getx (); //The amount of offsets/changes that will occur intScrollx= (int) (downx-MoveX); //the calculation will scroll to the position, to determine whether it will go out, beyond. Do not execute Scrollby//Getscrollx () The position currently scrolled to intNEWPOSITION=GETSCROLLX () +Scrollx; if(Newposition<-getchildat (0). Getmeasuredwidth ()) {//Limit left boundaryScrollTo (-getchildat (0). Getmeasuredwidth (), 0); } Else if(newposition>0) {//Limit right BoundaryScrollTo (0, 0); } Else{ //let the amount of change take effectScrollby (scrollx,0); } downx=MoveX; Break; Casemotionevent.action_up:intleftcenter=-(int) (Getchildat (0). Getmeasuredwidth ()/2.0f); intstartx=Getscrollx (); intDx=0; //compare to half of the left panel, depending on where you are currently scrolling if(startx<leftcenter) { //Open, Switch to menu panelDx=-getchildat (0). Getmeasuredwidth ()-StartX; } Else{ //Close, switch to main paneldx=0-StartX; } intDuration=math.abs (dx*10); Scroller.startscroll (StartX,0, DX, 0, duration); Invalidate (); //Redraw Interface, Drawchild (), Computescroll (); Break; default: Break; } return true;//Consumer Events} @Override////2. Maintain the continuation of the animation Public voidComputescroll () {Super. Computescroll (); if(Scroller.computescrolloffset ()) {intcurrx=Scroller.getcurrx (); ScrollTo (Currx,0); Invalidate (); } }}
Three, mainactivity
PackageCom.example.mystudydemo;Importandroid.app.Activity;ImportAndroid.os.Bundle;ImportAndroid.view.Window;ImportAndroid.widget.Button;ImportAndroid.widget.TextView; Public classMainactivityextendsActivity {@Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate); Requestwindowfeature (Window.feature_no_title); Setcontentview (R.layout.activity_main); } }
Custom control Learning-anti-QQ slide bar