Как установить навигационный ящик, который будет открыт справа налево
прежде всего, я знаю, что этот вопрос появился здесь раньше, но после многих попыток мне все равно не удалось. Я работаю на примере из сайт разработчиков 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>
11 ответов:
в вашем основном макете установите свой
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; } };
надеюсь, что это работает :)
добавьте этот код в манифесте:
<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>
Ваша активность.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); } } }); //... }
вот документация на ящике, и кажется, что вы можете настроить его, чтобы вытащить слева или справа.
позиционирование и макет ящика управляется с помощью атрибута android: layout_gravity на дочерних представлениях, соответствующих той стороне представления, с которой вы хотите, чтобы ящик появился: слева или справа. (Или начало / конец на версиях платформы, которые поддерживают макет направление.)
http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
вы должны сначала поместить этот код в свой AppManifest.xml в теге приложения:
android:supportsRtl="true"
затем в activity_main.xml-файл, поместите этот кусок кода:
android:layout_direction="rtl"
основная проблема со следующей ошибкой:
вид ящика не найден с абсолютной гравитацией слева
это то, что вы определили
android:layout_gravity="right"
для просмотра списка справа, но попробуйте открыть ящик слева, вызвав эту функцию:
mDrawerToggle.syncState();
и нажав на значок гамбургер!
просто прокомментируйте вышеуказанную функцию и попробуйте обработать открытие/закрытие меню, как сказал @Rudi!
Я решил эту проблему, изменив гравитацию navigationview до конец вместо start и это работает для меня
взгляните на это: слайд 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); }
Это позволит вам использовать функционал кнопки Home. Чтобы переместить кнопку в правую часть экрана панель действий вам придется реализовать пользовательский элемент действия, и, возможно, некоторые другие вещи, чтобы заставить его работать, как вы хотите.
Я сделал следующее изменение в Примере активности навигационного ящика в 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; }
главная.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 change
android:layout_gravity="start"
до
android:layout_gravity="end"
сделать его открытым из rtl не очень хорошо для пользовательского опыта, чтобы сделать его отзывчивым к пользовательской локали я просто добавил следующую строку в мои параметры DrawerLayout:
android:layoutDirection="locale"
добавил его в мой AppBarLayout, чтобы макет гамбургера соответствовал направлению открытия ящика.
ответ полезно установить навигацию, открытую справа налево, но у нее нет решения, чтобы установить ее значок справа. код может это исправить. Если вы дадите ему
drawer
в качестве первого param иViewCompat.LAYOUT_DIRECTION_RTL
в качестве второго параметра, весь макет будет установлен в 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); } });
обратите внимание, что вы должны сделать окончательный ящик, в противном случае вы получите это ошибка:
переменная 'ящик' доступна из внутреннего класса, должен быть объявлен финал
и не забудьте использовать
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>