Przede wszystkim wiem, że to pytanie pojawiło się tutaj wcześniej, ale po wielu próbach nadal mi się nie udało. Pracuję na przykładzie ze strony Android Developers .
Próbuję ustawić menu tak, aby było otwierane od prawej do lewej, zamiast tego, jak jest to implementowane w przykładzie (od lewej do prawej). Ponadto chcę przenieść przycisk otwierania menu na prawą stronę paska akcji. Podkreśliłem też tutaj niektóre odpowiedzi, na przykład w tej odpowiedzi .
Próbuję zmienić grawitację widoków i układy ale wyskakuje mi błąd:
nie znaleziono widoku szuflady z grawitacją absolutną LEWA
Czy możesz mi pomóc dowiedzieć się, na czym polega problem w moim kodzie i co powinienem zmienić, aby ustawić menu na otwieranie z prawej strony i przesunąć przycisk paska akcji na prawą stronę?
kod xml jest tutaj:
<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>
Odpowiedzi:
W głównym układzie ustaw
ListView
grawitację w prawo:android:layout_gravity="right"
Również w Twoim kodzie:
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; } };
mam nadzieję, że zadziała :)
źródło
setCustomView
metodę? Jeśli tak, czy mógłbyś wkleić kilka linków pokazujących, jak to zrobić?Dodaj ten kod do manifestu:
<application android:supportsRtl="true">
a następnie napisz ten kod w Oncreate:
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Mi to pasuje. ;)
źródło
ROZWIĄZANIE
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); } } }); //... }
źródło
toolbar.setNavigationOnClickListener
wymaga min. poziomu Api 21 :(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)Ta odpowiedź jest przydatna, aby ustawić nawigację od prawej do lewej, ale nie ma rozwiązania, aby ustawić jej ikonę na prawą stronę. Ten kod może to naprawić. Jeśli podasz mu
drawer
jako pierwszy parametr iViewCompat.LAYOUT_DIRECTION_RTL
jako drugi parametr, układ wejściowy zostanie ustawiony na RTL. Jest to szybkie i proste rozwiązanie, ale nie sądzę, aby było to właściwe rozwiązanie dla tych, którzy chcą tylko ustawić otwieranie menu od prawej do lewej i ustawić jego ikonę po prawej stronie. (Chociaż jest to zależne od twojego celu.) Jednak sugeruję podanietoolbar
zamiastdrawer
. W ten sposób tylko pasek narzędzi stał się RTL. Więc myślę, że połączenie tych 2 odpowiedzi może zrobić dokładnie to, co chcesz.Zgodnie z tymi opisami Twój kod powinien wyglądać tak:
(Dodaj te linie do metody 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); } });
Zauważ, że powinieneś ustawić szufladę jako ostateczną, w przeciwnym razie pojawi się ten błąd:
I nie zapomnij użyć
end
zamiaststart
wonNavigationItemSelected
metodzie:drawer.closeDrawer(GravityCompat.END);
oraz w Twoim pliku 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>
źródło
Oto dokumentacja szuflady i wygląda na to, że można ją skonfigurować tak, aby wysuwała się z lewej lub prawej strony.
http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
źródło
end
zamiastright
grawitacji. EDYCJA: Usuńandroid:layout_gravity="right"
zandroid.support...DrawerLayout
i zmieńandroid:layout_gravity="right"
naandroid:layout_gravity="end"
wnętrzeListView
Spójrz na to: slide ExpandableListView w formularzu DrawerLayout od prawej do lewej
Zakładam, że masz zaimplementowaną ActionBarDrawerToggle, sztuczka polega na zastąpieniu
onOptionsItemSelected(MenuItem item)
metody wewnątrz obiektu ActionBarDrawerToggle za pomocą tego:@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; }
upewnij się i zadzwoń do tego z
onOptionsItemSelected(MenuItem item)
poziomu działania:@Override public boolean onOptionsItemSelected(MenuItem item) { if(mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); }
Umożliwi to korzystanie z funkcji przycisku strony głównej. Aby przenieść przycisk na prawą stronę paska akcji, będziesz musiał zaimplementować niestandardowy element akcji, a być może kilka innych rzeczy, aby działał tak, jak chcesz.
źródło
główny problem z następującym błędem:
nie znaleziono widoku szuflady z grawitacją absolutną LEWA
jest to, że zdefiniowałeś
android:layout_gravity="right"
dla widoku listy po prawej, ale spróbuj otworzyć szufladę od lewej, wywołując tę funkcję:
mDrawerToggle.syncState();
i klikając ikonę hamburgera!
po prostu skomentuj powyższą funkcję i spróbuj obsłużyć otwieranie / zamykanie menu, tak jak powiedział @Rudi!
źródło
Rozwiązałem ten problem, zmieniając wagę widoku nawigacji
do końca zamiast od początku
<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" />
U mnie to zadziałało.
źródło
Najpierw należy umieścić ten kod w swoim AppManifest.xml w tagu aplikacji:
android:supportsRtl="true"
następnie w pliku activity_main.xml umieść ten fragment kodu:
android:layout_direction="rtl"
źródło
Zrobiłem następującą modyfikację przykładu działania szuflady nawigacji w Android Studio. Z bibliotekami wsparcia 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 (pobierz ic_menu_white_24px z 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>
W activity_main.xml zmień
android:layout_gravity="start"
do
android:layout_gravity="end"
źródło
Otwieranie go z rtl nie jest dobre dla wrażenia użytkownika, aby reagować na ustawienia regionalne użytkownika, właśnie dodałem następujący wiersz do moich parametrów DrawerLayout:
android:layoutDirection="locale"
Dodano go do mojego AppBarLayout, aby układ hamburgerów pasował również do kierunku otwierania szuflady.
źródło
DrawerLayout Właściwości
android:layout_gravity="right|end"
itools:openDrawer="end"
NavigationView nieruchomościandroid: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); } } }); //... }
źródło