Home >Java >javaTutorial >Android uses DrawerLayout to implement QQ-like two-way sliding menu
1. Overview
I previously wrote an Android high-imitation QQ5.0 side-sliding menu effect custom control, which coincided with the addition of a right-side menu in QQ5.2, just in time to see After reading DrawerLayout, on the one hand, I am more interested in the official stuff; on the other hand, this thing is really convenient to use, so I simply wrote a demo, a high imitation of QQ5.2 two-way side sliding, to share with everyone.
First take a look at the renderings:
DrawerLayout is really convenient to use. Let’s take a look at the usage~
2. DrawerLayout Use
directly use DrawerLayout as the root layout, and then the first View inside it is the content area, the second View is the left menu, and the third View is the right side sliding menu. Currently The third one is optional.
The width and height of the first View should be set to match_parent, of course, this is natural.
The second and third Views need to set android:layout_gravity="left", and android:layout_gravity="right" and the height is set to match_parent, and the width is a fixed value, which is the width of the side-sliding menu.
Write a layout file according to the above description, and then set it to the Activity to add left and right side sliding. Isn’t it very simple~~~
For example, our layout file:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/id_drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/img_frame_background" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/qq" > <Button android:layout_width="40dp" android:layout_height="30dp" android:layout_marginTop="10dp" android:layout_alignParentRight="true" android:background="@drawable/youce" android:onClick="OpenRightMenu" /> </RelativeLayout> <fragment android:id="@+id/id_left_menu" android:name="com.zhy.demo_zhy_17_drawerlayout.MenuLeftFragment" android:layout_width="200dp" android:layout_height="match_parent" android:layout_gravity="left" android:tag="LEFT" /> <fragment android:id="@+id/id_right_menu" android:name="com.zhy.demo_zhy_17_drawerlayout.MenuRightFragment" android:layout_width="100dp" android:layout_height="match_parent" android:layout_gravity="right" android:tag="RIGHT" /> </android.support.v4.widget.DrawerLayout>
Here our main content area is RelativeLayout
The two Fragments used in the menu are 200dp on the left and 100dp on the right;
Okay, let’s look at our layout file , let’s take a look at our detailed code.
3. Code is the best teacher
1. The corresponding layout file of MenuLeftFragment
package com.zhy.demo_zhy_17_drawerlayout; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class MenuLeftFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.layout_menu, container, false); } }
:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00000000" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/one" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_1" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@id/one" android:text="第1个Item" android:textColor="#f0f0f0" android:textSize="20sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/two" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_2" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@id/two" android:text="第2个Item" android:textColor="#f0f0f0" android:textSize="20sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/three" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_3" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@id/three" android:text="第3个Item" android:textColor="#f0f0f0" android:textSize="20sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/four" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_4" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@id/four" android:text="第4个Item" android:textColor="#f0f0f0" android:textSize="20sp" /> </RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/five" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_marginTop="20dp" android:src="@drawable/img_5" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="20dp" android:layout_toRightOf="@id/five" android:text="第5个Item" android:textColor="#f0f0f0" android:textSize="20sp" /> </RelativeLayout> </LinearLayout> </RelativeLayout>
is actually piled up Layout~~Nothing to say~
2. MenuRightFragment
package com.zhy.demo_zhy_17_drawerlayout; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class MenuRightFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.menu_layout_right, container, false); } }
Corresponding layout file:
<?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:gravity="center_vertical" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" android:layout_marginBottom="20dp" android:orientation="vertical" > <ImageView android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/wode" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="扫一扫" android:textColor="#ffffff" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" android:layout_marginBottom="20dp" android:orientation="vertical" > <ImageView android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/saoma" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="讨论组" android:textColor="#ffffff" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" android:layout_marginBottom="20dp" android:orientation="vertical" > <ImageView android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/wode" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="扫一扫" android:textColor="#ffffff" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" android:layout_marginBottom="20dp" android:orientation="vertical" > <ImageView android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/saoma" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="讨论组" android:textColor="#ffffff" /> </LinearLayout> </LinearLayout>
is still very simple, except that the icon is difficult to find~~
3. MainActivity
The layout file of MainActivity has been posted~~
package com.zhy.demo_zhy_17_drawerlayout; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout.DrawerListener; import android.view.Gravity; import android.view.View; import android.view.Window; import com.nineoldandroids.view.ViewHelper; public class MainActivity extends FragmentActivity { private DrawerLayout mDrawerLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); initView(); initEvents(); } public void OpenRightMenu(View view) { mDrawerLayout.openDrawer(Gravity.RIGHT); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT); } private void initEvents() { mDrawerLayout.setDrawerListener(new DrawerListener() { @Override public void onDrawerStateChanged(int newState) { } @Override public void onDrawerSlide(View drawerView, float slideOffset) { View mContent = mDrawerLayout.getChildAt(0); View mMenu = drawerView; float scale = 1 - slideOffset; float rightScale = 0.8f + scale * 0.2f; if (drawerView.getTag().equals("LEFT")) { float leftScale = 1 - 0.3f * scale; ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); ViewHelper.setAlpha(mMenu, 0.6f + 0.4f * (1 - scale)); ViewHelper.setTranslationX(mContent, mMenu.getMeasuredWidth() * (1 - scale)); ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getMeasuredHeight() / 2); mContent.invalidate(); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); } else { ViewHelper.setTranslationX(mContent, -mMenu.getMeasuredWidth() * slideOffset); ViewHelper.setPivotX(mContent, mContent.getMeasuredWidth()); ViewHelper.setPivotY(mContent, mContent.getMeasuredHeight() / 2); mContent.invalidate(); ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); } } @Override public void onDrawerOpened(View drawerView) { } @Override public void onDrawerClosed(View drawerView) { mDrawerLayout.setDrawerLockMode( DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT); } }); } private void initView() { mDrawerLayout = (DrawerLayout) findViewById(R.id.id_drawerLayout); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT); } }
Well, the code basically has no comments~~Where is Visa? It's because there really isn't much to comment on.
A few points to mention:
1. In order to simulate the right menu of QQ, you need to click to appear, so when initializing DrawerLayout, use mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,Gravity.RIGHT ); means that only programming can pop it up.
Then after it pops up, the gesture needs to be able to slide back, so I wrote again in OpenRightMenu:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED,Gravity.RIGHT); UNLOCK it.
Finally, in the onDrawerClosed callback, continue to set mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,Gravity.RIGHT);
2. Animation effect
The animation uses nineoldandroids, about animation For the calculation of various offsets and scaling ratios, please refer to the Android high-imitation QQ5.0 side-sliding menu effect custom control that is basically the same. The only difference is that ViewHelper.setTranslationX(mContent, mMenu. getMeasuredWidth() * (1 - scale)); Let the Content be on the right side of the menu. By default, the Menu is above the menu, so we set the X-direction offset for the Content based on the distance drawn by the menu.
Okay, in fact, you can see that you can do this. Basically, any side sliding menu effect can be written. If you are interested, you can use DrawerLayout to realize all the effects of this blog: Android implements two-way side sliding menus with different forms. Custom controls are coming.
3. setDrawerListener
It can also be seen through the code. You can use setDrawerListener to monitor the opening and closing of the menu, etc. Here, the judgment of which menu the current operation is is based on TAG. I think it can also be judged using gravity~~
Okay, let’s stop talking. Since DrawerLayout can only draw menus from the boundary by default, However, the gesture area for drawing out the menu in QQ is relatively large. If you are interested, you can rewrite the onTouchEvent of the Activity and judge in it. If the left and right sliding gesture is amazing, it should not be troublesome to pop up the menu~~~
For more articles related to Android using DrawerLayout to implement a QQ-like two-way sliding menu, please pay attention to the PHP Chinese website!