You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Fragment数据传递异常:NgoSignup2Fragment获值为Null

Fragment间数据传递为空问题排查

问题描述

尝试从NgoSignup1Fragment向NgoSignup2Fragment传递数据,MainActivity通过Communicator接口接收数据时变量值均正确,但NgoSignup2Fragment中获取到的所有变量值均为Null。

相关代码

NgoSignup1Fragment代码

class NgoSignup1Fragment : Fragment() {

private lateinit var communicator: Communicator
private lateinit var nextBtn: Button

private var name : TextInputEditText ?=null
private var mail : TextInputEditText ?=null
private var phone : TextInputEditText ?=null
private var add :TextInputEditText ?=null
private var pinCode :TextInputEditText ?=null
private var password :TextInputEditText ?=null
private var confirmPassword :TextInputEditText ?=null

private val emailPattern = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+"

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?,

): View? {
    val v = layoutInflater.inflate(R.layout.ngo_signup1_fragment, container, false)
    communicator = activity as Communicator

    nextBtn = v.findViewById(R.id.btn_ngosignup1_next)

    name = v?.findViewById(R.id.et_ngosignup_name)
    mail = v?.findViewById(R.id.et_ngosignup_mail)
    phone = v?.findViewById(R.id.et_ngosignup_phone)
    add = v?.findViewById(R.id.et_ngosignup_address)
    pinCode = v?.findViewById(R.id.et_ngosignup_pincode)
    password =v?.findViewById(R.id.et_ngosignup_password)
    confirmPassword =v?.findViewById(R.id.et_ngosignup_confirmpassword)


    nextBtn.setOnClickListener {
        val orgName = name?.text.toString().trim()
        val orgMail = mail?.text.toString().trim()
        val orgPhone = phone?.text.toString().trim()
        val officeAdd = add?.text.toString().trim()
        val orgPinCode = pinCode?.text.toString().trim()
        val orgPass = password?.text.toString().trim()
        val confirmPass=confirmPassword?.text.toString().trim()
        if (orgName.isEmpty()) {
            name?.error = "Please provide organisation's name"
            markButtonDisable(nextBtn)
        }
        if (orgMail.isEmpty()) {
            mail?.error = "Mail cannot be empty"
            markButtonDisable(nextBtn)
        }
        if (orgPhone.isEmpty()) {
            phone?.error = "Enter your phone number"
            markButtonDisable(nextBtn)
        }
        if (officeAdd.isEmpty()) {
            add?.error = "Address cannot be empty"
            markButtonDisable(nextBtn)
        }
        if (orgPinCode.isEmpty()) {
            name?.error = "Name cannot be empty"
            markButtonDisable(nextBtn)
        }
        if (orgPass.isEmpty()){
            password?.error = "Password cannot be empty"
            markButtonDisable(nextBtn)
        }
        if (!(orgMail.matches(emailPattern.toRegex()))) {
            mail?.error = "Invalid email"
            markButtonDisable(nextBtn)
        }
        if (!(isValidPassword(orgPass))) {
            password?.error = "Password format is invalid"
            markButtonDisable(nextBtn)
        }
        if(orgPass != confirmPass){
            confirmPassword?.error = "Passwords doesn't match"
            markButtonDisable(nextBtn)
        }else{
           communicator.passDataCom(orgName,orgMail,orgPhone,officeAdd,orgPinCode,orgPass)
            activity?.supportFragmentManager?.beginTransaction()
                ?.replace(
                    R.id.fragment_container1,
                    NgoSignup2Fragment()
                )?.addToBackStack(null)?.commit()
        }

    }

    return v
}
private fun isValidPassword(password: String): Boolean {
    val passwordREGEX = Pattern.compile(
        "^" +
                "(?=.*[0-9])" +         //at least 1 digit
                "(?=.*[a-z])" +         //at least 1 lower case letter
                "(?=.*[A-Z])" +         //at least 1 upper case letter
                "(?=.*[a-zA-Z])" +      //any letter
                "(?=.*[@#$%^&+=])" +    //at least 1 special character
                "(?=\\S+$)" +           //no white spaces
                ".{8,}" +               //at least 8 characters
                "$"
    )
    return passwordREGEX.matcher(password).matches()
}
private fun markButtonDisable(b:Button){
    b.isEnabled =false
    b.setBackgroundColor(resources.getColor(R.color.theme_button_disabled))
}}

数据传递接口Communicator

interface Communicator {
fun passDataCom(
    orgName: String,
    orgMail: String,
    orgPhone: String,
    officeAdd: String,
    orgPin: String,
    orgPass: String
)}

MainActivity代码

class MainActivity : AppCompatActivity(),Communicator {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setTheme(R.style.Theme_Samarpan)
    setContentView(R.layout.activity_main)
    addFragment()

}

private fun addFragment() {
    val userSignInLayout= LoginFragment()
    supportFragmentManager.beginTransaction().add(R.id.fragment_container1,userSignInLayout).commit()
}

override fun passDataCom(
    orgName: String,
    orgMail: String,
    orgPhone: String,
    officeAdd: String,
    orgPin: String,
    orgPass: String
) {
    val bundle=Bundle()
    bundle.putString("Name",orgName)
    bundle.putString("Mail",orgMail)
    bundle.putString("Phone",orgPhone)
    bundle.putString("Address",officeAdd)
    bundle.putString("PinCode",orgPin)
    bundle.putString("Password",orgPass)

    val transaction=this.supportFragmentManager.beginTransaction()
    val ngoSignUp2 = NgoSignup2Fragment()
    ngoSignUp2.arguments = bundle
    transaction. Commit()
}}

接收数据的NgoSignup2Fragment代码

class NgoSignup2Fragment : Fragment(){

private var v : View?=null
private var btnNgoRegister: Button?=null
private var tilCategoryOthers:TextInputLayout?=null
private var etCategoryOthers:TextInputEditText?=null


private var orgName:String =""
private var orgMail:String =""
private var orgPhone:String =""
private var officeAdd:String =""
private var orgPin:String =""
private var orgPass:String =""
private var category:String=""

private lateinit var registerAuth: FirebaseAuth


override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    v = layoutInflater.inflate(R.layout.ngo_signup2_fragment,container,false)
    btnNgoRegister=v?.findViewById(R.id.btnNgoRegister)
    tilCategoryOthers=v?.findViewById(R.id.til_category_others)
    etCategoryOthers=v?.findViewById(R.id.et_category_others)

    val organisationTypes = resources.getStringArray(R.array.organisation_type)
    val arrayAdapter = ArrayAdapter(requireContext(),R.layout.dropdown_item,organisationTypes)
    val autoCompleteTV= v?.findViewById<AutoCompleteTextView>(R.id.ngosignup_select_orgtype_items)
    autoCompleteTV?.setAdapter(arrayAdapter)

    category=autoCompleteTV?.text.toString().trim()

    registerAuth= Firebase.auth

    orgName= arguments?.getString("Name").toString().trim()
    orgMail= arguments?.getString("Mail").toString().trim()
    orgPhone=arguments?.getString("Phone").toString().trim()
    officeAdd=arguments?.getString("Address").toString().trim()
    orgPin=arguments?.getString("PinCode").toString().trim()
    orgPass=arguments?.getString("Password").toString().trim()

    btnNgoRegister?.setOnClickListener {
        Toast.makeText(activity, orgName, Toast.LENGTH_SHORT).show()
        if(category == "Others"){
            btnNgoRegister?.isEnabled=false
            tilCategoryOthers?.visibility=View.VISIBLE
            category=etCategoryOthers?.text.toString()
            btnNgoRegister?.isEnabled=true
        }
        val db = FirebaseFirestore.getInstance()
        try{
            registerAuth.createUserWithEmailAndPassword(orgMail,orgPass)
                .addOnCompleteListener{ task->
                    if(task.isSuccessful){
                        val ngo: FirebaseUser? =registerAuth.currentUser
                        Toast.makeText(
                            activity,
                            "Thank You! for choosing us",
                            Toast.LENGTH_SHORT
                         ).show()
                        val documentReference : DocumentReference =db.collection("users").document(
                            ngo?.uid ?: ""
                     )
                        val ngoInfo :MutableMap<String,Any> = HashMap()
                        ngoInfo["Full Name"]= orgName
                        ngoInfo["Email"]= orgMail
                        ngoInfo["PhoneNumber"]=orgPhone
                        ngoInfo["Address"]=officeAdd
                        ngoInfo["Pin Code"]=orgPin
                        ngoInfo["isDonor"]="0"
                        documentReference.set(ngoInfo).addOnSuccessListener {
                            Log.d(ContentValues.TAG, "User data for $orgName was collected successfully ")
                        }.addOnFailureListener{ e ->
                            Log.w(ContentValues.TAG, "Error adding data", e)
                        }
                }else{
                        Toast.makeText(
                            activity,
                            task.exception!!.message.toString(),
                            Toast.LENGTH_SHORT
                        ).show()
                    }
            }
    }
    catch(e :Exception){
        Toast.makeText(context, "Fields cannot be empty $e", Toast.LENGTH_SHORT).show()
    }
    }
    return v
}}

问题原因

核心问题在于两次创建了不同的NgoSignup2Fragment实例:

  1. MainActivity的passDataCom方法中,创建了绑定数据的NgoSignup2Fragment实例,但仅调用了拼写错误的transaction.Commit()(应为小写commit()),未执行replace操作将该实例加载到容器。
  2. NgoSignup1Fragment的按钮点击事件里,又新建了一个无数据绑定的NgoSignup2Fragment实例并执行替换,导致接收端获取不到数据。

修复方案

方案一:让MainActivity负责Fragment替换

  1. 更新MainActivity的passDataCom方法,完成替换逻辑:
override fun passDataCom(
    orgName: String,
    orgMail: String,
    orgPhone: String,
    officeAdd: String,
    orgPin: String,
    orgPass: String
) {
    val bundle=Bundle()
    bundle.putString("Name",orgName)
    bundle.putString("Mail",orgMail)
    bundle.putString("Phone",orgPhone)
    bundle.putString("Address",officeAdd)
    bundle.putString("PinCode",orgPin)
    bundle.putString("Password",orgPass)

    val ngoSignUp2 = NgoSignup2Fragment()
    ngoSignUp2.arguments = bundle

    supportFragmentManager.beginTransaction()
        .replace(R.id.fragment_container1, ngoSignUp2)
        .addToBackStack(null)
        .commit()
}
  1. 修改NgoSignup1Fragment的按钮点击逻辑,移除自行创建Fragment的代码:
else{
    communicator.passDataCom(orgName,orgMail,orgPhone,officeAdd,orgPinCode,orgPass)
    // 移除以下代码
    // activity?.supportFragmentManager?.beginTransaction()
    //     ?.replace(
    //         R.id.fragment_container1,
    //         NgoSignup2Fragment()
    //     )?.addToBackStack(null)?.commit()
}

方案二:直接在NgoSignup1Fragment中传递数据

若无需MainActivity处理数据,可直接在NgoSignup1Fragment中完成数据传递与Fragment替换,简化流程:

else{
    val bundle=Bundle()
    bundle.putString("Name",orgName)
    bundle.putString("Mail",orgMail)
    bundle.putString("Phone",orgPhone)
    bundle.putString("Address",officeAdd)
    bundle.putString("PinCode",orgPinCode)
    bundle.putString("Password",orgPass)

    val ngoSignUp2 = NgoSignup2Fragment()
    ngoSignUp2.arguments = bundle

    activity?.supportFragmentManager?.beginTransaction()
        ?.replace(R.id.fragment_container1, ngoSignUp2)
        ?.addToBackStack(null)
        ?.commit()
}

此方案可同步移除Communicator接口及MainActivity中的对应实现代码。

内容的提问来源于stack exchange,提问作者Jadu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:20:31