如何在Activity中调用Fragment内定义的getData函数
从Activity调用Fragment的getData函数并存储到Firestore
1. 重构Fragment的getData函数
你当前的getData是onViewCreated的局部函数,外部无法访问。需要将其提升为Fragment的成员函数,同时封装数据并处理输入异常:
第一步:创建数据类封装字段
用数据类统一管理所有获取到的库存数据,避免零散变量传递:
data class StockData( val dairyMealStock: Int?, val dairyMealDuration: Int?, val maizeCharmStock: Int?, val maizeCharmDuration: Int?, val wheatBrandStock: Int?, val wheatBrandDuration: Int?, val maizeBrandStock: Int?, val maizeBrandDuration: Int?, val cottonCakeStock: Int?, val cottonCakeDuration: Int?, val pyrethrumStock: Int?, val pyrethrumDuration: Int?, val dcpStock: Int?, val dcpDuration: Int?, val blockStock: Int?, val blockDuration: Int?, val jotoStock: Int?, val jotoDuration: Int?, val yaMaziwaStock: Int?, val yaMaziwaDuration: Int?, val allPurposeStock: Int?, val allPurposeDuration: Int? )
第二步:修改Fragment代码,暴露getData函数
将getData改为Fragment的成员函数,用toIntOrNull处理空输入或非数字的情况,避免崩溃:
class YourFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 其他初始化逻辑 } // 提升为Fragment的公共成员函数,外部可调用 fun getData(): StockData { val dairyMealStock = view?.findViewById<EditText>(R.id.et_dairy_meal_stock)?.text.toString().toIntOrNull() val dairyMealDuration = view?.findViewById<EditText>(R.id.et_dairy_meal_used)?.text.toString().toIntOrNull() val maizeCharmStock = view?.findViewById<EditText>(R.id.et_maize_charm_stock)?.text.toString().toIntOrNull() val maizeCharmDuration = view?.findViewById<EditText>(R.id.et_maize_charm_used)?.text.toString().toIntOrNull() val wheatBrandStock = view?.findViewById<EditText>(R.id.et_wheat_brand_stock)?.text.toString().toIntOrNull() val wheatBrandDuration = view?.findViewById<EditText>(R.id.et_wheat_brand_used)?.text.toString().toIntOrNull() val maizeBrandStock = view?.findViewById<EditText>(R.id.et_maize_brand_stock)?.text.toString().toIntOrNull() val maizeBrandDuration = view?.findViewById<EditText>(R.id.et_maize_brand_used)?.text.toString().toIntOrNull() val cottonCakeStock = view?.findViewById<EditText>(R.id.et_cotton_cake_stock)?.text.toString().toIntOrNull() val cottonCakeDuration = view?.findViewById<EditText>(R.id.et_cotton_cake_used)?.text.toString().toIntOrNull() val pyrethrumStock = view?.findViewById<EditText>(R.id.et_pyrethrum_stock)?.text.toString().toIntOrNull() val pyrethrumDuration = view?.findViewById<EditText>(R.id.et_pyrethrum_used)?.text.toString().toIntOrNull() val dcpStock = view?.findViewById<EditText>(R.id.et_D_C_P_stock)?.text.toString().toIntOrNull() val dcpDuration = view?.findViewById<EditText>(R.id.et_D_C_P_duration)?.text.toString().toIntOrNull() val blockStock = view?.findViewById<EditText>(R.id.et_block_stock)?.text.toString().toIntOrNull() val blockDuration = view?.findViewById<EditText>(R.id.et_Block_duration)?.text.toString().toIntOrNull() val jotoStock = view?.findViewById<EditText>(R.id.et_joto_stock)?.text.toString().toIntOrNull() val jotoDuration = view?.findViewById<EditText>(R.id.et_joto_duration)?.text.toString().toIntOrNull() val yaMaziwaStock = view?.findViewById<EditText>(R.id.et_ya_maziwa_stock)?.text.toString().toIntOrNull() val yaMaziwaDuration = view?.findViewById<EditText>(R.id.et_ya_maziwa_duration)?.text.toString().toIntOrNull() val allPurposeStock = view?.findViewById<EditText>(R.id.et_all_purpose_stock)?.text.toString().toIntOrNull() val allPurposeDuration = view?.findViewById<EditText>(R.id.et_all_purpose_duration)?.text.toString().toIntOrNull() return StockData( dairyMealStock, dairyMealDuration, maizeCharmStock, maizeCharmDuration, wheatBrandStock, wheatBrandDuration, maizeBrandStock, maizeBrandDuration, cottonCakeStock, cottonCakeDuration, pyrethrumStock, pyrethrumDuration, dcpStock, dcpDuration, blockStock, blockDuration, jotoStock, jotoDuration, yaMaziwaStock, yaMaziwaDuration, allPurposeStock, allPurposeDuration ) } }
2. 在主Activity中调用并存储到Firestore
先获取Fragment实例,调用getData拿到数据后,直接将数据类对象传入Firestore完成存储:
class MainActivity : AppCompatActivity() { private lateinit var db: FirebaseFirestore override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) db = FirebaseFirestore.getInstance() // 通过布局ID获取Fragment实例(如果是动态添加的,用findFragmentByTag) val yourFragment = supportFragmentManager.findFragmentById(R.id.your_fragment_id) as? YourFragment // 示例:在按钮点击时触发存储逻辑 findViewById<Button>(R.id.btn_save_data).setOnClickListener { yourFragment?.let { fragment -> val stockData = fragment.getData() // 可选:验证数据是否完整(根据业务需求调整) val hasEmptyValue = listOf( stockData.dairyMealStock, stockData.dairyMealDuration, stockData.maizeCharmStock, stockData.maizeCharmDuration, // 其他需要验证的字段... ).any { it == null } if (!hasEmptyValue) { // 存储到Firestore db.collection("stock_records") .add(stockData) .addOnSuccessListener { docRef -> Log.d("Firestore", "数据存储成功,文档ID:${docRef.id}") // 存储成功后的UI提示逻辑 } .addOnFailureListener { e -> Log.w("Firestore", "数据存储失败", e) // 错误处理逻辑 } } else { // 提示用户输入不完整 } } } } }
关键注意事项
- 函数可见性:确保
getData是Fragment的公共函数(Kotlin默认public),不要放在onViewCreated内部作为局部函数。 - 空值处理:用
toIntOrNull替代toInt,避免用户输入空值或非数字内容时崩溃。 - Fragment实例有效性:调用
getData前要确保Fragment已附加到Activity,实例不为null。 - Firestore序列化:Firestore支持直接存储数据类对象,前提是数据类有默认构造函数(Kotlin数据类自动生成)。
内容的提问来源于stack exchange,提问作者Victor kiptoo
相关产品推荐
相关产品推荐

