ナビゲーションドロワーを右から左に開くように設定する方法


83

まず第一に、私はこの質問が以前にここに現れたことを知っていますが、たくさん試した後、私はまだ成功しませんでした。私はAndroidDevelopersサイトの例に取り組んでい ます

例での実装方法(左から右)ではなく、メニューを右から左に開くように設定しようとしています。さらに、メニューを開くボタンをアクションバーの右側に移動したいと思います。また、ここでいくつかの回答を赤字にします。たとえば、この回答です。

ビューとレイアウトの重力を変更しようとしましたが、エラーが発生します:

絶対重力左で引き出しビューが見つかりません

メニューを右から開くように設定し、アクションバーボタンを右側に移動するには、コードの問題点と何を変更すればよいかを理解するのを手伝ってもらえますか?

xmlコードはここにあります:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_gravity="right"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layoutDirection="rtl"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ListView android:id="@+id/left_drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="right"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="10dp"
        android:background="#111"/>

</android.support.v4.widget.DrawerLayout>


見てみましょうgithub.com/Ali-Rezaei/SlidingDrawer数行のコードで任意の側からスライドさせることが可能となります。
アリ

回答:


154

メインレイアウトで、ListView重力を右に設定します。

android:layout_gravity="right" 

あなたのコードにも:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
            R.drawable.ic_drawer, R.string.drawer_open,
            R.string.drawer_close) {

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
                mDrawerLayout.closeDrawer(Gravity.RIGHT);
            } 
            else {
                mDrawerLayout.openDrawer(Gravity.RIGHT);
            }
        }
        return false;
    }
};

それがうまくいくことを願っています:)


2
@ルディ:第二部の答えを知っていますか?アクションバーを右から左に作成する方法を意味します。(引き出しと上ナビゲーションアイコンの方向も変わります)
Alireza Farahani 2014

@alirezaカスタマイズされたアクションバーを使用しないのはなぜですか?
ルディ2014

@ルディ:あなたはsetCustomView方法を意味しますか?はいの場合、その方法を示すリンクを貼り付けていただけませんか。
Alireza Farahani 2014

@alirezaつまり、ビューの上部でアクションバーを使用する代わりに、メインxmlでカスタムアクションバーを作成し、必要に応じて設定します。
ルディ2014

@Rudi:では、アップナビゲーションや引き出しの開閉アニメーションなど、同じ動作を実現するにはどうすればよいですか?それらを最初から実装する必要がありますか?
Alireza Farahani 2014

61

このコードをマニフェストに追加します。

<application android:supportsRtl="true">

次に、Oncreateで次のコードを記述します。

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

わたしにはできる。;)


1
これは正解です。リストビューの重力を設定して開始し、このコードを使用すると、すべてが正常になります
Mahdi Giveie 2014

9
動作していますが、setLayoutDirection(View.LAYOUT_DIRECTION_RTL)は17を超えるAPI用であるため、これをAPIの下位に使用することはできません
Milad

6
これにより、toStartOf / toEndOfなど、アクティビティのレイアウト全体が反転しませんか?
TWiStErRob 2015年

13
これは間違った答えです。アクティビティのレイアウト全体を右から左に反転します。
タルン

1
それは迅速な解決策ですが、正しい解決策ではないと思いました。
sidhanshu 2017年

37

解決


your_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="end">

    <include layout="@layout/app_bar_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:itemTextColor="@color/black"
        app:menu="@menu/activity_root_drawer" />

</android.support.v4.widget.DrawerLayout>

YourActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
//...
toolbar = (Toolbar) findViewById(R.id.toolbar);

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT)) {
                drawer.closeDrawer(Gravity.RIGHT);
            } else {
                drawer.openDrawer(Gravity.RIGHT);
            }
        }
    });
//...
}

2
よく働く。ただし、ツールバーアイコンはまだ左側に表示されます。トグルボタンアイコンも右に移動するにはどうすればよいですか?
ダーリウーシュ2018

DrawerlayoutとNavigationViewの両方にandroid:layout_gravity = "end"を指定しましたが、正常に機能しています。
varotariya vajsi 2018

toolbar.setNavigationOnClickListener最小Apiレベル21が必要です:(
SepJaPro2.4 2018年

@ SepJaPro2.4はい、しかしFrom August 2018, new apps must target at least Android 8.0 (API level 26). From November 2018, app updates must target Android 8.0 (API level 26).(Google)
Volodymyr Kulyk

2
アンドロイド追加:layoutDirection =右にトグルボタンを設定するには、あなたのAppBarLayout XMLでの「RTL」
Terranology

4

この回答は、ナビゲーションを右から左に開くように設定するのに役立ちますが、アイコンを右側に設定する解決策はありません。このコードで修正できます。あなたはそれを与える場合はdrawer、その最初のパラメータとして及びViewCompat.LAYOUT_DIRECTION_RTLその第二のparamとして、entierレイアウトはRTLに設定されます。これは迅速で簡単な解決策ですが、メニューを右から左に開くように設定し、アイコンを右側に設定するだけの人にとっては正しい解決策ではないと思います。(ただし、目的によって異なります。)ただし、のtoolbar代わりにを与えることをお勧めしdrawerます。このようにして、ツールバーだけがRTLになりました。したがって、これら2つの答えを組み合わせることで、まさにあなたが望むことを実行できると思います。

これらの説明によると、コードは次のようになります。

(これらの行をonCreateメソッドに追加します)

final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); // Set it final to fix the error that will be mention below.

    ViewCompat.setLayoutDirection(toolbar, ViewCompat.LAYOUT_DIRECTION_RTL);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (drawer.isDrawerOpen(Gravity.RIGHT))
                drawer.closeDrawer(Gravity.RIGHT);
            else
                drawer.openDrawer(Gravity.RIGHT);
        }
    });

ドロワーをファイナルにする必要があることに注意してください。そうしないと、次のエラーが発生します。

変数 'drawer'は内部クラス内からアクセスされ、finalとして宣言する必要があります

そして、メソッドのend代わりに使用することを忘れないでください:startonNavigationItemSelected

drawer.closeDrawer(GravityCompat.END);

そしてあなたのactivity_main.xmlで

<android.support.v4.widget.DrawerLayout 
   android:id="@+id/drawer_layout"
   tools:openDrawer="end">

   <android.support.design.widget.NavigationView
      android:id="@+id/nav_view"
      android:layout_gravity="end"/>
</android.support.v4.widget.DrawerLayout>

3

これが引き出しのドキュメントで、左または右から引き出すように設定できるようです。

ドロワーの配置とレイアウトは、ドロワーを表示するビューのどちら側(左または右)に対応する子ビューのandroid:layout_gravity属性を使用して制御されます。(または、レイアウト方向をサポートするプラットフォームバージョンで開始/終了します。)

http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html


私は以前にこの答えを見ました、そして私は私の質問でもそれについて言及しました。
ガルバン2013

はい。重力のend代わりに使用してみてくださいright。編集:android:layout_gravity="right"から削除して内部にandroid.support...DrawerLayout変更android:layout_gravity="right"android:layout_gravity="end"ListView
KickAss 2013

1
それでもエラーが発生しました。絶対重力が左のドロワービューが見つかりません。マニフェストandroid:supportsRtl = "true"に追加し、drawerLayoutの下のxmlにandroid:layoutDirection = "rtl"を追加すると、右側にメニューが開きますが、クリックしても閉じません。リスト内の項目をクリックするか、リストの外側をクリックするとメニューボタン(アクションバー内)は閉じますが、アクションバーのメニューボタンをクリックすると表示されません。理由は何ですか。
ガルバン2013

完全にはわかりませんが...ドロワーの方向と位置が変更されたため、アクティビティでは、Androidの例のように、Toggleスイッチメソッド/ボタンリスナーが必要です。必要かどうかを確認してください。 RightToLeftを移動して閉じることがわかるように変更されました。(それが理にかなっている場合)、それは閉じて文句を言わないので、それは...メニューのホールドを考えることは(隠されたIE)左にすでにあるかもしれない
もう最高

皆さん、私も同じようなことをしていますが、laoutDirection = "rtl"を使用する場合は、minSdkを17に変更する必要がありますが、アプリはAPIレベル10をサポートする必要があります。アプリがAPI 10をサポートできるように、皆さんが私を助けてくれますか。
aditya 2013年

3

これを見てください:DrawerLayoutフォームでExpandableListViewを右から左にスライドさせます

ActionBarDrawerToggleが実装されていると仮定します。トリックはonOptionsItemSelected(MenuItem item)、ActionBarDrawerToggleオブジェクト内のメソッドを次のようにオーバーライドすることです。

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item != null && item.getItemId() == android.R.id.home) {
            if (mDrawer.isDrawerOpen(Gravity.RIGHT)) {
                mDrawer.closeDrawer(Gravity.RIGHT);
            } else {
                mDrawer.openDrawer(Gravity.RIGHT);
            }
            return true;
        }
        return false;
    }

onOptionsItemSelected(MenuItem item)アクティビティでこれを確認して呼び出します。

@Override
public boolean onOptionsItemSelected(MenuItem item) {

if(mDrawerToggle.onOptionsItemSelected(item)) {
    return true;
}

return super.onOptionsItemSelected(item);
}

これにより、ホームボタン機能を使用できるようになります。ボタンをアクションバーの右側に移動するには、カスタムアクションアイテムを実装する必要があります。また、必要に応じて機能させるために他の要素を実装する必要があります。


3

次のエラーの主な問題:

絶対重力左で引き出しビューが見つかりません

つまり、あなたは

android:layout_gravity="right"

右のリストビューの場合、ただし、次の関数を呼び出して、左からドロワーを開こうとします。

mDrawerToggle.syncState();

ハンバーガーアイコンをクリック!

上記の関数にコメントして、@ Rudiが言ったようにメニューの開閉を処理してみてください!


3

ナビゲーションビューの重力を変更することで、この問題を解決しました

android:layout_gravity

開始する代わりに終了する

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/activity_drawer" />

それは私のために働いた。


2

まず、次のコードをAppManifest.xmlのアプリケーションタグに配置する必要があります。

android:supportsRtl="true"

次に、activity_main.xmlファイルに次のコードを配置します。

android:layout_direction="rtl"

それはこれまでで最高の解決策です、あなたは私の一日のおかげを救います
Ahmed Mousa 2017年

2

AndroidStudioのNavigationDrawerActivityの例に次の変更を加えました。サポートライブラリ付き25.3.1。

MainActivity.java:

private DrawerLayout mDrawerLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
        mDrawerLayout.closeDrawer(GravityCompat.END);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    switch (itemId) {
        case android.R.id.home:
            finish();
            return true;

        case R.id.action_right_drawer:
            if (mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
                mDrawerLayout.closeDrawer(GravityCompat.END);
            } else {
                mDrawerLayout.openDrawer(GravityCompat.END);
            }
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.

    mDrawerLayout.closeDrawer(GravityCompat.END);
    return true;
}

main.xml(https://material.io/icons/からic_menu_white_24pxをダウンロード):

<?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/action_right_drawer"
        android:title="Drawer menu"
        android:icon="@drawable/ic_menu_white_24px"
        android:orderInCategory="100"
        app:showAsAction="always" />
</menu>

activity_main.xmlの変更

android:layout_gravity="start"

android:layout_gravity="end"

2

rtlから開くことは、ユーザーエクスペリエンスにとって良くありません。ユーザーロケールに応答するようにするために、DrawerLayoutパラメーターに次の行を追加しました。

android:layoutDirection="locale"

これをAppBarLayoutに追加して、ハンバーガーのレイアウトを引き出しの開口方向にも一致させました。


1

DrawerLayoutプロパティ android:layout_gravity="right|end"tools:openDrawer="end" NavigationViewプロパティ android:layout_gravity="end"

XML Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:layout_gravity="right|end"
    tools:openDrawer="end">

    <include layout="@layout/content_main" />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Java Code

// Appropriate Click Event or Menu Item Click Event

if (drawerLayout.isDrawerOpen(GravityCompat.END)) 
{
     drawerLayout.closeDrawer(GravityCompat.END);
} 
else 
{
     drawerLayout.openDrawer(GravityCompat.END);
}
//With Toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);

drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();

toolbar.setNavigationOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            //Gravity.END or Gravity.RIGHT
            if (drawer.isDrawerOpen(Gravity.END)) {
                drawer.closeDrawer(Gravity.END);
            } else {
                drawer.openDrawer(Gravity.END);
            }
        }
    });
//...
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.