ホームページ  >  記事  >  Java  >  Android は DrawerLayout を使用して QQ のような双方向スライド メニューを実装します

Android は DrawerLayout を使用して QQ のような双方向スライド メニューを実装します

高洛峰
高洛峰オリジナル
2017-01-07 14:42:091274ブラウズ

1. 概要

私は以前、Android QQ5.0 の模倣性の高い横スライド メニュー効果のカスタム コントロールを作成しましたが、それは偶然にも DrawerLayout を参照したときに QQ5.2 で右側のメニューを追加したものでした。一方では、公式のほうが興味があるのですが、一方で、これは本当に使いやすいので、QQ5.2 の双方向サイド スライドのデモを作成して共有しました。みんなとともに。

まずレンダリングを見てみましょう:

Android は DrawerLayout を使用して QQ のような双方向スライド メニューを実装します

DrawerLayoutはとても便利です。使い方を見てみましょう~

2. DrawerLayoutの使用

最初のレイアウトとしてDrawerLayoutを使用します。その中の 1 つのビューはコンテンツ領域、2 番目のビューは左側のメニュー、3 番目のビューは右側のスライド メニューです。 現在、3 番目のビューはオプションです。

最初のビューの幅と高さは match_parent に設定する必要があります。これは当然のことです。

2 番目と 3 番目のビューは、android:layout_gravity="left" と android:layout_gravity="right" を設定する必要があり、高さは match_parent に設定され、幅は固定値 (側面の幅) になります。スライドメニュー。

上記のようにレイアウト ファイルを作成し、それをアクティビティに設定して、左右のスライドを追加します。非常に簡単ですよね~~~

たとえば、レイアウト ファイル:

<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>

ここにメイン コンテンツがあります。エリアは RelativeLayout です

メニューに使用される 2 つのフラグメントは、左側が 200 dp、右側が 100 dp です

さて、レイアウト ファイルを確認した後、詳細なコードを見てみましょう。

3. コードは最良の教師です

1. 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>

は実際には積み上げられたレイアウトです~~楽しいです~

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); 
  } 
}
の対応するレイアウトファイル。

:

<?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>

アイコンが見つけにくいことを除けば、とてもシンプルです~~

3. MainActivity
MainActivityのレイアウトファイルが投稿されました~~

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); 
  } 
  
}

まあ、コードには基本的にコメントはありません~~ ~ビザはどこですか?それは本当にコメントするものが何もないからです。

いくつかのポイント:

1. QQ の右側のメニューをクリックして表示する必要があるため、DrawerLayout を初期化するときに、mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED,Gravity.RIGHT); はプログラミングのみで実行できることを意味します。それが浮かび上がります。

次に、ポップアップした後、ジェスチャをスライドして戻すことができる必要があるので、OpenRightMenu に次のように書きました:

mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED,Gravity.RIGHT);

最後に、onDrawerClosed コールバックで mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT); の設定を続けます

アニメーションは、nineoldandroids のさまざまなオフセットとスケーリング率の計算を参照してください。 Android の模倣度の高い QQ5.0 のサイドスライド メニュー効果のカスタム コントロールは、基本的に同じです。唯一の違いは、ViewHelper.setTranslationX(mContent, mMenu.getMeasuredWidth() * (1 -scale)); が設定されていることです。コンテンツ: デフォルトではコンテンツはメニューの右側にあり、メニューはメニューの上にあるため、メニューによって描画される距離に基づいてコンテンツの X 方向のオフセットを設定します。

これで、基本的にどのようなサイドスライド メニュー効果も作成できるようになりました。興味があれば、DrawerLayout を使用して、このブログのすべての効果を実現できます。Android では、さまざまなフォームの双方向の横スライド メニューが実装される予定です。

3. setDrawerListener

setDrawerListener を使用して、メニューの開閉などを監視することもできます。ここで、現在の操作がどのメニューであるかの判断は、重力を使って判断することもできると思います~~

まあ、それ以上ではありません。DrawerLayoutはデフォルトでは境界線からしかメニューを描画できませんが、QQは描画します。メニューのジェスチャ領域は比較的広いので、興味がある場合は、ActivityのonTouchEventを書き換えて、左右のスライドジェスチャが素晴らしい場合は、メニューをポップアップするのは面倒ではないはずです。 ~~

その他 Android は DrawerLayout を使用して QQ 模倣を実装します 双方向スライド メニューに関連する記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。