Переместить закусочную над нижней планкой
Я столкнулся с некоторыми проблемами с новой нижней панелью.
Я не могу принудительно переместить снэк-бар над нижней панелью (так сказано в руководстве по дизайну: https://www.google.com/design/spec/components/bottom-navigation.html#bottom-navigation-specs).
Это мой activity_main.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="start">
<include
layout="@layout/app_bar_main_activity"
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="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main_activity"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
Это мой app_bar_main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="test.tab_activity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/MyAppTheme.NoActionBar.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/main_activity_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/MyAppTheme.NoActionBar.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_add_white_24dp" />
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
style="@style/AppTabLayout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/colorPrimary"
/>
</LinearLayout>
Закусочная в main_activity.java выглядит следующим образом
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(findViewById(R.id.main_content), "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
![Wrong...snackbar should be above bottom bar]()
Ответы
Ответ 1
замените свой xml →
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="test.tab_activity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/main_activity_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/placeSnackBar">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
android:src="@drawable/ic_menu_gallery" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/colorPrimary" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
а код Snackbar будет
Snackbar.make(findViewById(R.id.placeSnackBar), "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Ответ 2
Вы можете сделать это программно, не загромождая свой xml с дополнительными координатамиLayouts, изменив поля закусочной.
Пример Java:
Snackbar snack = Snackbar.make(findViewById(R.id.coordinatorLayout),
"Your message", Snackbar.LENGTH_LONG);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)
snack.getView().getLayoutParams();
params.setMargins(leftMargin, topMargin, rightMargin, bottomBar.height);
snack.getView().setLayoutParams(params);
snack.show();
Отдельная линия Котлин:
Snackbar.make(coordinatorLayout, "Your message", Snackbar.LENGTH_LONG).apply {view.layoutParams = (view.layoutParams as CoordinatorLayout.LayoutParams).apply {setMargins(leftMargin, topMargin, rightMargin, bottomBar.height)}}.show()
Ответ 3
Предполагая, что вы работаете с CoordinatorLayout, вы можете изменить параметры компоновки закладок перед вызовом show(). Установив anchorId и anchorGravity, snackBar будет отображаться над нижней навигационной панелью:
val layoutParams = snackbar.view.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.anchorId = R.id.navigation //Id for your bottomNavBar or TabLayout
layoutParams.anchorGravity = Gravity.TOP
layoutParams.gravity = Gravity.TOP
snackbar.view.layoutParams = layoutParams
Ответ 4
Есть отличная статья о том, как использовать это ЗДЕСЬ. Там вы узнаете, как сделать закусочную над BottomNavigationBar
В основном код ниже представляет наиболее распространенное использование Toolbar
вместе с BottomNavigationBar
и FrameLayout
качестве контейнера фрагмента.
Важный! Заметить, что
- Кнопка ФАБ использует якорь для размещения correcty и useCompactPadding сохранить маржу
-
BottomNavigationView
использует layout_behaviour для обработки прокрутки и положения SnackBar
<android.support.design.widget.AppBarLayout
android:id="@+id/myAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:contentInsetStart="0dp"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="@menu/bottom_navigation"
app:layout_behavior="murt.shoppinglistapp.ui.BottomNavigationBehavior"
android:background="?android:attr/windowBackground"
/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_add_shopping_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:useCompatPadding="true"
app:srcCompat="@drawable/ic_add_24"
app:layout_anchor="@id/navigation_bar"
app:layout_anchorGravity="top|right"
android:layout_gravity="top"
/>
Внедрение поведения, не стесняйтесь использовать это! Это легко и дружелюбно;) (прокрутка)
class BottomNavigationBehavior : CoordinatorLayout.Behavior<BottomNavigationView> {
constructor(): super()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView,
dependency: View): Boolean {
if (dependency is Snackbar.SnackbarLayout) {
updateSnackbar(child, dependency)
}
return super.layoutDependsOn(parent, child, dependency)
}
private fun updateSnackbar(child: View, snackbarLayout: Snackbar.SnackbarLayout) {
if (snackbarLayout.layoutParams is CoordinatorLayout.LayoutParams) {
val params = snackbarLayout.layoutParams as CoordinatorLayout.LayoutParams
params.anchorId = child.id
params.anchorGravity = Gravity.TOP
params.gravity = Gravity.TOP
snackbarLayout.layoutParams = params
}
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
directTargetChild: View,
target: View,
nestedScrollAxes: Int
): Boolean {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
target: View,
dx: Int,
dy: Int,
consumed: IntArray
) {
if (dy < 0) {
showBottomNavigationView(child)
} else if (dy > 0) {
hideBottomNavigationView(child)
}
}
private fun hideBottomNavigationView(view: BottomNavigationView) {
view.animate().translationY(view.height.toFloat())
}
private fun showBottomNavigationView(view: BottomNavigationView) {
view.animate().translationY(0f)
}
}
Ответ 5
Я использую BottomNavigationView и Snackbar из библиотеки поддержки дизайна версии 25.3.1 на целевом OS kitkat, lollipop и Marshmallow. На леденец и выше Snackbar скрывается за BottomNavigationView, но в Kitkat BottomNavigationView скрывается за закусочной.
Я попытался показать Snackbar другим подходом. Когда Snackbar показан, BottomNavigationView переводится по оси Y (прокручивается вниз) с использованием свойства translationY и Interpolator. После того, как Snackbar ушел, BottomNavigationView снова появляется с тем же свойством translationY.
Скрытие BottomNavigationView (вниз):
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomNavigationView.getLayoutParams();
bottomNavigationView.animate().translationY(bottomNavigationView.getHeight() + layoutParams.bottomMargin).setInterpolator(new LinearInterpolator()).start();
Отображение отображения BottomNavigationView на экране:
bottomNavigationView.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
Ответ 6
Это можно сделать просто, если родительский макет был макетом координатора.
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)
snackbar.getView().getLayoutParams();
params.setAnchorId(R.id.navigation); //id of the bottom navigation view
params.gravity = Gravity.TOP;
params.anchorGravity = Gravity.TOP;
snackbar.getView().setLayoutParams(params);
Ответ 7
Чтобы достичь этого, вы должны позаботиться о том, чтобы ViewGroup, которую вы предоставляете для снэк-бара, представлял собой CoordinatorLayout, иначе он не будет отображаться над нижним меню навигации.
Ответ 8
С новым дизайном материалов есть простой способ:
Snackbar snackbar= Snackbar.make(view, text, duration);
snackbar.setAnchorView(bottomBar);
Таким образом, Snackbar
будет отображаться над BottomNavigationView
.