Home > Java > javaTutorial > body text

Android uses DrawerLayout to implement QQ-like two-way sliding menu

高洛峰
Release: 2017-01-07 14:42:09
Original
1312 people have browsed it

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:

Android uses DrawerLayout to implement QQ-like two-way sliding menu

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>
Copy after login

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); 
  } 
}
Copy after login

:

<?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>
Copy after login

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); 
  } 
}
Copy after login

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>
Copy after login

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); 
  } 
  
}
Copy after login

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!


source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template