I am applying navigation library to my project.
And I get this error:
android.view.InflateException: Binary XML file line #23: Binary XML file line #23: Error inflating class fragment
This is MainActivity.kt:
val fragmentManager = supportFragmentManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if(savedInstanceState == null){
fragmentManager.beginTransaction().add(R.id.nav_host_fragment, InitFragment()).commit()
}else{
}
}
This is activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:tint="#555"
tools:context="com.example.view.main.MainActivity">
<ImageView
android:id="#+id/iv_flame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph"/>
</RelativeLayout>
</layout>
This is InitFragment.kt
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
var binding = DataBindingUtil.inflate<FragmentInitBinding>(inflater, R.layout.fragment_init, container, false)
binding!!.initVm = InitViewModel(this#InitFragment)
var view = binding.root
return view
}
this is fragment_init.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="initVm"
type="com.example.vm.InitViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/transparent"
tools:context=".view.main.fragment.LoginFragment">
</layout>
I don't see any problem with this code. Is there any extra job I have to implement for this? I am using Data Binding. But I don't think I need to it for MainActivity.kt.
MainActivity.kt contains all the fragments. And initFragment.kt will be the first navigation that has menu to navigate.
What should I do?
Edit: In case of JAVA and NOT KOTLIN
after setContentView()
add
Fragment fragment = findViewById(R.id.nav_host_fragment);
Basically an initialization error.
AccountActivity :
class AccountActivity : AppCompatActivity(){
private lateinit var activityAccountBinding: ActivityAccountBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ViewDataBinding>(this,
R.layout.activity_account)
setDataBinder(binding)
setup()
}
override fun setDataBinder(viewDataBinding: ViewDataBinding) {
activityAccountBinding = viewDataBinding as ActivityAccountBinding
// to getting events in this file(Click event)
activityAccountBinding.accountActivity = this
}
override fun setup() {
}
}
activity_account:-
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="accountActivity"
type="com.app.presentation.myaccount.activity.AccountActivity"
/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/red_fd3d50">
<fragment
android:id="#+id/fragmentContainer"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/my_account_graph"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
my_account_graph:-
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/my_account_graph"
app:startDestination="#id/profileFragment">
<fragment
android:id="#+id/profileFragment"
android:name="com.app.presentation.myaccount.ProfileFragment"
android:label="ProfileFragment"
tools:layout="#layout/fragment_profile" />
</navigation>
Related
This question already has answers here:
Navigation Component: How to set drawer with toolbar in each fragment
(2 answers)
Closed 1 year ago.
I am using NavHostFragment to display fragments. When I am trying to obtain activity's FloatingActionButton in fragment application crashes.
MainActivity.kt
class MainActivity : AppCompatActivity(), ImageDrawerListDialogFragment.OnImageClickListener {
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) // <--
...
}
}
SearchFragment.kt
class SearchFragment : Fragment(), ImageDrawerListDialogFragment.OnImageClickListener {
private lateinit var fab: FloatingActionButton
...
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
_binding = FragmentSearchBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fab = (requireActivity() as MainActivity).findViewById(R.id.floatingActionButton) // <--
fab.setOnSafeClickListener { requestPermission() }
...
}
}
activity_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:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.AppName.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/Theme.AppName.PopupOverlay">
<androidx.appcompat.widget.SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:imeOptions="actionDone"
android:inputType="text"
app:iconifiedByDefault="false" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:contentDescription="create new search request"
app:layout_anchorGravity="bottom|end"
app:srcCompat="#android:drawable/ic_input_add" />
<include layout="#layout/content_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/nav_graph"
app:startDestination="#id/SearchFragment">
...
</navigation>
error
Caused by: android.view.InflateException: Binary XML file line #36 in com.dmytroa.appName:layout/activity_main: Binary XML file line #18 in com.dmytroa.appName:layout/content_main: Error inflating class fragment Caused by: android.view.InflateException: Binary XML file line #18 in com.dmytroa.appName:layout/content_main: Error inflating class fragment Caused by: java.lang.NullPointerException: requireActivity() as MainActivity).findViewById(R.id.floatingActionButton) must not be null
fab = (requireActivity() as
MainActivity).findViewById(R.id.floatingActionButton) // <--
fab.setOnSafeClickListener { requestPermission() }
I would suggest you not "reach up" from the Fragment into the Activity to operate on a view that exists in its layout. This creates an explicit dependency on that Activity from your Fragment which will break if you every try to use that Fragment anywhere else.
Execute logic that operates on the Activity's views within the Activity itself.
MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fab = findViewById(R.id.floatingActionButton)
fab.setOnSafeClickListener { requestPermission() }
...
}
i am facing issue with viewbinding access child of activity toolbar inside fragment.
here i am accessing edittext of toolbar inside my fragment class. but not able to access via view binding. please help me solve out this issue.
activityhome.xml
<?xml version="1.0" encoding="utf-8"?>
<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=".ui.activity.HomeActivity">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_home"
app:layout_constraintTop_toTopOf="parent"/>
<fragment
android:id="#+id/nav_main_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintTop_toBottomOf="#id/toolbar"
app:layout_constraintBottom_toTopOf="#id/actHomeBottomNavigation"
app:navGraph="#navigation/nav_graph_main"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/actHomeBottomNavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/_4sdp"
android:background="#color/black"
android:visibility="visible"
app:elevation="#dimen/_10sdp"
app:itemIconTint="#drawable/selector_color"
app:itemTextColor="#drawable/selector_color"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="#menu/bottom_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
toolbarhome.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/toolbarLayoutFragment"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/blackgrey">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/searchLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<ImageView
android:id="#+id/toolbarBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<EditText
android:id="#+id/toolbarEditSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Search"
android:textSize="#dimen/_14ssp"
android:background="#android:color/transparent"
android:textColorHint="#color/lightgrey"
android:textColor="#color/white"
app:layout_constraintStart_toEndOf="#id/toolbarBack"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
HomeFragment.kt
class HomeFragment : BaseFragment(), TextWatcher {
lateinit var binding: FragmentHomeBinding
lateinit var editSearch: EditText
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// return inflater.inflate(R.layout.fragment_home, container, false)
binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
editSearch=activity?.findViewById(R.id.toolbarEditSearch)!!
// act?.binding?.toolbar?.toolbarEditSearch?.addTextChangedListener(this)
}
}
error i am getting in logcat is below.
Caused by: android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #14: Error inflating class fragment
Caused by: java.lang.NullPointerException
at com.webforest.sft.ui.fragment.HomeFragment.onViewCreated(HomeFragment.kt:61)
set your xml code in
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout>
// your other layout or anything
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
and use this code in your fagment
private var fragmentFirstBinding: FragmentFirstBinding? = null
in the onCreate
val binding = FragmentBlankBinding.bind(view)
fragmentFirstBinding = binding
I learned today that there is something called viewbinding other than databinding.
I was new to viewbinding, but I was already using it in code.
In other words, I knew it was data binding and was using it wrong.
To use viewbinding i need to apply below code in gradle. However, I have never applied anything other than data binding.
dataBinding { enabled = true }
However, in my code, it is accessed through the ID of the view with binding.title.text-like code.
There is also no <data> tag. Isn't this a view binding?
XML
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.WritingRoutineFragment">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.AppBarOverlay"
app:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#color/white"
android:textAppearance="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_centerHorizontal="true" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
WRFragment.kt
class WritingRoutineFragment : Fragment() {
var titleArg: String? = null
private var _binding: FragmentWritingRoutineBinding? = null
private val binding get() = _binding!!
private val viewModel = WriteRoutineViewModel()
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
_binding = FragmentWritingRoutineBinding.inflate(inflater, container, false)
viewModel.setTitle(titleArg)
viewModel.title.observe(viewLifecycleOwner) { titleData ->
// UI UPDATE
binding.title.text = titleData // viewbinding? title is TextView ID
}
return binding.root
}
}
viewModel.title.observe(viewLifecycleOwner) { titleData ->
// UI UPDATE
binding.title.text = titleData // viewbinding? title is TextView ID
}
yes,you are using view binding.
if you want to use data binding ,code will be like
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="yourpackage.viewmodel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.WritingRoutineFragment">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.AppBarOverlay"
app:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#color/white"
android:text="#{viewModel.title}"
android:textAppearance="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_centerHorizontal="true" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
No, I guess you have to use both. Both provide different functionalities.
While creating bottom navigation with the jetpack navigation component the code below would work for an activity
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
findViewById<BottomNavigationView>(R.id.bottom_nav).setupWithNavController(navController)
with that, while working inside with fragments you need to call .setupWithNavController and pass in the navController and all should be fine.
But in my case with a navgraph inside the fragments XML and bottom navigation specified the app build but its only stuck in the home screen.
MainFragment.kt
class MainFragment : Fragment() {
private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
NavigationUI.setupWithNavController(binding.bottomNav,findNavController())
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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=".ui.MainFragment">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_navigation_menu" />
<fragment
android:id="#+id/main_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/main_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
main_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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_gragh"
app:startDestination="#id/homeFragment">
<fragment
android:id="#+id/homeFragment"
android:name="io.github.jerrymatera.medstab.ui.home.HomeFragment"
android:label="fragment_home"
tools:layout="#layout/fragment_home" />
<fragment
android:id="#+id/appointmentFragment"
android:name="io.github.jerrymatera.medstab.ui.appointment.AppointmentFragment"
android:label="appointment_fragment"
tools:layout="#layout/appointment_fragment" />
<fragment
android:id="#+id/chatFragment"
android:name="io.github.jerrymatera.medstab.ui.chat.ChatFragment"
android:label="chat_fragment"
tools:layout="#layout/chat_fragment" />
<fragment
android:id="#+id/profileFragment"
android:name="io.github.jerrymatera.medstab.ui.profile.ProfileFragment"
android:label="profile_fragment"
tools:layout="#layout/profile_fragment" />
</navigation>
menu/bottom_navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/mainFragment"
android:icon="#drawable/ic_home_24"
android:title="#string/home" />
<item
android:id="#+id/appointmentFragment"
android:enabled="true"
android:icon="#drawable/ic_date_range_24"
android:title="#string/appointments" />
<item
android:id="#+id/chatFragment"
android:enabled="true"
android:icon="#drawable/ic_chat_24"
android:title="#string/chat" />
<item
android:id="#+id/profileFragment"
android:enabled="true"
android:icon="#drawable/ic_account_box_24"
android:title="#string/profile" />
</menu>
In menu resource of NavigationView (menu/bottom_navigation_menu.xml) each item ID must be matching with fragment ID in navigation graph(main_graph.xml). By this NavigationUI will figure out mapping between item and destination and it will perform fragment transaction on item selection.
change
android:id="#+id/mainFragment"
to
android:id="#+id/homeFragment"
in menu/bottom_navigation_menu.xml
Maybe the problem is in MainFragment.kt but I don't know the exact reason
NavigationUI.setupWithNavController(binding.bottomNav,findNavController())
require BottomNavigationView and NavController
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.