Android Kotlin:如何从Adapter传变量到Fragment及向TabHost内Fragment传activityID?
Hey there! Let's work through your two Fragment data-passing issues step by step—they're common hurdles when setting up TabLayout with Fragments, so you're not alone here.
1. Passing Variables from Your Adapter to Instantiated Fragments
The most reliable and Android-recommended way to pass data to a Fragment is to use a static factory method in your Fragment class. This avoids issues with Fragment recreation (like screen rotations) and keeps your code clean. Here's how to implement it:
First, update your Fragment to include a factory method that bundles your variables:
class MyTabFragment : Fragment() { private var customVariable: String? = null private var activityId: Int? = null companion object { // Define keys for your arguments to avoid typos private const val ARG_CUSTOM_VAR = "arg_custom_var" private const val ARG_ACTIVITY_ID = "arg_activity_id" // Factory method to create a Fragment instance with parameters fun newInstance(varValue: String, activityId: Int): MyTabFragment { val fragment = MyTabFragment() val args = Bundle().apply { putString(ARG_CUSTOM_VAR, varValue) putInt(ARG_ACTIVITY_ID, activityId) } fragment.arguments = args // This is where you attach the bundle return fragment } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Extract the arguments when the Fragment initializes arguments?.let { customVariable = it.getString(ARG_CUSTOM_VAR) activityId = it.getInt(ARG_ACTIVITY_ID) } } // Rest of your Fragment logic... }
Then, in your TabLayout adapter (like FragmentPagerAdapter or FragmentStateAdapter), use this factory method instead of directly instantiating the Fragment:
class MyTabAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) { private val tabItems = listOf("Tab 1", "Tab 2", "Tab 3") private val targetActivityId = 123 // Replace with your actual activity ID override fun getItem(position: Int): Fragment { // Pass unique or shared variables based on tab position return when (position) { 0 -> MyTabFragment.newInstance("Data for Tab 1", targetActivityId) 1 -> MyTabFragment.newInstance("Data for Tab 2", targetActivityId) else -> MyTabFragment.newInstance("Data for Tab 3", targetActivityId) } } override fun getCount(): Int = tabItems.size override fun getPageTitle(position: Int): CharSequence? = tabItems[position] }
2. Fixing the "setArgument Method Doesn't Exist" Issue
Chances are you made a tiny spelling mistake here—it's setArguments() (plural), not setArgument() (singular). Additionally, this method must be called before the Fragment is added to the Activity (which is why the factory method approach above works perfectly).
If you ever need to call it directly (though the factory method is better), here's the correct syntax:
val fragment = MyTabFragment() val args = Bundle() args.putInt("activity_id", 123) fragment.setArguments(args) // Notice the plural "Arguments"
A quick note: Never pass data through a Fragment's constructor directly. When Android recreates your Fragment (e.g., after a configuration change), it will use the empty constructor, and your custom parameters will be lost. Using arguments ensures the data is preserved automatically.
内容的提问来源于stack exchange,提问作者Nicolas Felten

