如何在Fragment中获取经Class B修改后的A类变量pto1的值?
解决Fragment获取Class B修改后A类变量的问题
核心问题是Fragment D和Class B各自创建了A类的独立实例,导致Fragment读取的是自己实例的初始值,拿不到B修改后的结果。要解决这个问题,关键是让两者共享同一个A类实例,或者通过数据监听的方式同步值,下面是几种可行的实现方式:
方案1:将A类改为单例模式
让A类全局只有一个实例,这样B和Fragment操作的都是同一个对象,修改和读取的是同一个pto1值。
修改A类:
class A private constructor() { var pto1 = 0.0 fun changeValue(a: Double){ pto1 = a } // 单例实现 companion object { val instance: A by lazy { A() } } }
修改Class B:
class B { // 使用单例实例 val classA = A.instance fun onClickEvent(b:Double){ classA.changeValue(b) } }
修改Fragment D:
class D : Fragment() { // 使用同一个单例实例 val classA = A.instance override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.your_fragment_layout, container, false) val button = view.findViewById<Button>(R.id.button) button.setOnClickListener { val f = classA.pto1 // 这里拿到的就是B修改后的值 } return view } }
方案2:在父组件中创建A实例并传递
如果不想用单例(比如需要多个A实例的场景),可以在共同的父组件(如Activity)中创建A的实例,再传递给Class B和Fragment D,确保两者使用同一个对象。
示例(以Activity为父组件):
// 父Activity class MainActivity : AppCompatActivity() { val sharedAInstance = A() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 给B传递实例 val classB = B(sharedAInstance) // 给Fragment传递实例,比如通过arguments val fragmentD = D().apply { arguments = Bundle().apply { putParcelable("shared_a", sharedAInstance) // 注意A类要实现Parcelable接口 } } // 替换Fragment的逻辑... } } // 修改Class B,接收外部传入的A实例 class B(private val classA: A) { fun onClickEvent(b:Double){ classA.changeValue(b) } } // 修改Fragment D,获取传入的A实例 class D : Fragment() { private lateinit var classA: A override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.getParcelable<A>("shared_a")?.let { classA = it } } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.your_fragment_layout, container, false) val button = view.findViewById<Button>(R.id.button) button.setOnClickListener { val f = classA.pto1 // 拿到B修改后的值 } return view } } // 让A类实现Parcelable接口 class A : Parcelable { var pto1 = 0.0 fun changeValue(a: Double){ pto1 = a } constructor() // Parcelable相关实现 constructor(parcel: Parcel) : this() { pto1 = parcel.readDouble() } override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeDouble(pto1) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<A> { override fun createFromParcel(parcel: Parcel): A { return A(parcel) } override fun newArray(size: Int): Array<A?> { return arrayOfNulls(size) } } }
方案3:使用观察者模式监听数据变化
如果不想直接共享实例,可以让A类的pto1变成可观察的数据源,B修改数据时自动通知Fragment,Fragment订阅变化即可获取最新值。这里用Android的LiveData举例:
修改A类:
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.LiveData class A { // 用MutableLiveData包装pto1,内部可修改,对外暴露不可修改的LiveData private val _pto1 = MutableLiveData<Double>().apply { value = 0.0 } val pto1: LiveData<Double> = _pto1 fun changeValue(a: Double){ _pto1.value = a } }
修改Class B:
class B { val classA = A() fun onClickEvent(b:Double){ classA.changeValue(b) } // 对外提供A的LiveData,供Fragment订阅 fun getPto1LiveData() = classA.pto1 }
修改Fragment D:
import androidx.lifecycle.Observer class D : Fragment() { // 假设已经获取到Class B的实例(比如通过父组件传递) private lateinit var classB: B override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.your_fragment_layout, container, false) val button = view.findViewById<Button>(R.id.button) // 订阅pto1的变化 classB.getPto1LiveData().observe(viewLifecycleOwner, Observer { newValue -> // 这里可以拿到最新的pto1值,比如存起来或者直接使用 button.setOnClickListener { val f = newValue // 或者直接用newValue } }) return view } // 比如在onAttach中获取Class B实例,或者通过其他方式传递 override fun onAttach(context: Context) { super.onAttach(context) if (context is MainActivity) { classB = context.classB } } }
内容的提问来源于stack exchange,提问作者George Jung
相关产品推荐
相关产品推荐

