I'm trying to add tablayout in one of my fragments.
tablayout in mainActivity works well, but tablayout in fragment doesn't work.
Tab menu shows well, but nothing comes up in my viewPager.
I want to make like this.
and it's my app
HomeDetailFragment.kt
class HomeDetailFragment : Fragment() {
lateinit var homeDetailRecyclerViewAdapter : HomeDetailRecyclerViewAdapter
private val myContext = FragmentActivity()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home_detail, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
configureTopNavigation()
}
private fun configureTopNavigation(){
vp_home_detail.adapter = HomeDetailPagerAdapter(myContext.supportFragmentManager, 5)
vp_home_detail.offscreenPageLimit = 5
tl_home_detail_bar.setupWithViewPager(vp_home_detail)
}
}
HomeDetailPagerAdapter.kt
class HomeDetailPagerAdapter (fm : FragmentManager, val fragmentCount : Int): FragmentStatePagerAdapter(fm){
private val fragmentTitleList = mutableListOf("전체", "요가","발레", "태권도", "헬스")
override fun getItem(position:Int): Fragment{
when(position){
0-> return HomeFragment()
1-> return WholeFragment()
2-> return YogaFragment()
3-> return BalletFragment()
4-> return TakFragment()
else -> return HomeFragment()
}
}
override fun getPageTitle(position: Int):CharSequence?{
return fragmentTitleList[position]
}
override fun getCount(): Int = fragmentCount
}
fragment_home_detail.xml
<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:background="#f2f7ff"
tools:context=".ui.home.HomeDetailFragment">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl_home_detail_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#ffffff"
app:tabIndicatorColor="#2c77f1"
android:layout_alignParentTop="true"
android:theme="#style/HomeDetailTab"
android:elevation="5dp" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/vp_home_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/tl_home_detail_bar"/>
Use childFragmentManager instead of myContext.supportFragmentManager
vp_home_detail.adapter = HomeDetailPagerAdapter(childFragmentManager, 5)
Related
I have one AlertSettingfragment which has two tabItem ( SMS text and Email). I have created two fragments for viewpager(SMStext Fragment and Email Fragment) according to the tabItem. But i am not able to connect to the viewpager. Please Help
fragment_alertSetting.xml
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="42dp"
android:layout_margin="2dp"
android:backgroundTint="#color/gray"
app:tabBackground="#drawable/track_selector"
app:tabGravity="fill"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabRippleColor="#color/transparent"
app:tabSelectedTextColor="#color/dark_blue"
app:tabTextAppearance="#style/CustomTextAppearanceTab"
app:tabTextColor="#color/gray_blue">
<com.google.android.material.tabs.TabItem
android:id="#+id/smsTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/sms_text" />
<com.google.android.material.tabs.TabItem
android:id="#+id/emailTab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/email" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/alertSettingViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="16dp"
android:background="#color/white"
app:layout_constraintTop_toBottomOf="#id/tabLayoutView" />
AlertSettingFragment.kt
#AndroidEntryPoint
class CascadeSettingsAlertFragment : Fragment() {
private lateinit var binding: FragmentCascadeSettingsAlertBinding
private var listener: OnFragmentInteractionListener? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentCascadeSettingsAlertBinding.inflate(inflater,container,false).apply {
alertSettingViewPager.adapter = CascadeAlertSettingAdapter(this#CascadeSettingsAlertFragment)
TabLayoutMediator(
tabLayout,
alertSettingViewPager
) { tabs, position ->
val tabBinding = when (position) {
SMS_PAGE_INDEX -> binding.smsTab
EMAIL_PAGE_INDEX -> binding.emailTab
else -> binding.smsTab
}
tabs.view = tabBinding.
}.attach()
}
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
AlertSettingAdapter.kt
const val SMS_PAGE_INDEX = 0
const val EMAIL_PAGE_INDEX = 1
class CascadeAlertSettingAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
private val tabFragmentsCreators: Map<Int, () -> Fragment> = mapOf(
SMS_PAGE_INDEX to { AlertSettingsSmsFragment() },
EMAIL_PAGE_INDEX to { AlertSettingsEmailFragment() },
)
override fun getItemCount() = tabFragmentsCreators.size
override fun createFragment(position: Int): Fragment {
return tabFragmentsCreators[position]?.invoke() ?: throw IndexOutOfBoundsException()
}
}
You have to add the TabItems programmatically to the TabLayout, TabItems added via XML are not actually added to the TabLayout, as mentioned in the documentation of TabLayout.
More info:
https://developer.android.com/reference/com/google/android/material/tabs/TabItem
I found an interesting feature in one of the applications, I want to repeat it. The application has ViewPager and TabLayout and a bunch of fragments inside.
On the first fragment there is a button img1
, by pressing it, the fragment is replaced by another img2
while ads_banner is removed and the toolbar is replaced,
and when swiping to the right and back, it shows fragment1, please tell me how this can be done. Here is what I already wrote:
MainActivity
class MainActivity : AppCompatActivity() {
private var mAdView: AdView? = null
#SuppressLint("ResourceType")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adRequest = AdRequest.Builder().build()
mAdView = findViewById(R.id.adView)
mAdView!!.loadAd(adRequest)
initTab()
}
fun initTab() {
tab_layout.addTab(tab_layout.newTab().setIcon(R.drawable.image1)
tab_layout.addTab(tab_layout.newTab().setIcon(R.drawable.image2)
tab_layout.addTab(tab_layout.newTab().setIcon(R.drawable.image3)
tab_layout.tabGravity = TabLayout.GRAVITY_FILL
val adapter = MyPagerAdapter(supportFragmentManager, tab_layout.tabCount)
pager.adapter = adapter
pager.offscreenPageLimit = 2
pager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tab_layout))
tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
pager.currentItem = tab.position
if (tab.position == 0) {
tab_layout.getTabAt(0)!!.setIcon(R.drawable.image1_focus)
}
if (tab.position == 1) {
tab_layout.getTabAt(1)!!.setIcon(R.drawable.image2_focus)
}
if (tab.position == 2) {
tab_layout.getTabAt(2)!!.setIcon(R.drawable.image3_focus)
}
}
override fun onTabUnselected(tab: TabLayout.Tab) {
if (tab.position == 0) tab_layout.getTabAt(0)!!.setIcon(R.drawable.image1)
if (tab.position == 1) tab_layout.getTabAt(1)!!.setIcon(R.drawable.image2)
if (tab.position == 2) tab_layout.getTabAt(2)!!.setIcon(R.drawable.image3)
}
override fun onTabReselected(tab: TabLayout.Tab) {
}
})
}
activity_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:id="#+id/mainlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".MainActivity">
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#color/transparent"
app:adSize="SMART_BANNER"
app:adUnitId="#string/banner_key"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
style="#style/MyToolbar"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_marginTop="2dp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/adView"
app:popupTheme="#style/AppTheme.PopupOverlay">
<TextView
android:id="#+id/toolbar_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="#font/sf_pro_display_regular"
android:textColor="#color/black"
android:textSize="24sp"
tools:layout_editor_absoluteX="206dp"
tools:layout_editor_absoluteY="7dp" />
</androidx.appcompat.widget.Toolbar>
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#fff"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:tabBackground="#drawable/tab_color_selector"
app:tabIndicatorColor="#2196F3"
app:tabIndicatorGravity="top"
app:tabIndicatorHeight="4dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
MyPagerAdapter
class MyPagerAdapter(fm: FragmentManager, internal var mNumOfTabs: Int) : FragmentStatePagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
when (position) {
0 -> {
return RootFragment()
// return Fragment1()
}
1 -> {
return Fragment2()
}
2 -> {
return Fragment3()
}
}
}
override fun getCount(): Int {
return mNumOfTabs
}
}
Fragment1
class Fragment1: Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_1, container, false)
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
btnfr1.setOnClickListener {
val trans = fragmentManager!!.beginTransaction()
trans.replace(R.id.root_frame, Fragment4())
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
trans.addToBackStack(null)
trans.commit()
}
}
RootFragment
class RootFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.root_fragment, container, false)
val transaction = fragmentManager!!.beginTransaction()
transaction.replace(R.id.root_frame, Fragment1())
transaction.commit()
return view
}
}
root_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/root_frame" >
</FrameLayout>
In Fragment1, only the button for calling Fragment4. Tried to do as here https://www.codexpedia.com/android/android-viewpager-fragment-swap/
it turned out to replace Fragment1 with Fragment4, but I don’t know how to reset Fragment4 when swiping and don’t understand how to replace Toolbar and remove ads.
The trick is that as RootFragment is the fragment on the 0th index, what you need to do is show the original fragment as a child fragment of RootFragment using fragment transactions via childFragmentManager.
This way, you can replace the children of RootFragment, without actually having to replace RootFragment itself inside the ViewPager.
You need to implement createFragment and getItemCount methods in MyPagerAdapter to supply instances of fragments as pages to ViewPager.
Modify MyPagerAdapter class as shown below and test:
class MyPagerAdapter(fm: FragmentManager, internal var mNumOfTabs: Int) : FragmentStatePagerAdapter(fm) {
override fun getItemCount(): Int = mNumOfTabs
override fun createFragment(position: Int): Fragment {
when (position) {
0 -> {
return RootFragment()
}
1 -> {
return Fragment2()
}
2 -> {
return Fragment3()
}
}
}
}
Hi I have a strange problem. MainActivity has a framelayout and a main fragment EnterFragment.
EnterFragment has a framelayout and i'd like to see other 2 fragments. SignupFragment and LoginFragment.
When EnterFragment starts, it shows SignupFragment.java.. after MainActivity invoke a method of EnterFragment to change fragment to LoginFragment but app crash:
java.lang.IllegalStateException: Fragment EnterFragment{95bc7de (70f980b2-eff8-4e4c-a644-e95544b73584)} has not been attached yet.
at androidx.fragment.app.Fragment.getChildFragmentManager(Fragment.java:923)
Here the project: https://www.dropbox.com/s/qq1kl4qw688ipjr/example.zip?dl=0
Here the code:
//MainActivity
class MainActivity : AppCompatActivity() {
private var enterFragment: EnterFragment?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
showEnter()
}
private fun showEnter() {
enterFragment= EnterFragment.newInstance()
this.replaceFragmentTransition(R.id.fragmentContainer, EnterFragment.newInstance(), EnterFragment.TAG )
var handler= Handler()
handler.postDelayed(Runnable {gotoLoginFromSignup() }, 8000)
}
private fun gotoLoginFromSignup() {
enterFragment?.gotoLogin()
}
}
//EnterFragment
class EnterFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_enrer, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
this.replaceFragmentTransition(R.id.fmContainer, SignuFragment.newInstance(), SignuFragment.TAG )
}
fun gotoLogin(){
this.replaceFragmentTransition(R.id.fmContainer, LoginFragment.newInstance(), SignuFragment.TAG )
}
companion object {
val TAG: String="EnterFragment"
#JvmStatic
fun newInstance() = EnterFragment()
}
}
//SignupFragment
class SignuFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_signup, container, false)
}
companion object {
val TAG: String="SignuFragment"
#JvmStatic
fun newInstance() = SignuFragment()
}
}
//LoginFragment
class LoginFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_login, container, false)
}
companion object {
val TAG: String="LoginFragment"
#JvmStatic
fun newInstance() = LoginFragment()
}
}
//EXTENSIONS
fun FragmentActivity.replaceFragmentTransition(
container: Int,
fragment: Fragment?,
tag: String
) {
fragment?.let {
var transition = this.supportFragmentManager
.beginTransaction()
transition.replace(container, it, tag)
.commitNowAllowingStateLoss()
}
}
fun Fragment.replaceFragmentTransition(
container: Int,
fragment: Fragment?,
tag: String
) {
fragment?.let {
var transition = this.childFragmentManager
.beginTransaction()
transition.replace(container, it, tag)
.commitNowAllowingStateLoss()
}
}
//main activity layout
<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=".MainActivity">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragmentContainer"
android:layout_width="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_height="0dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
//enterFragment
<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=".EnterFragment">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fmContainer"
android:layout_width="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_height="0dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Replace this
this.replaceFragment(R.id.fragmentContainer, FatherFragment.newInstance(), FatherFragment.TAG )
with
this.replaceFragment(R.id.fragmentContainer, fatherFragment!!, FatherFragment.TAG )
while transaction, you are passing different instance & calling openLogin() with another instance.
FatherFragment.newInstance() will give new instance.
I've been trying to combine a bottom navigation view, a tablayout and a viewpager. I already have the tableyout working with the viewpager, but when selecting another item (different from the one containing the tableyout) from the bottom navigation view nothing happens and it seems that they were disabled. I do not know what I'm doing wrong. I am a novice on Android.
I want something like this:
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val onNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_data_sheet -> {
replaceFragment(DataSheetFragment())
return#OnNavigationItemSelectedListener true
}
R.id.navigation_search -> {
replaceFragment(SearchFragment())
return#OnNavigationItemSelectedListener true
}
R.id.navigation_notifications -> {
replaceFragment(NotificationsFragment())
return#OnNavigationItemSelectedListener true
}
R.id.navigation_profile -> {
val intent = Intent(this#MainActivity, NoLoginActivity::class.java)
startActivity(intent)
finish()
return#OnNavigationItemSelectedListener true
}
}
false
}
private fun replaceFragment(fragment: Fragment) {
val fragmentTransition = supportFragmentManager.beginTransaction()
fragmentTransition.replace(R.id.fragmentContainer, fragment)
fragmentTransition.commit()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
replaceFragment(DataSheetFragment())
val navView: BottomNavigationView = findViewById(R.id.bottom_navigation)
navView.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)
}}
PagerAdapter.kt
class PagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment {
return when (position) {
0 -> {
SpecimensFragment()
}
else -> {
return FungiFragment()
}
}
}
override fun getCount(): Int {
return 2
}
override fun getPageTitle(position: Int): CharSequence {
return when (position) {
0 -> "Especímenes"
else -> {
return "Hongos"
}
}
}}
DataSheetFragment.kt: Fragment que contiene el tablayout
class DataSheetFragment : Fragment() {
private lateinit var viewPager: ViewPager
private lateinit var tabs: TabLayout
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view: View = inflater.inflate(R.layout.fragment_data_sheet, container, false)
viewPager = view.findViewById(R.id.viewPager)
tabs = view.findViewById(R.id.data_sheet_tabs)
val fragmentAdapter = PagerAdapter(childFragmentManager)
viewPager.adapter = fragmentAdapter
tabs.setupWithViewPager(viewPager)
return view
}}
fragment_data_sheet.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=".Fragments.DataSheetFragment"
>
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:title="#string/data_sheet"
app:titleTextColor="#color/white"
android:background="#color/colorPrimary"
>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="#+id/data_sheet_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/toolbar"
android:background="#color/background_color"
app:tabTextAppearance="#style/TabLayoutTextAppearance"
>
<com.google.android.material.tabs.TabItem
android:id="#+id/specimens_tab"
android:text="#string/specimens"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.google.android.material.tabs.TabItem
android:id="#+id/fungi_tab"
android:text="#string/fungi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/data_sheet_tabs"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
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