Я начинаю работать над приложением Android, и я хотел бы использовать этот новый компонент навигации Android.И это приложение будет иметь нижнюю навигационную панель с 5 разделами, и каждый из этих разделов должен хранить backstack фрагментов.Например, если я нахожусь в первом разделе и перехожу к результатам поиска, а затем к карте, и теперь, если я щелкаю по разделу профиля в нижнем виде навигации, а затем возвращаюсь к первому разделу, мне все равно нужно находиться на экране карты.Итак, я нашел эту среднюю статью , которая объясняет одно возможное решение этой проблемы, которое состоит в том, чтобы иметь 5 фрагментов NavHostFragments, и вы показываете / скрываете их в зависимости от того, какой раздел вы находитесь.Также еще одна вещь, что когда вы переходите к некоторым фрагментам, мне нужно скрыть нижнюю навигационную панель ... Итак, я создал новый проект, чтобы опробовать некоторые вещи, и получил странные результаты.Я не могу полностью понять, как работает атрибут fitsSystemWindows
, и у меня появилось странное поведение ...
Во-первых, заголовок вПанель инструментов на 4-м изображении имеет некоторое верхнее поле, и я понятия не имею, почему ... Я создал совершенно новый проект без фрагментов, только одно основное действие с точно такой же компоновкой, и у меня нет верхнего поля для заголовка на панели инструментов.
Во-вторых, когда я возвращаюсь со страницы Safari к результатам поиска (4-е и 5-е изображения), нижний навигационный вид наполовину виден без причины ...
Как исправить 4-е и5-е изображения?Также еще один вопрос относительно атрибута fitSystemWindows
.Разве кнопка поиска на первом изображении не должна находиться под строкой состояния?Поскольку fitSystemWindows=true
не применяется к ConstraintLayout -> FrameLayout -> ExploreFragment's ConstraintLayout
.Единственное место, где атрибут fitSystemWindows
добавляется в XML, находится в файле fragment_safari.xml
.
Примечание : минимальный уровень поддержки API Android, который мне нужно поддерживать, равен 21 (Lollipop и выше).
Вот код:
Тема, которую я использую
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowBackground">@color/colorWindowBackground</item>
</style>
MainActivity.kt
class MainActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
currentController = findNavController(R.id.explore_nav_host_fragment)
exploreNavController.addOnNavigatedListener { controller, destination ->
when (destination.id) {
R.id.searchResultsFragment,
R.id.exploreFragment -> showBottomNavigation()
R.id.safariFragment,
R.id.filterFragment -> hideBottomNavigation()
}
}
bottom_navigation.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.action_explore -> {
currentController = exploreNavController
explore_nav_host_frame.visibility = View.VISIBLE
favorite_nav_host_frame.visibility = View.GONE
reviews_nav_host_frame.visibility = View.GONE
true
}
R.id.action_favorite -> {
currentController = favoriteNavController
explore_nav_host_frame.visibility = View.GONE
favorite_nav_host_frame.visibility = View.VISIBLE
reviews_nav_host_frame.visibility = View.GONE
true
}
else -> false
}
}
}
fun hideBottomNavigation() {
if(isBottomNavigationViewVisible) {
bottom_navigation.visibility = View.GONE
isBottomNavigationViewVisible = false
}
}
fun showBottomNavigation() {
if(!isBottomNavigationViewVisible) {
bottom_navigation.visibility = View.VISIBLE
isBottomNavigationViewVisible = true
}
}
// ...
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/explore_nav_host_frame"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<fragment
android:id="@+id/explore_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/nav_graph_explore" />
</FrameLayout>
<FrameLayout
android:id="@+id/favorite_nav_host_frame"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<fragment
android:id="@+id/favorite_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/nav_graph_favorite" />
</FrameLayout>
<FrameLayout
android:id="@+id/reviews_nav_host_frame"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<fragment
android:id="@+id/reviews_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="@navigation/nav_graph_reviews" />
</FrameLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:background="@android:color/darker_gray"
android:elevation="4dp"
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_menu"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
SafariFragment.kt
class SafariFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_safari, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
initActionBar()
addTextViews()
}
private fun initActionBar() {
(activity as AppCompatActivity).apply {
setSupportActionBar(toolbar)
supportActionBar?.apply {
title = "Safari"
setDisplayHomeAsUpEnabled(true)
setDisplayShowHomeEnabled(true)
}
}
}
private fun addTextViews() {
for(i in 1..10) {
content_scroll.addView(TextView(context).apply {
text = i.toString()
setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent))
setTextColor(ContextCompat.getColor(context, R.color.white))
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
48*3
).apply {
setMargins(36, 36, 36, 36)
}
})
}
}
}
фрагмент_safari.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="240dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed|snap">
<ImageView
android:id="@+id/safari_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:srcCompat="@drawable/safari"
tools:ignore="ContentDescription" />
<View
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@drawable/toolbar_gradient"
android:fitsSystemWindows="true" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/content_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
РЕДАКТИРОВАТЬ:
Мне удалось исправить нижнюю навигационную панель. Я установил CoordinatorLayout в качестве корня для макета каждого фрагмента и применил fitsSystemWindows=true
CoordinatorLayout и первому ребенку.Но я все еще получаю проблемы с заголовком на панели инструментов.