Как открыть навигационный ящик справа налево
Прежде всего, я знаю, что этот вопрос появился здесь раньше, но после многих попыток все еще не получилось.
Я работаю над примером из
Сайт разработчиков Android.
Я пытаюсь открыть меню справа налево, а не как его реализация в примере (слева направо). Кроме того, я хочу переместить открытую кнопку меню в правую сторону панели действий. Я также добавил некоторые ответы здесь, например в этом ответе.
Я пытаюсь изменить гравитацию представлений и макетов, но получаю ошибку:
не найдено ни одного обзора ящика с абсолютной силой тяжести LEFT
Не могли бы вы помочь мне разобраться, в чем проблема в моем коде, и что я должен изменить, чтобы открыть меню справа и переместить кнопку панели действий вправо?
код 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>
Ответы
Ответ 1
В вашем основном макете установите гравитацию 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
Добавьте этот код в манифест:
<application android:supportsRtl="true">
а затем напишите этот код в Oncreate:
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Это работает для меня.;)
Ответ 3
Решение
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);
}
}
});
//...
}
Ответ 4
Этот ответ полезен для того, чтобы навигация была открыта справа налево, но у него нет решения, чтобы установить ее значок справа. Этот код может это исправить. Если вы зададите ему drawer
в качестве первого параметра и ViewCompat.LAYOUT_DIRECTION_RTL
в качестве второго параметра, для более полной компоновки будет установлено значение 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
в методе onNavigationItemSelected
:
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>
Ответ 5
Вот документация на ящике, и кажется, что вы можете настроить ее на выход слева или справа.
Позиционирование и расположение ящика управляется с помощью атрибута android: layout_gravity для дочерних представлений, соответствующих той стороне представления, которую вы хотите, чтобы ящик выходил из: влево или вправо. (Или начало/конец на версиях платформы, поддерживающих направление макета.)
http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
Ответ 6
Взгляните на это: слайд 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)
в Управлении:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
Это позволит вам использовать функциональность кнопки "Дом". Чтобы переместить кнопку в правую сторону панели действий, вам нужно будет реализовать пользовательский элемент действия и, возможно, некоторые другие вещи, чтобы заставить его работать так, как вы хотите.
Ответ 7
Вы должны сначала поместить этот код в свой AppManifest.xml в тег приложения:
android:supportsRtl="true"
то в файле activity_main.xml поместите этот фрагмент кода:
android:layout_direction="rtl"
Ответ 8
основная проблема со следующей ошибкой:
не найдено ни одного обзора ящика с абсолютной силой тяжести LEFT
заключается в том, что вы определили
android:layout_gravity="right"
для просмотра списка справа, но попробуйте открыть ящик слева, вызвав эту функцию:
mDrawerToggle.syncState();
и нажав на значок гамбургера!
просто прокомментируйте вышеприведенную функцию и попытайтесь обработать открытие/закрытие меню, например, @Rudi!
Ответ 9
Я решил эту проблему, изменив гравитацию навигационного обзора
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" />
Это сработало для меня.
Ответ 10
Я сделал следующую модификацию для примера Activity Drawer в 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"
Ответ 11
Сделать его открытым с rtl не очень удобно для пользователей, чтобы он реагировал на пользовательский язык. Я просто добавил следующую строку к моим параметрам DrawerLayout:
android:layoutDirection="locale"
Добавил его в мой AppBarLayout, чтобы макет гамбургера соответствовал направлению открытия ящика.