Прежде всего, я знаю, что этот вопрос появлялся здесь раньше, но после многих попыток мне все равно не удалось. Я работаю над примером с сайта разработчиков Android .
Я пытаюсь настроить открытие меню справа налево, а не как его реализация в примере (слева направо). Кроме того, я хочу переместить кнопку открытого меню в правую часть панели действий. Я также выделил здесь несколько ответов, например, в этом ответе .
Я пытаюсь изменить серьезность представлений и макетов, но получаю сообщение об ошибке:
не найден вид ящика с абсолютной гравитацией СЛЕВА
Не могли бы вы помочь мне выяснить, в чем проблема в моем коде, и что мне нужно изменить, чтобы меню открывалось справа, а кнопку панели действий перемещать вправо?
код 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>
Ответы:
В основном макете установите
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; } };
надеюсь, что это работает :)
источник
setCustomView
метод? Если да, не могли бы вы вставить несколько ссылок, показывающих, как это сделать?Добавьте этот код в манифест:
<application android:supportsRtl="true">
а затем напишите этот код в Oncreate:
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Меня устраивает. ;)
источник
РЕШЕНИЕ
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); } } }); //... }
источник
toolbar.setNavigationOnClickListener
требуется минимальный уровень 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).
(гугл)Этот ответ полезен для открытия навигации справа налево, но у него нет решения, чтобы установить значок справа. Этот код может это исправить. Если вы укажете ему в
drawer
качестве первого параметра и вViewCompat.LAYOUT_DIRECTION_RTL
качестве второго параметра, для макета entier будет установлено значение RTL. Это быстрое и простое решение, но я не думаю, что оно может быть правильным для тех, кто хочет, чтобы меню открывалось только справа налево, а его значок располагался справа. (Хотя это зависит от вашей цели.) Однако я предлагаю использоватьtoolbar
вместоdrawer
. Таким образом, панель инструментов стала RTL. Поэтому я думаю, что комбинация этих двух ответов может сделать именно то, что вы хотите.Согласно этим описаниям ваш код должен быть таким:
(Добавьте эти строки в метод 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); } });
Обратите внимание, что вы должны сделать ящик окончательным, иначе вы получите эту ошибку:
И не забудьте использовать
end
вместо методаstart
inonNavigationItemSelected
: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>
источник
Вот документация на ящик, и, похоже, вы можете настроить его так, чтобы он выдвигался слева или справа.
http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
источник
end
вместоright
силы тяжести. РЕДАКТИРОВАТЬ: удалитьandroid:layout_gravity="right"
изandroid.support...DrawerLayout
и заменитьandroid:layout_gravity="right"
наandroid:layout_gravity="end"
внутреннюю частьListView
Взгляните на это: сдвиньте ExpandableListView в форму DrawerLayout справа налево
Я предполагаю, что у вас реализован 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)
в Activity:@Override public boolean onOptionsItemSelected(MenuItem item) { if(mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); }
Это позволит вам использовать функциональность кнопки «Домой». Чтобы переместить кнопку в правую часть панели действий, вам нужно будет реализовать настраиваемый элемент действия и, возможно, некоторые другие вещи, чтобы заставить его работать так, как вы хотите.
источник
основная проблема со следующей ошибкой:
не найден вид ящика с абсолютной гравитацией СЛЕВА
это вы определили
android:layout_gravity="right"
для просмотра списка справа, но попробуйте открыть ящик слева, вызвав эту функцию:
mDrawerToggle.syncState();
и нажав на значок гамбургера!
просто прокомментируйте вышеуказанную функцию и попробуйте обработать открытие / закрытие меню, как сказал @Rudi!
источник
Я решил эту проблему, изменив степень тяжести навигации
чтобы закончить вместо начала
<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" />
У меня это сработало.
источник
Сначала вы должны поместить этот код в свой AppManifest.xml в теге приложения:
android:supportsRtl="true"
затем в файле activity_main.xml поместите этот фрагмент кода:
android:layout_direction="rtl"
источник
Я внес следующую модификацию в пример активности навигационного ящика в Android Studio. С библиотеками поддержки 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 (загрузите ic_menu_white_24px с 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>
В activity_main.xml измените
android:layout_gravity="start"
к
android:layout_gravity="end"
источник
Открытие его из rtl не очень удобно для пользователя, чтобы он реагировал на локаль пользователя, я просто добавил следующую строку в свои параметры DrawerLayout:
android:layoutDirection="locale"
Добавил его в свой AppBarLayout, чтобы макет гамбургера соответствовал направлению открытия ящика.
источник
Свойства DrawerLayout
android:layout_gravity="right|end"
и свойствоtools:openDrawer="end"
NavigationViewandroid: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); } } }); //... }
источник