I am using bottom navigation. I want to open a dialog window by selecting the option menu after switching to another fragment screen through the bottom menu.
But I don't see the option menu..
I wrote it by referring to other sample code, but I do not know the cause
WorkoutListFragment.kt
class WorkoutListFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_workout_list, container,false)
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.record_item_add, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val dialog = BodyPartDialogFragment()
dialog.show(activity!!.supportFragmentManager, "BodyPartDialog")
return true
}
}
ADDED
val toolbar: Toolbar = view.findViewById(R.id.toolbar)
(activity as AppCompatActivity).setSupportActionBar(toolbar)
WorkouListFragment.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=".fragment.WorkoutListFragment">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:theme="#style/Theme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="LIST"
app:titleTextColor="#color/black"
app:titleMarginStart="30dp"
android:paddingRight="30dp"
android:theme="#style/Theme.PopupOverlay"/>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Related
I'm trying to combine NavigationDrawer with a Toolbar that has a refresh Menu option:
The problem I'm encountering is that I cannot make the Toolbar show the menu button.
My MainActivity only holds a Fragment. activity_main.xml:
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_nav_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/main" />
MainActivity.kt:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
nav_main:
<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_main"
app:startDestination="#id/drawerFragment"
>
<fragment
android:id="#+id/drawerFragment"
android:name="com.example.rocketman.drawer.DrawerFragment"
android:label="DrawerFragment"
tools:layout="#layout/fragment_drawer"
/>
</navigation>
Basically my MainActivity navigates directly into a DrawerFragment, which is here:
<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"
android:orientation="vertical"
tools:context="com.example.rocketman.drawer.DrawerFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.rocketman.drawer.DrawerFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbar_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/midnight_blue"
app:titleTextColor="#color/white"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/drawer_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/drawer_nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
And finally, my DrawerFragment:
private const val KEY_SELECTED_DRAWER_ITEM = "DRAWER_SELECTED_ITEM_ID_KEY"
class DrawerFragment: Fragment() {
private lateinit var binding: FragmentDrawerBinding
private var drawerSelectedItemId = R.id.nav_home
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentDrawerBinding.inflate(inflater)
(requireActivity() as AppCompatActivity).setSupportActionBar(toolbar_home)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
savedInstanceState?.let {
drawerSelectedItemId = it.getInt(KEY_SELECTED_DRAWER_ITEM, drawerSelectedItemId)
}
setupDrawer()
setBackPressedHandler()
}
private fun setBackPressedHandler() {
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
if (binding.drawerLayout.isOpen) {
binding.drawerLayout.close()
} else {
findNavController().popBackStack()
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putInt(KEY_SELECTED_DRAWER_ITEM, drawerSelectedItemId)
super.onSaveInstanceState(outState)
}
private fun setupDrawer() {
val controller = binding.drawerNavView.setupWithNavController(
childFragmentManager,
findNavController(),
listOf(
//all the items on the Drawer have their own navigation graph
R.navigation.home,
R.navigation.rocket,
R.navigation.company
),
R.id.drawer_container,
drawerSelectedItemId,
requireActivity().intent
)
controller.observe(
viewLifecycleOwner,
{ navController ->
NavigationUI.setupWithNavController(
binding.toolbarHome,
navController,
binding.drawerLayout
)
drawerSelectedItemId = navController.graph.id
}
)
}
}
In other words, the Drawer has three items: home, rocket and company as can be seen here, menu/drawer:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/nav_home"
android:checked="true"
android:checkable="true"
android:icon="#drawable/ic_home"
android:title="#string/nav_menu_home"
/>
<item
android:id="#+id/nav_rocket"
android:checkable="true"
android:icon="#drawable/ic_rocket"
android:title="#string/nav_menu_rocket_list"
/>
<item
android:id="#+id/nav_company"
android:checkable="true"
android:icon="#drawable/ic_company"
android:title="#string/nav_menu_company_data"
/>
</menu>
Each of home, rocket and company have their own navigation graph, for example navigation/company looks like this:
<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_company"
app:startDestination="#id/companyDataFragment">
<fragment
android:id="#+id/companyDataFragment"
android:name="com.example.rocketman.company.CompanyFragment"
android:label="#string/nav_menu_company_data"
tools:layout="#layout/fragment_company_data"
/>
</navigation>
And the CompanyFragment is straight forward:
class CompanyFragment: Fragment() {
private lateinit var binding: FragmentCompanyDataBinding
private val vm by lazy {
ViewModelProvider(this).get(CompanyVM::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
Repo.init(requireContext())
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentCompanyDataBinding.inflate(inflater)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.company, menu)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupObservers()
}
private fun setupObservers() {
//observing
}
}
That part works.
However, I want to create a menu action for Company. So first I create a menu item menu/company:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/update"
android:icon="#drawable/ic_baseline_refresh_24"
android:title="#string/menu_company_update"
app:showAsAction="ifRoom|withText"
/>
</menu>
Then in CompanyFragment I call override onCreate() { setHasOptionsMenu(true) } and override onCreateOptionsMenu() { inflater.inflate(R.menu.company, menu }.
This should create the options menu for the Toolbar. However, the Fragment only shows the drawer menu icon but not the options menu icon.
I can add a Toolbar to the content Fragment itself but then the app has two Toolbars, the one with the drawer and the one with option items:
How do I make the Toolbar have both the NavigationDrawer and option items?
Still many people continue to use ActionBar, we don't have to use it any more. And if I were you, I would not use ActionBar and setHasOptionsMenu(true) which is related to ActionBar, but just would use a Toolbar.
Just delete setHasOptionsMenu(true), onCreateOptionsMenu() and onOptionsItemSelected() (if you have it).
Instead, use Toolbar.inflateMenu() and Toolbar.setOnMenuItemClickListener() directly on your Toolbar.
From what I understand from your question, you want to display overflow menu along with drawer menu.
The showAsAction option in the menu xml file is what you can use to control how that single menu option will show up in the actionbar.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/update"
android:icon="#drawable/ic_baseline_refresh_24"
android:title="#string/menu_company_update"
app:showAsAction="ifRoom|withText"
/>
</menu>
change this to
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/update"
android:icon="#drawable/ic_baseline_refresh_24"
android:title="#string/menu_company_update"
app:showAsAction="never"
/>
</menu>
This will show the menu item in the Overflow menu.
I have a fragment with toolbar, I need to handle navigation by the click on options menu item. At first i thought the problem is navigation, but then I supposed that it just not clickable. I tried to use Toast to see if it's working and it's not. Layout screenshot
CocktailListFragment
class CocktailListFragment : Fragment() {
private val viewModel: CocktailListViewModel by lazy {
ViewModelProvider(this).get(CocktailListViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = CocktailListFragmentBinding.inflate(inflater)
...
setHasOptionsMenu(true)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.filter_menu, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.filter -> {
Toast.makeText(context, "Filter clicked", Toast.LENGTH_LONG).show()
true
} else -> super.onOptionsItemSelected(item)
}
}
}
Can this problem be connected with layout?
filter_list.xml
<layout 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">
<data>
<variable
name="cocktail"
type="com.example.coctaildb.cocktaillist.CocktailListViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="#style/Widget.AppCompat.Toolbar"
android:background="#android:color/white"
app:menu="#menu/filter_menu"
app:title="#string/drinks"
android:elevation="20dp"
app:titleTextColor="#android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.recyclerview.widget.RecyclerView
... />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Here my menu file:
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/filter"
android:icon="#drawable/ic_filter_icon"
android:title="#string/filters"
app:showAsAction="always" />
</menu>
Try to handle your click events with the OnMenuItemClickListener method:
class CocktailListFragment : Fragment() {
private val viewModel: CocktailListViewModel by lazy {
ViewModelProvider(this).get(CocktailListViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = CocktailListFragmentBinding.inflate(inflater)
...
binding.root.toolbar.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.filter -> {
Toast.makeText(context, "Filter clicked", Toast.LENGTH_LONG).show()
true
}
}
false
}
return binding.root
}
}
While creating a very simple sample app, I couldn't wrap my head around why my app is closing when I press the hardware back button on my emulator.
I have 1 mainActivity and 2 fragments.
When I am on the NavigationFragment and press back, the app closes instead of going back to IntermediateFragment.
MainActivity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar.setTitle(R.string.app_name)
}
}
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.exampleapplication.MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent"
/>
<fragment
android:id="#+id/my_nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/main_nav"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
navigation_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"
android:id="#+id/main_nav"
app:startDestination="#+id/intermediateFragment">
<fragment
android:id="#+id/intermediateFragment"
android:name="com.exampleapplication.IntermediateFragment">
<action
android:id="#+id/action_intermediate_to_navigation"
app:destination="#+id/navigationFragment"
/>
</fragment>
<fragment
android:id="#+id/navigationFragment"
android:name="com.exampleapplication.NavigationFragment"
/>
</navigation>
IntermediateFragment:
class IntermediateFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_intermediate, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_next_fragment.setOnClickListener {
findNavController().navigate(R.id.action_intermediate_to_navigation)
}
}
}
NavigationFragment:
class NavigationFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_navigation, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_first_library.setOnClickListener {
findNavController().setGraph(R.navigation.first_library_nav)
}
btn_download_pdf.setOnClickListener {
findNavController().setGraph(R.navigation.download_pdf_nav)
}
}
}
Any ideas?
You're missing one line on your <fragment>:
app:defaultNavHost="true"
As per the Navigation Getting Started guide:
The app:defaultNavHost="true" attribute ensures that your NavHostFragment intercepts the system Back button.
Since you don't set that, Navigtion does not intercept the back button and hence, you only get the default activity behavior (which is closing your activity).
I am working on app that uses Navigation pattern.
Now I have an Activity and few fragments.
Each Fragment has a unique functionality so I created a separate toolbar for each fragment: collapsing, usual or no toolbar at all.
I used the following example: https://android.jlelse.eu/instagram-style-navigation-using-navigation-component-854037cf1389
It works pretty well, but now I am taking an issue if I want to set some menu items in the toolbar.
For example, I would like to add a settings menu to the toolbar of the Profile Fragment
I tried setting a menu item, but it simply never appears and I think the method doesn't get called at all..
Is it possible to solve this issue without changing the whole architecture logic?
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.my_layout, container, false)
setHasOptionsMenu(true)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.toolbar.apply {
setupWithNavController(findNavController())
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.main_menu, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.action_get_info)
Toast.makeText(context!!, "test message", Toast.LENGTH_SHORT).show()
return super.onOptionsItemSelected(item)
}
<?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_get_info"
android:icon="#drawable/ic_setting"
android:title="Settings"
app:showAsAction="always" />
</menu>
<layout 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"
tools:context="com.example.MyFragment">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
style="#style/ToolbarAppearance"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_test_image" />
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
The following code is based by Android Studio Wizard 3.2.1 for creating Tabbed Activity.
There is a button1 on PlaceholderFragment1 connected Tab1, and a button2 on PlaceholderFragment2 connected Tab2
I hope to click button1 to switch to Tab2, and click button2 to switch to Tab1, How can I do ?
BTW, I have read How to change tab on button click in Android? and How to programmatically switch tabs using buttonclick in Android
Code
class MainActivity : AppCompatActivity() {
private var mSectionsPagerAdapter: SectionsPagerAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mSectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager)
container.adapter = mSectionsPagerAdapter
container.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs))
tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(container))
}
inner class SectionsPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
val fragment: Fragment
when (position) {
0 -> fragment = PlaceholderFragment1() //Tab1
1 -> fragment = PlaceholderFragment2() //Tab2
else -> throw IllegalArgumentException("Invalid section number")
}
return fragment
}
override fun getCount(): Int {
return 2
}
}
class PlaceholderFragment1 : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView = inflater.inflate(R.layout.fragment_main1, container, false)
return rootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
button1.setOnClickListener {
//Switch to Tab2
}
}
}
class PlaceholderFragment2 : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val rootView = inflater.inflate(R.layout.fragment_main2, container, false)
return rootView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
button2.setOnClickListener {
//Switch to Tab1
}
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<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/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:id="#+id/tabItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_1"/>
<android.support.design.widget.TabItem
android:id="#+id/tabItem2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tab_text_2"/>
</android.support.design.widget.TabLayout>
</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"/>
</android.support.design.widget.CoordinatorLayout>
fragment_main1.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:text="Button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button1"/>
</android.support.constraint.ConstraintLayout>
My way
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...
setControl(view)
}
private fun setControl(view: View){
button1.setOnClickListener {
var viewPager=view.parent as ViewPager
viewPager.setCurrentItem(1,true)
}
}
manually binding these events is not required...
you just have to setup the TabLayout with the Viewpager:
container.adapter = mSectionsPagerAdapter
tabs.setupWithViewPager(container);
then these events are being handled by the framework, in a rather convenient way.
PS: container is a rather unfortunate variable name for a ViewPager.
I think you should use Livedata and ViewModel.
Create View Model class with livedata.
Observer Livedata in MainActivity.
Update livedata value from your fragment.
For example:
class TabChangerViewModel : ViewModel() {
val colorResource = MutableLiveData<Int>()
.........
}
In your MainActivity class:
val tabChangerViewModel = ViewModelProviders.of(this).get(TabChangerViewModel::class.java) // initialize view model
tabChangerViewModel.colorResource.observe(this, android.arch.lifecycle.Observer {
//mViewPager.setCurrentItem(it)
})
Now update live data value from your fragment:
val tabChangerViewModel = ViewModelProviders.of(activity).get(TabChangerViewModel::class.java) // initialize view model
tabChangerViewModel.colorResource.value = TAB_POSITION_WANT_TO_SELECT