So stellen Sie ein, dass die Navigationsleiste von rechts nach links geöffnet wird

82

Zunächst einmal weiß ich, dass diese Frage hier schon einmal aufgetaucht ist, aber nachdem ich viel versucht habe, war ich immer noch nicht erfolgreich. Ich arbeite an dem Beispiel von der Android Developers Site .

Ich versuche, das Menü so einzustellen, dass es von rechts nach links geöffnet wird, anstatt wie es im Beispiel implementiert wird (von links nach rechts). Außerdem möchte ich die Schaltfläche zum Öffnen des Menüs auf die rechte Seite der Aktionsleiste verschieben. Ich habe hier auch einige Antworten rot, zum Beispiel in dieser Antwort .

Ich versuche, die Schwerkraft der Ansichten und Layouts zu ändern, erhalte jedoch den Fehler:

Keine Schubladenansicht mit absoluter Schwerkraft LINKS gefunden

Können Sie mir bitte helfen, herauszufinden, wo das Problem in meinem Code liegt und was ich ändern muss, um das Menü von rechts zu öffnen und die Schaltfläche in der Aktionsleiste nach rechts zu verschieben?

Der XML-Code ist hier:

<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>
galvan
quelle
Werfen Sie einen Blick auf github.com/Ali-Rezaei/SlidingDrawer , das es ermöglicht, mit wenigen Codezeilen von jeder Seite zu gleiten.
Ali
Siehe Antwort stackoverflow.com/a/44076363/5332645
Aman Saxena

Antworten:

153

Stellen Sie in Ihrem ListViewHauptlayout Ihre Schwerkraft auf rechts:

android:layout_gravity="right" 

Auch in Ihrem Code:

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

hoffe, es funktioniert :)

Rudi
quelle
2
@ Rudi: Kennst du die Antwort des zweiten Teils? Ich meine, wie man die Aktionsleiste von rechts nach links macht. (Die Richtung des Schubladen- und Navigationssymbols ändert sich ebenfalls.)
Alireza Farahani
@alireza warum verwendest du keine angepasste Aktionsleiste?
Rudi
@ Rudi: Du meinst setCustomViewMethode? Wenn ja, würde es Ihnen etwas ausmachen, einige Links einzufügen, die zeigen, wie das geht?
Alireza Farahani
@alireza Ich meinte, anstatt die Aktionsleiste oben in Ihrer Ansicht zu verwenden, erstellen Sie Ihre benutzerdefinierte Aktionsleiste in Ihrer Haupt-XML und richten Sie sie nach Ihren Wünschen ein.
Rudi
@Rudi: Aber wie kann ich dann das gleiche Verhalten wie bei der Navigation nach oben und beim Öffnen und Schließen von Schubladen erreichen? Muss ich sie von Grund auf neu implementieren?
Alireza Farahani
61

Fügen Sie diesen Code zum Manifest hinzu:

<application android:supportsRtl="true">

und schreiben Sie dann diesen Code auf Oncreate:

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

Für mich geht das. ;)

Amir Bax
quelle
1
Dies ist die richtige Antwort. Stellen Sie einfach die Schwerkraft Ihrer Listenansicht ein, um zu beginnen, und verwenden Sie dann diesen Code. Alles sollte in Ordnung sein
Mahdi Giveie
9
Es funktioniert jedoch, setLayoutDirection (View.LAYOUT_DIRECTION_RTL) ist für API über 17, so dass Sie dies nicht für API niedriger verwenden können
Milad
6
Wird dies nicht das gesamte Layout der Aktivität umdrehen, auch nicht das toStartOf / toEndOf usw.?
TWiStErRob
13
Das ist eine falsche Antwort. Das gesamte Aktivitätslayout wird von rechts nach links gespiegelt.
Tarun
1
Ich dachte, es ist eine schnelle Lösung, aber keine richtige.
Sidhanshu
37

LÖSUNG


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);
            }
        }
    });
//...
}
Volodymyr Kulyk
quelle
2
Funktioniert super. Das Symbolleistensymbol wird jedoch weiterhin links angezeigt. Wie kann ich das Symbol für die Umschalttaste auch nach rechts bringen?
Darush
Ich gab android: layout_gravity = "end" sowohl für Drawerlayout als auch für NavigationView, es funktioniert gut.
Varotariya Vajsi
toolbar.setNavigationOnClickListenererfordert min Api Level 21 :(
SepJaPro2.4
@ SepJaPro2.4 ja, aber 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
Fügen Sie android: layoutDirection = "rtl" in Ihrem AppBarLayout-XML hinzu, um die Umschalttaste nach rechts zu setzen
Terranology
4

Diese Antwort ist nützlich, um die Navigation von rechts nach links zu öffnen, aber es gibt keine Lösung, das Symbol auf die rechte Seite zu setzen. Dieser Code kann das Problem beheben. Wenn Sie es drawerals ersten und ViewCompat.LAYOUT_DIRECTION_RTLals zweiten Parameter angeben, wird das gesamte Layout auf RTL gesetzt. Es ist eine schnelle und einfache Lösung, aber ich denke nicht, dass es eine richtige Lösung für diejenigen sein kann, die nur festlegen möchten, dass das Menü von rechts nach links geöffnet wird und das Symbol auf der rechten Seite angezeigt wird. (Obwohl es von Ihrem Zweck abhängt.) Ich schlage jedoch vor, das toolbaranstelle des zu geben drawer. Auf diese Weise wurde nur die Symbolleiste zu RTL. Ich denke, die Kombination dieser beiden Antworten kann genau das tun, was Sie wollen.

Nach diesen Beschreibungen sollte Ihr Code folgendermaßen aussehen:

(Fügen Sie diese Zeilen zur onCreate-Methode hinzu.)

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

Beachten Sie, dass Sie die Schublade endgültig machen sollten, sonst wird folgende Fehlermeldung angezeigt:

Der Zugriff auf die Variable 'Schublade' erfolgt innerhalb der inneren Klasse und muss als endgültig deklariert werden

Und vergessen Sie nicht, endanstelle von startin onNavigationItemSelectedMethode zu verwenden:

drawer.closeDrawer(GravityCompat.END);

und in Ihrer 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>
Reyhaneh Sharifzadeh
quelle
3

Hier ist die Dokumentation zur Schublade, und Sie können sie anscheinend so konfigurieren, dass sie von links oder rechts herausgezogen werden kann.

Die Positionierung und das Layout der Schubladen werden mithilfe des Attributs android: layout_gravity in untergeordneten Ansichten gesteuert, das der Seite der Ansicht entspricht, aus der die Schublade hervorgehen soll: links oder rechts. (Oder starten / beenden Sie auf Plattformversionen, die die Layoutrichtung unterstützen.)

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

Super
quelle
Ich habe diese Antwort schon einmal gesehen und sie auch in meiner Frage erwähnt.
Galvan
In Ordnung. Versuchen Sie es endstatt rightin der Schwerkraft. EDIT: Entfernen Sie android:layout_gravity="right"aus dem android.support...DrawerLayoutund wechseln Sie android:layout_gravity="right"nach android:layout_gravity="end"innenListView
KickAss
1
Ich habe immer noch den Fehler: Keine Schubladenansicht mit absoluter Schwerkraft LINKS gefunden. Ich habe dem Manifest android hinzugefügt: supportRtl = "true", und in der XML unter dem drawerLayout habe ich android hinzugefügt: layoutDirection = "rtl", und dann öffnet sich das Menü auf der rechten Seite, aber jetzt wird es nicht geschlossen, wenn ich auf das klicke Menüschaltfläche (in der Aktionsleiste), wenn ich auf ein Element in der Liste klicke oder außerhalb der Liste, die geschlossen wird, aber nein, wenn ich auf die Menüschaltfläche in der Aktionsleiste klicke, irgendwelche Ideen warum?
Galvan
Ich bin mir nicht ganz sicher, aber ... da sich die Richtung und Position der Schublade jetzt ändert, sollten Sie in Ihrer Aktivität gemäß dem Android-Beispiel die Kippschaltermethode / den Tasten-Listener verwenden und prüfen, ob dies erforderlich ist geändert, so dass es schließen kann, indem es nach rechts verschoben wird. Es könnte sein, dass das Halten des Menüs bereits links ist (dh versteckt ist), sodass es nicht geschlossen wird (wenn das Sinn macht) ...
KickAss
Leute, ich mache auch das Gleiche, aber wenn ich laoutDirection = "rtl" benutze, muss ich minSdk auf 17 ändern, aber meine App muss API Level 10 unterstützen. Könnt ihr mir helfen, damit meine App API 10 unterstützt?
Aditya
3

Schauen Sie sich das an: Schieben Sie ExpandableListView im DrawerLayout-Formular von rechts nach links

Ich gehe davon aus, dass Sie ActionBarDrawerToggle implementiert haben. Der Trick besteht darin, die onOptionsItemSelected(MenuItem item)Methode im ActionBarDrawerToggle-Objekt folgendermaßen zu überschreiben :

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

Stellen Sie sicher und rufen Sie dies onOptionsItemSelected(MenuItem item)in der Aktivität auf:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

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

return super.onOptionsItemSelected(item);
}

Auf diese Weise können Sie die Home-Button-Funktion verwenden. Um die Schaltfläche auf die rechte Seite der Aktionsleiste zu verschieben, müssen Sie ein benutzerdefiniertes Aktionselement und möglicherweise einige andere Elemente implementieren, damit es wie gewünscht funktioniert.

d370urn3ur
quelle
3

das Hauptproblem mit dem folgenden Fehler:

Keine Schubladenansicht mit absoluter Schwerkraft LINKS gefunden

ist das, du hast das definiert

android:layout_gravity="right"

für die Listenansicht rechts, aber versuchen Sie, die Schublade von links zu öffnen, indem Sie diese Funktion aufrufen:

mDrawerToggle.syncState();

und klicken Sie auf das Hamburger-Symbol!

Kommentieren Sie einfach die obige Funktion und versuchen Sie, das Öffnen / Schließen des Menüs zu handhaben, wie @Rudi sagte!

par4301
quelle
3

Ich habe dieses Problem gelöst, indem ich die Schwerkraft der Navigationsansicht geändert habe

android: layout_gravity

zu beenden statt zu beginnen

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

Es hat bei mir funktioniert.

Abdulaziz Alnahhas
quelle
2

Sie sollten diesen Code zunächst in Ihre AppManifest.xml im Anwendungs-Tag einfügen:

android:supportsRtl="true"

Fügen Sie dann in Ihre Datei activity_main.xml diesen Code ein:

android:layout_direction="rtl"
Shabnam Esmaeili
quelle
Das ist die beste Lösung aller Zeiten. Sie retten meinen Tag, danke
Ahmed Mousa,
2

Ich habe die folgenden Änderungen am Beispiel für die Navigation Drawer-Aktivität in Android Studio vorgenommen. Mit Unterstützungsbibliotheken 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 (download ic_menu_white_24px von https://material.io/icons/ ):

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

In activity_main.xml ändern

android:layout_gravity="start"

zu

android:layout_gravity="end"
Mathias Jeppsson
quelle
2

Das Öffnen über RTL ist nicht gut für die Benutzererfahrung. Um auf das Gebietsschema des Benutzers zu reagieren, habe ich meinen DrawerLayout-Parametern die folgende Zeile hinzugefügt:

android:layoutDirection="locale"

Es wurde meinem AppBarLayout hinzugefügt, damit das Hamburger-Layout auch der Öffnungsrichtung der Schublade entspricht.

arbel03
quelle
1

DrawerLayout- Eigenschaften android:layout_gravity="right|end"und tools:openDrawer="end" NavigationView- Eigenschaft 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);
            }
        }
    });
//...
}
Ashvin Solanki
quelle