Viewdraghelper practice of imitation Android official side-slide menu Navigationdrawer effect

Source: Internet
Author: User

People who believe in mobile apps are familiar with the slide menu bar, dropdown, bounce, bounce, and more, and almost every major mobile app, whether iOS or Android, can be seen. 2.3 ago, a lot of third parties such as Slidingmenu, Menudrawer, Actionbarsherlock and so on have greatly enriched and deepened this kind of interaction idea. Allows a small screen to accommodate more interactive interfaces. Also this trend, Android official in V4 finally launched the drawerlayout. Show the importance and affirmation of skidding.


It's nagging. Went to see the source code of Drawerlayout and the official example. The officially supplied Drawerlayout is well packaged and ready to use. The principle of implementation is to use the viewdraghelper mentioned in the previous article to achieve. and Viewdraghelper with view and Scroller, To achieve a real drag-and-drop effect. In order to deepen the understanding of viewdraghelper, this time I also to imitate the official Navigationdrawer sample effect, do it. Please put it in the wrong place. Thank you, ha.


Because it is imitation, so the principle is the same as Navigationdrawer, the picture also most borrowed the official example of the picture. The key to Navigationdrawer's implementation is drawerlayout, which utilizes viewdraghelper. Of course, not only viewdraghelper, but also other auxiliary classes. Because Navigationdrawer is a combination of Actionbar, Actionbardrawertoggle is also used as a switch to toggle the slide-off menu. But in fact, to achieve a similar official effect, only with Viewdraghelper is enough. Because our aim is to learn viewdraghelper. If you do not know the viewdraghelper, you can go to the previous article or the official website to read the document first to understand the relevant information.


First (amount, mobile phone recording screen after the effect of =,=)



The following code:

Layout file:

Activity_main.xm

<com.alextam.simpleslidingmenu.slidingmenu xmlns:android= "Http://schemas.android.com/apk/res/android" Android : id= "@+id/drawer_layout" android:layout_width= "match_parent" android:layout_height= "Match_parent" Android:orienta tion= "Horizontal" > <framelayout android:id= "@+id/content_frame" android:layout_width= "Match_par         Ent "android:layout_height=" match_parent "android:background=" @drawable/bg "/> <linearlayout        Android:id= "@+id/ly_main_a" android:layout_width= "240DP" android:layout_height= "Match_parent" android:orientation= "vertical" android:background= "#888888" android:alpha= "0.0" Android:layout_gravi            ty= "Start" android:layout_marginleft= " -220DP" android:padding= "20DP" > <listview Android:id= "@+id/listview_main" android:layout_width= "Match_parent" android:layout_height= "match   _parent "/>  </LinearLayout></com.alextam.simpleslidingmenu.SlidingMenu> 

Look at the source code of the official example, it is not difficult to understand why this layout, because the side menu bar layout is hidden outside the screen. I also borrowed from this idea.


Drawerlayout is an officially packaged view class. So I also used viewdraghelper to encapsulate a similar view, Slidingmenu.

public class Slidingmenu extends Framelayout {private static final String TAG = "Slidingmenu";    Private Viewdraghelper Mdraghelper;  private int minValue = 20;    DP//EDGE contact threshold private int leftedgeminsize = MinValue;    Child view left value private int leftvalue;    Private View childviewa;//private view CHILDVIEWBG;    Private Boolean slidingmenuopensate = false;    Note A few points,//if Mdraghelper.settlecapturedviewat (left, top); method to move the view, you must use Invalidate () to refresh the view to be effective.    Public Slidingmenu (Context context) {this (context,null);    } public Slidingmenu (context context, AttributeSet Attrs) {this (context,attrs,0); } public Slidingmenu (context context, AttributeSet attrs, int defstyleattr) {Super (context, Attrs, Defstylea        TTR);    Init ();  } private void Init () {//For improved compatibility, the new Viewdraghelper () method is private and can only be created using the Create () factory method Mdraghelper =        Viewdraghelper.create (This, 1.0f, New Scallback ()); int evalue = (int) typedvalue.applydimension (Typedvalue.complex_unit_dip, MinValue, Getresources (). Getdisplaymetrics ()); Leftedgeminsize = evalue > MinValue?    Evalue:minvalue; } @Override protected void Onfinishinflate () {Childviewa = Findviewbyid (r.id.ly_main_a);//CHILDVIEWB    G = Findviewbyid (r.id.content_frame);        }/** * Drag monitoring interface, to use Viewdraghelper, must implement the interface class */private class Scallback extends Viewdraghelper.callback {  The method must implement @Override public boolean Trycaptureview (View child, int pointerid) {return        Childviewa = = Child; } @Override public void onviewdragstatechanged (int.) {if (state = = Viewdraghelper.sta                    Te_idle) {//idle if (childviewa.getleft () >= 0) {                Slidingmenuopensate = true;      }} else if (state = = viewdraghelper.state_dragging)      {//drag} else if (state = = viewdraghelper.state_settling) { Settle}} @Override public void onviewpositionchanged (View changedview, int lef T, int top, int dx, int dy) {if (Changedview! = null) {float ALP = (float) (1                + (float) math.abs (left)/leftvalue);                if (left <= leftvalue) {changedview.setalpha (0.0f);                } else {Changedview.setalpha (ALP);        }}} @Override public void onviewcaptured (View capturedchild, int activepointerid) {}        When a gesture releases a child View, the method is recalled @Override public void onviewreleased (View releasedchild, float xvel, float yvel)            {if (Xvel < LEFTVALUE/3) {closemenu (); } else if ((Xvel + LEFTVALUE/3) > 0) {openmenu ();                    } else {if (Releasedchild.getleft () > (LEFTVALUE-LEFTVALUE/3)) {                Openmenu ();                } else {closemenu (); }}} @Override public void onedgetouched (int edgeflags, int pointerid) {} @Overrid        E public boolean onedgelock (int edgeflags) {return false; } @Override public void onedgedragstarted (int edgeflags, int. pointerid) {} @Override public in        T getorderedchildindex (int index) {return index;        } @Override public int getviewhorizontaldragrange (View child) {return 0;        } @Override public int getviewverticaldragrange (View child) {return leftvalue;    }//Implements the important method of horizontal dragging, the value returned is the value that implements the child view being dragged horizontally @Override    public int Clampviewpositionhorizontal (View child, int left, int dx) {final int paddingleft = GETPA            Ddingleft (); Limit the drag of a child view beyond the left and right edges of the parent view//If you return directly                    It is also possible. But the drag of the sub-view can slide out of the parent view position//FINAL int resultleft = Math.min (Math.max (Paddingleft,left),//            GetWidth ()-Getchildat (1). GetWidth ());//return resultleft;            Final int resultleft = Math.max (Leftvalue, Math.min (left,0));        return resultleft;            }//An important way to implement vertical drag @Override public int clampviewpositionvertical (View child, int top, int dy) {            Final int paddingtop = Getpaddingtop ();            Final int resulttop = Math.min (Math.max (Paddingtop,top), getheight ()-childviewa.getheight ());        return resulttop; }} @Override public boolean onintercepttouchevent (Motionevent ev) {final int action = Motioneventcomp        at.getactionmasked (EV); If (action = = Motionevent.action_cancel | | action = = MOTIONEVENT.ACTION_UP)            {if (mdraghelper! = null)//Cancel or finger release, all should Cancel () Mdraghelper.cancel ();        return false;    } return mdraghelper.shouldintercepttouchevent (EV);                } @Override public boolean ontouchevent (motionevent ev) {if (ev.getaction () = = Motionevent.action_up | |                Ev.getaction () = = Motionevent.action_cancel) {if (Childviewa! = null) { if (slidingmenuopensate && ev.getx () > Childviewa.getwidth ()) {Close                Menu ();            }}} if (Mdraghelper! = null) {mdraghelper.processtouchevent (EV);        return true;    } return false; } @Override public void Computescroll () {if (mdraghelper.continuesettling (True)) {Viewcompat.     Postinvalidateonanimation (this);   }} @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (cha        NGED,L,T,R,B);    Leftvalue = Leftedgeminsize-childviewa.getwidth (); } protected void Openmenu () {if (mdraghelper! = null) {if (MDRAGHELPER.SMOOTHSLIDEVIEWTO (ch                ildviewa,0,0)) {viewcompat.postinvalidateonanimation (this);            Slidingmenuopensate = true; }}} protected void Closemenu () {if (mdraghelper! = null) {if (mdraghelper.smoot                Hslideviewto (childviewa,leftvalue,0)) {viewcompat.postinvalidateonanimation (this);            Slidingmenuopensate = false;    }}}//Get side-slip menu bar Expand State Public Boolean getslidingmenuopensate () {return slidingmenuopensate; }}

The key to the whole process is 3 places, one is the viewdraghelper provided in the previous callback interface class to implement, callback interface provides the entire view drag or settle process monitoring method, very effective. The second is to handle the Ontouch event of the gesture touch. Third, set the edge size of the draggable view as needed. This value directly determines whether the view can be quickly and efficiently positioned to the gesture.

The purpose is to be familiar with Viewdraghelper this class and realize the effect of skidding, so simpleslidingmenu this class does not encapsulate is very complex, the idea is still able to see it. For unfamiliar things, my principle is generally done first to say, as to do well, How to optimize and so on, are waiting for a rough finished product out of the first. Otherwise Hu thought a lot of, and did nothing, efficiency is too low. Of course, the main idea is to have it.


Array of references in Strings.xml:

<string-array name= "Planets_array" >        <item>Mercury</item>        <item>venus</item >        <item>Earth</item>        <item>Mars</item>        <item>Jupiter</item>        <item>Saturn</item>        <item>Uranus</item>        <item>Neptune</item>    </string-array>


And then the mainacitvity.

public class Mainactivity extends Activity {private LinearLayout linearlayout;    Private ListView ListView;    Private Slidingmenu drawerlayout;    Private string[] mplanettitles;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.activity_main);        Drawerlayout = (slidingmenu) Findviewbyid (r.id.drawer_layout);        LinearLayout = (linearlayout) Findviewbyid (r.id.ly_main_a);        Mplanettitles = Getresources (). Getstringarray (R.array.planets_array);        ListView = (ListView) Findviewbyid (R.id.listview_main);        Listview.setadapter (New arrayadapter<string> (this,r.layout.drawer_list_item,mplanettitles));    Listview.setonitemclicklistener (New Draweritemclicklistener ()); } Private class Draweritemclicklistener implements Listview.onitemclicklistener {@Override public voi D Onitemclick (adapterview<?> parent, view view, int position, long ID)       {listview.setselection (position);        SelectItem (position); }} private void SelectItem (int position) {//update the main content by replacing fragments FRAGM        ent fragment = new Planetfragment ();        Bundle args = new bundle ();        Args.putint (planetfragment.arg_planet_number, position);        Fragment.setarguments (args);        Fragmentmanager Fragmentmanager = Getfragmentmanager ();        Fragmentmanager.begintransaction (). replace (R.id.content_frame, fragment). commit ();        Update selected item and title, then close the drawer listview.setitemchecked (position, true);    Slip-on menu Drawerlayout.closemenu (); } public static class Planetfragment extends Fragment {public static final String Arg_planet_number = "plane        T_number "; Public planetfragment () {//Empty constructor required for fragment subclasses} @Overrid E Public View Oncreateview (Layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {            View Rootview = inflater.inflate (R.layout.fragment_planet, container, false);            int i = getarguments (). GetInt (Arg_planet_number);            String Planet = Getresources (). Getstringarray (R.array.planets_array) [i]; int imageId = Getresources (). Getidentifier (Planet.tolowercase (Locale.getdefault ()), "drawable", Getacti            Vity (). Getpackagename ());            ((ImageView) Rootview.findviewbyid (R.id.image)). Setimageresource (ImageId);            Getactivity (). Settitle (planet);        return rootview; }    }}


The mainactivity implementation process, similar to Navigationdrawer, is to replace the layout of an ID with fragment. Here to illustrate, mainactivity in the creation and replacement of planetfragment related methods source code is the use of the sample source code.  After all, don't want to reinvent the wheel. The difference is that the example uses the ListView directly as a side-by-side menu, but this is a bit limited. So changed the layout, inside the ListView, so that the ListView can also be quoted. Of course layout can also be installed in other view or layout.


Finally back to the slippery side of the matter, sliding is a good choice of interaction. The authorities also gave guidance on this, placing the app's menu navigation on the left side and placing the function on the menu on the right. While skidding has been popular for quite a long time, there are now many mature third parties available. Viewdraghelper only offers a choice when it comes to its own realization. As to whether a good choice, with the specific needs and implementation of the relevant. Of course, Viewdraghelper is not confined to simply dragging a view or something. Combine it with ViewGroup, or some layout classes, to produce a container with a rich drag-and-drop effect. Then, this article is written here, thank you for reading. ^^



Viewdraghelper practice of imitation Android official side-slide menu Navigationdrawer effect

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.