User0829
User0829

Reputation: 187

Kotlin: update fragment in viewPager

I am considering a simple example consists of the following component:

So, in the screen, you can swipe to see each fragment. I want my example to have the function: if one writes a text in the editText and click the button then it shows up in Fragment B.

A tried it by using notifyDatsetChanged() but it does not work. Could anyone help? Below is the whole code of mine:

MainActivity.kt

package com.myproject.chapterfivesectionone

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.myproject.chapterfivesectionone.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    lateinit var fragmentB: FragmentB

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        val fragmentList = listOf(FragmentA(), FragmentB())
        val adapter = FragmentAdapter(this)
        adapter.fragmentList = fragmentList
        binding.viewPager.adapter = adapter

        binding.buttonSend.setOnClickListener {
            var bundle = Bundle()
            bundle.putString("key1", binding.editTextWriteSomething.text.toString())
            fragmentB.arguments = bundle

            adapter.notifyDataSetChanged()
        }
    }

}

FragmentAdapter.kt

package com.myproject.chapterfivesectionone

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter

class FragmentAdapter(fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
    var fragmentList = listOf<Fragment>()

    override fun getItemCount(): Int {
        return fragmentList.size
    }

    override fun createFragment(position: Int): Fragment {
        return fragmentList.get(position)
    }
}

FragmentA.kt

package com.myproject.chapterfivesectionone

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class FragmentA : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_a, container, false)
    }
}

FragmentB.kt

package com.myproject.chapterfivesectionone

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.myproject.chapterfivesectionone.databinding.FragmentBBinding

class FragmentB : Fragment() {
    lateinit var binding: FragmentBBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentBBinding.inflate(inflater, container, false)
        if (arguments?.getString("key1") != null) {
            binding.textViewInFragmentB.text = arguments?.getString("key1")
        }
        return binding.root
    }
}

Upvotes: 2

Views: 457

Answers (1)

Linh
Linh

Reputation: 60923

Currently, fragmentB is inside fragmentList so you can retrieve it like fragmentList[fragmentBPosition]. Then defind a function inside FragmentB for update the TextView

binding.buttonSend.setOnClickListener {
    (fragmentList[1] as FragmentB).updateTheTextView("new")
    // if you want code more clean, can replace hard code value by a constant or you can write some logic to find FragmentB from fragmentList
}

FragmentB

class FragmentB : Fragment() {
    fun updateTheTextView(newText : String) {
          binding.textViewInFragmentB.text = newText
    }
}

Upvotes: 1

Related Questions