DrawerLayout with multiple stacks and navigation component - android

I'm using the navigation component and in one of my fragments I have a drawer layout with multiple stacks.
Navigation
Splash -> Login -> Home(drawer layout)
From Home i would like use drawerlayout and 2 fragments stacks.
Home (Search Nav Graph) -> Search -> S1 -> S2
Home (Profile Nav Graph) -> Profile -> P1
HomeFragment
class HomeFragment : BaseFragment() {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val appBarConfiguration = AppBarConfiguration(setOf(R.navigation.search_nav_graph, R.navigation.profile_nav_graph), binding.drawerLayout)
binding.collapsingToolbarLayout.setupWithNavController(binding.toolbar, findNavController(), appBarConfiguration)
return binding.root
}
}
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="#dimen/tall_toolbar_height">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="top"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<!-- The main content view where fragments are loaded -->
<FrameLayout
android:id="#+id/flContent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/drawer_header" />
<include layout="#layout/drawer_menu" />
</LinearLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
I guess the way to go is using flContent but I don't find the way to match the pieces according to documentation

I've finally realize that i can just use the childFragmentManager
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val busquedaNavHostFragment = NavHostFragment.create(R.navigation.search)
val perfilNavHostFragment = NavHostFragment.create(R.navigation.profile)
childFragmentManager.beginTransaction()
.add(R.id.flContent, busquedaNavHostFragment, busquedaNavHostFragment.javaClass.name)
.add(R.id.flContent, perfilNavHostFragment, perfilNavHostFragment.javaClass.name)
.hide(busquedaNavHostFragment)
.show(perfilNavHostFragment)
.commitNow()
binding.navView.findViewById<LinearLayout>(R.id.ll_perfil).setOnClickListener {
binding.drawerLayout.close()
childFragmentManager.beginTransaction()
.show(perfilNavHostFragment)
.hide(busquedaNavHostFragment)
.commit()
}
binding.navView.findViewById<LinearLayout>(R.id.ll_busqueda).setOnClickListener {
binding.drawerLayout.close()
childFragmentManager.beginTransaction()
.show(busquedaNavHostFragment)
.hide(perfilNavHostFragment)
.commit()
}
return binding.root
}

Related

Changing view property with View Binding has no effect

I'm trying to use view binding to change the visibility of an ImageView in the app bar when I navigate to a certain fragment. The structure of the app is pretty much like the stock Navigation Drawer Activity in Android Studio.
Since the app_bar_main.xml layout is included in activity_main.xml and has an id, I figured I should be able to just inflate the ActivityMainBinding and reference the app bar and its views. So I do like in the documentation to access the binding from the fragment:
private var _binding: FragmentChooseVehicleBinding? = null
private var _mainBinding: ActivityMainBinding? = null
private val binding get() = _binding!!
private val mainBinding get() = _mainBinding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
chooseVehicleViewModel =
ViewModelProvider(this).get(ChooseVehicleViewModel::class.java)
_binding = FragmentChooseVehicleBinding.inflate(inflater, container, false)
_mainBinding = ActivityMainBinding.inflate(layoutInflater)
mainBinding.appBarMain.appBarLogo.visibility = View.GONE //This has no effect in the UI
return binding.root
}
I checked with debugging and the visibility property on appBarLogo changed correctly and is the right value in onStart()/onResume() as well, but the image still appears in the UI.
Another thing I tried is to inflate the app bar view binding directly, like this:
override fun onStart() {
super.onStart()
val binding = AppBarMainBinding.inflate(layoutInflater)
binding.appBarLogo.visibility = View.GONE
}
Still no change in the UI; the image remains visible. The only thing that works is the old findViewById:
override fun onStart() {
super.onStart()
val appBarLogo = activity?.findViewById<ImageView>(R.id.appBarLogo)
appBarLogo?.visibility = View.GONE
}
Any idea what I'm doing wrong? Thanks.
Update: Here are the layout files (thanks Michael):
activity_main.xml:
<?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"
tools:openDrawer="start">
<include
android:id="#+id/app_bar_main"
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="#dimen/nav_header_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#drawable/gradient_black"
app:itemIconTint="#color/white"
app:itemTextColor="#FFFFFF"
app:menu="#menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
app_bar_main.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"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.company.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#drawable/gradient_red"
app:popupTheme="#style/Theme.company.PopupOverlay">
<ImageView
android:layout_width="match_parent"
android:id="#+id/appBarLogo"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_marginRight="70dp"
app:srcCompat="#drawable/ic_logo_company" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Fragment not showing properly

I am learning Kotlin, have done apps in Java before. I now have an activity with an Toolbar, NavigationView and a FragmentView. As I understand this: Fragment Tutorial, it is enough to state the Fragment in the xml file.
I have this activity_main.xml file:
<?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/navigation_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/main_app_bar_layout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/holo_blue_light"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/main_navigation"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/main_app_bar_layout"
app:menu="#menu/navigation_menu" />
<androidx.fragment.app.FragmentContainerView
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_container"
android:name="com.example.android.camerax.tflite.TestFragment"
tools:layout="#layout/fragment_test" />
</androidx.drawerlayout.widget.DrawerLayout>
This is the fragment_test.xml:
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context="com.example.android.camerax.tflite.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:textAlignment="center"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
This is the Activity:
class CameraActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var fragment: CameraActivityFragment
private lateinit var navigationDrawer: DrawerLayout
private lateinit var toolbar: Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
navigationDrawer = findViewById(R.id.navigation_container)
// Handle user consent update
toolbar = findViewById(R.id.main_toolbar)
setSupportActionBar(toolbar)
val toggle = ActionBarDrawerToggle(
this,
navigationDrawer,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
navigationDrawer.addDrawerListener(toggle)
toggle.syncState()
val navigationView: NavigationView = findViewById(R.id.main_navigation)
navigationView.setNavigationItemSelectedListener(this)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.show_recordings) {
// Start ListView
}
navigationDrawer.closeDrawer(GravityCompat.START)
return true
}
}
and here is the TestFragment.kt:
class TestFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_test, container, false)
}
companion object {
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
TestFragment().apply {
arguments = Bundle().apply {
}
}
}
}
I have tried to read the link above and also follow this: AndroidTrivia. No success and I really think this is quite basic and should work. When I run the debugger I can see that onCreateView is called in the Fragment, as it should be.
This is how it looks. Sometimes, the text blips on the screen. So seems like something is overwriting the fragment?
screenshot 1
screenshot 2
Edit
After updating the FragmentContainerView with elevation 9dp, the text is shown. But now the Toolbar is hidden, although there is a marginTop for the FragmentContainerView. Screenshot 3
There are two things I would like to suggest here.
First if possible get back to ConstraintLayout as in your last answer. It is not necessary for sure, but would recommend.
Second the blipping might be cause by the difference in elevation since the elevation of NavigationView is different.
So I suggest you add the following to your FragmentContainerView
<androidx.fragment.app.FragmentContainerView
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_container"
android:elevation="9dp"
android:name="com.example.android.camerax.tflite.TestFragment"
tools:layout="#layout/fragment_test" />
9dp since most Android Views like BottomNav etc are upto 8dp
Also would recommend to modify your fragment_test as follows and add the following
<androidx.constraintlayout.widget.ConstraintLayout 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:background="#android:color/white"
android:clickable="true"
android:focusable="true"
tools:context="com.example.android.camerax.tflite.TestFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"
android:textAlignment="center"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

EditText not resize based on content in a viewpager

I have a simple structure. MainActivity with BottomNavigationView and NavController. In this nav controller, i have 4 items. One of them is FavoritesFragment. This fragment has simple layout:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".view.main.favorites.FavoritesFragment">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tlTest"
android:layout_width="match_parent"
android:layout_height="40dp"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/vpTest"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/tlTest"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
With following code:
FragmentAdapter
package com.lust.ahri.view.main.favorites
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.lust.ahri.view.base.BaseFragment
class TestAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
private val fragments: MutableList<BaseFragment> = mutableListOf()
private val titles: MutableList<String> = mutableListOf()
override fun getItem(position: Int): Fragment {
return fragments[position]
}
override fun getCount(): Int {
return fragments.count()
}
override fun getPageTitle(position: Int): CharSequence? {
return titles[position]
}
fun addFragment(fragment: BaseFragment, title: String) {
fragments.add(fragment)
titles.add(title)
}
}
And FavoritesFragment
class FavoritesFragment : BaseFragment() {
private lateinit var adapter: TestAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_favorites, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adapter = TestAdapter(childFragmentManager)
adapter.addFragment(TestFragment(), "Test1")
adapter.addFragment(TestFragment(), "Test2")
vpTest.adapter = adapter
tlTest.setupWithViewPager(vpTest)
}
}
Problem that in my TestFragment i have layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center|top">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/test1"
android:layout_width="wrap_content"
android:hint="10"
android:maxLines="1"
android:maxLength="10"
android:layout_height="50dp" />
<EditText
android:layout_width="wrap_content"
android:hint="10"
android:maxLines="1"
android:maxLength="10"
android:layout_height="50dp"
android:layout_marginTop="70dp" />
</LinearLayout>
I meant that my edit texts will resize with wrap_content like as usual depending on the number of characters, in fact, the fields do not change their size but are only cropped.
I tried to change my layout to Constraint, Relative or another, but actually i couldn't find any solution.
I need an answer how to make edit texts change their width in a viewpager like a default layout behaviour and why it's happening.
I think the problem lies in the ViewPager 0dp height. Try this
<RelativeLayout 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.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/Widget.AppCompat.PopupMenu.Overflow" />
<android.support.design.widget.TabLayout
android:id="#+id/mtab_ID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#color/colorAccent1"
app:tabIndicatorHeight="3dp"
app:tabTextColor="#color/colorWhite"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/mViewpager_ID"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/app_bar"
/>
</RelativeLayout>

TabLayout in fragment show empty white bar

Currently my application have a MainActivity with the toolbar and a framelayout used to display fragment.
Now I have a fragment with tablayout and viewpager. But the tablayout in this fragment shows an empty whitebar instead of the tab content. I am still able to swipe left and right to change viewpager content which is my other fragment but unable to view the tablayout.
So this is my fragment with tablayout and viewpager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
android:fillViewport="true"/>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
class UploadPreviewFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_upload_preview, container, false)
val viewPager = view.findViewById<ViewPager>(R.id.view_pager)
val tabLayout = view.findViewById<TabLayout>(R.id.tab_layout)
val fragmentManager = UploadPagerAdapter(childFragmentManager)
viewPager.adapter = fragmentManager
tabLayout.setupWithViewPager(view_pager)
return view
}
}
My adapter calss:
class UploadPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> {
UploadPdfFragment()
}
else -> {
UploadImagesFragment()
}
}
}
override fun getCount(): Int {
return 2
}
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0 -> {
"Upload PDF"
}
else -> {
"Upload Images"
}
}
}
}
And Screenshot for the tablayout:
https://i.stack.imgur.com/9mFWU.png
EDIT
I have found the solution to my problem from https://developer.android.com/reference/android/support/design/widget/TabLayout. The problem cause by this is because the xml file, the tablayout should place inside the viewpager.
<LinearLayout
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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
android:background="#color/colorPrimary"
android:fillViewport="true"/>
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
change ParentFragmentManager to childFargmentManager in Adapter definition

Android BottomNavigationBar moves when one of pages contains collapsing toolbar and fitSystemWindows is true

I have an activity with BottomNavigationView. On navigation I show/hide two fragments one of which is empty fragment, another contains collapsing toolbar which has set android:fitsSystemWindows="true" .
The problem is - when I open collapsing fragment tab and navigate back to empty fragment, the bottom navigation view moving down (out of device screen).
The problem doesn't appear, when I don't set fitSystemWindows true or when I create a new fragment every time user changes tab. But I need to keep both.
Is there a solution to escape this?
Here is the sample code, which behaves so
Activity
class BottomNavigationActivity : AppCompatActivity() {
private var currentFragment: Fragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_bottom_navigation)
val bottomNavigationView = findViewById(R.id.activity_navigation__bottom_bar) as BottomNavigationView
bottomNavigationView.setOnNavigationItemSelectedListener {
when (it.itemId) {
R.id.action_blank -> openFragment(findFragment("blank")?:BlankFragment(), "blank")
R.id.action_collapsed -> openFragment(findFragment("collapsing")?:CollapsingFragment(), "collapsing")
}
return#setOnNavigationItemSelectedListener true
}
}
private fun openFragment(fragment: Fragment, tag: String) {
val fragmentTransaction = supportFragmentManager.beginTransaction()
currentFragment?.let {
fragmentTransaction.hide(it)
}
if (!fragment.isAdded) {
fragmentTransaction.add(R.id.container, fragment, tag);
}
if (!fragment.isVisible) {
fragmentTransaction.show(fragment)
}
currentFragment = fragment
fragmentTransaction.commitAllowingStateLoss()
}
private fun findFragment(tag: String): Fragment? {
return supportFragmentManager.findFragmentByTag(tag)
}
}
Activity layout xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#id/activity_navigation__bottom_bar"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/activity_navigation__bottom_bar"
android:background="#color/colorPrimary"
android:layout_width="match_parent"
app:menu="#menu/menu"
android:layout_height="56dp"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
the empty Fragment
class BlankFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_blank, container, false)
}
}
empty fragment layout xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="blank fragment"/>
</FrameLayout>
the collapsing Fragment
class CollapsingFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_collapsing, container, false)
}
}
collapsing fragment layout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/fragment_collapsing_toolbar__appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/fragment_collapsing_toolbar__container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="?android:attr/windowBackground"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/fragment_collapsing_toolbar__toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="collapsing fragment"
app:titleMarginStart="72dp"
app:titleMarginEnd="72dp"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/fragment_collapsing_toolbar__content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
here is the menu
<?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_blank"
android:enabled="true"
android:title="blank"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_collapsed"
android:enabled="true"
android:title="collapsing"
app:showAsAction="ifRoom" />
</menu>
Thanks.

Categories

Resources