How to avoid reinflating menu in fragments with AppBarLayout? - android

I inflate my SearchView into my AppBarLayout and MaterialToolbar in MainActivity. When I search items in ListFragment and open DetailFragment for an item then get back my AppBarLayout inflates again and I see my list is cleared. I want it to save query and show my previous state.
In ListFragment I do:
override fun onCreateOptionsMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu_main, menu)
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
setupSearchView(menu)
}
private fun setupSearchView(menu: Menu) {
userSearchView = menu.findItem(R.id.search).actionView as SearchView
userSearchView?.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
query?.let(viewModel::trySearching)
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
newText?.let(viewModel::trySearching)
return true
}
})
}
In DetailFragment I do:
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
menu.clear()
}
For navigation I use AAC nav component

Related

How to get back the action bar icons after closing the search view?

While clicking the search view icon, I am hiding the other icon from the action bar. After closing the search view, the action bar icons are replaced by a more icon. How to get back the old list of icons in the action bar?
class ProductListFragment : Fragment() {
.....
.......
private lateinit var sortItem:MenuItem
private lateinit var searchItem: MenuItem
override fun onPrepareOptionsMenu(menu: Menu) {
searchItem=menu.findItem(R.id.category_search)
sortItem=menu.findItem(R.id.sort)
super.onPrepareOptionsMenu(menu)
}
.........
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.category_activity_menu,menu)
val searchView=menu.findItem(R.id.category_search)?.actionView as SearchView
searchView.setOnSearchClickListener {
sortItem.isVisible=false
}
searchView.setOnCloseListener{
true
}
searchView.setOnQueryTextListener(object: SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
searchData(newText)
return true
}
})
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId){
R.id.category_search->{
}
R.id.sort->{
val bottomSheetFragment=SortBottomSheetFragment()
bottomSheetFragment.show(parentFragmentManager,"")
}
}
return super.onOptionsItemSelected(item)
}
}

Android toolbar menu doesn't work properly when I even set shoAsAction as always

here is my code
fun initActionBar() {
setSupportActionBar(toolbar_main)
actionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
MenuInflater(this).inflate(R.menu.toolbar_menu, menu)
return true
}
and here I serve you my menu and screenshot
Remove the '?' after actionBar. Looks like this now:
fun initActionBar() {
setSupportActionBar(toolbar_main)
actionBar.setDisplayHomeAsUpEnabled(true)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
MenuInflater(this).inflate(R.menu.toolbar_menu, menu)
return true
}

Kotlin - Call fragment method from MainActivity

I have two fragments and a toolbar with a menu. I want to be able to switch fragments when a menu item is selected by calling the method in the fragment that does this. Problem is, I get this error when I try running the app with the code below. java.lang.IllegalStateException: Fragment FirstFragment{5ce330b (f5c2d362-d3fb-4346-9971-dd7be653e609)} not associated with a fragment manager.
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var adapter: Adapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> {
FirstFragment().settings()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
FirstFragment.kt
fun settings() {
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
}
How can I implement a fragment manager so I can call this method via MenuItem and not get an exception? Thanks in advance!
Thanks for the help! I solved the issue by creating the MenuItem in my first fragment like so:
lateinit var second: MenuItem
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
second = menu.add("second fragment")
second.setOnMenuItemClickListener() {
settings()
true
}
}
fun settings() {
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
}

How to update option menu item icon?

Here is my code I want to update menu item icon based on data I requesting in server that is why I need to have access to menu item in onViewCreated as I think solution which I am doing now is not right as observing data in onPrepareOptionsMenu?
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_favorite, menu)
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
viewModel.favorite
.observe(viewLifecycleOwner, Observer {
if (it.data != null) {
menu.findItem(R.id.action_favorite)?.icon = true
}
})
}

setSupportActionBar inside of a Fragment

I have a Fragment:
class HomeFragment : Fragment() { ... }
Now I'm trying to add an Actionbar to it, but this doesn't work:
setSupportActionBar(findViewById(R.id.toolbar_main))
How can I set the Support and then add Items to the ActionBar?
This is how it works in an AppCompatActivity:
// This adds items to the ActionBar
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_toolbar_main, menu)
return true
}
// This is the OnClickListener for the Buttons in the ActionBar
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
R.id.toolbar_edit -> {
true
}
R.id.toolbar_search -> {
true
}
else -> {
// If we got here, the user's action was not recognized.
// Invoke the superclass to handle it.
super.onOptionsItemSelected(item)
}
}
Big thanks in advance!
Override onCreateOptionsMenu in your Fragment and inflate your menu inside. Than in onCreate method of Fragment set setHasOptionsMenu() to true. To inflate different menus depending on Fragment creation clear the menu first.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(Your menu here, menu)
}

Categories

Resources