android 如何将数据从Activity传递到FragmentKotlin?

zfciruhq  于 2022-12-09  发布在  Android
关注(0)|答案(2)|浏览(169)

我使用Firebase Auth和Firestore登录屏幕,并将Firestore和Firebase Auth链接到同一个电子邮件。我希望当我登录或注册到应用程序的电子邮件,它必须传递到其他活动的片段,如果它将是成功的,我可以访问Firestore。我尝试了捆绑包和SafeArgs,但它总是给予我空。我不能解决这个恼人的问题。我将离开我的代码。

登录活动.kt

private val db = Firebase.firestore.collection("users")
private val auth = Firebase.auth
private lateinit var binding: ActivityLoginBinding

private fun loginUser(email: String, password: String) {
        if (email.isNotEmpty() && password.isNotEmpty()) {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    auth.signInWithEmailAndPassword(email, password)
                        .addOnSuccessListener {
                            val fragment = MainFragment()
                            val bundle = Bundle()
                            bundle.putString("mail", email)
                            fragment.arguments = bundle
                            checkLogged()
                            Toast.makeText(this@LoginActivity, "Welcome Again", Toast.LENGTH_SHORT)
                                .show()
                        }
                        .addOnFailureListener {
                            Toast.makeText(this@LoginActivity, it.message, Toast.LENGTH_LONG).show()
                        }.await()
                } catch (e: Exception) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@LoginActivity, e.message, Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }

    private fun registerUser(email: String, password: String, user: User) {
        if (email.isNotEmpty() && password.isNotEmpty()) {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    auth.createUserWithEmailAndPassword(email, password)
                        .addOnSuccessListener {
                            db.document(user.email).set(user)
                            val fragment = MainFragment()
                            val bundle = Bundle()
                            bundle.putString("email", user.email)
                            fragment.arguments = bundle
                            checkLogged()
                            Toast.makeText(
                                this@LoginActivity,
                                "Welcome ${user.name}",
                                Toast.LENGTH_SHORT
                            ).show()
                        }.await()
                } catch (e: java.lang.Exception) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@LoginActivity, e.message, Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }

    private fun checkLogged() {
        if (Firebase.auth.currentUser != null) {
            Firebase.auth.currentUser!!.reload()
            startActivity(Intent(this@LoginActivity, MainActivity::class.java))
            finish()
        } else {
            //
        }
    }

主要片段.kt

class MainFragment : Fragment() {

private val db = Firebase.firestore.collection("users")
private lateinit var binding: FragmentMainBinding

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    binding = FragmentMainBinding.inflate(inflater, container, false)
    if (arguments != null){
        val textName = arguments?.getString("email")
        binding.txtName.text = textName
    }
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

}

导航图形.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/mainFragment">
    <fragment
        android:id="@+id/addMealFragment"
        android:name="com.meetozan.caloriecounter.AddMealFragment"
        android:label="fragment_add_meal"
        tools:layout="@layout/fragment_add_meal" />
    <fragment
        android:id="@+id/calendarFragment"
        android:name="com.meetozan.caloriecounter.CalendarFragment"
        android:label="fragment_calendar"
        tools:layout="@layout/fragment_calendar" />
    <fragment
        android:id="@+id/foodsFragment"
        android:name="com.meetozan.caloriecounter.FoodsFragment"
        android:label="fragment_foods"
        tools:layout="@layout/fragment_foods" />
    <fragment
        android:id="@+id/leaderboardFragment"
        android:name="com.meetozan.caloriecounter.LeaderboardFragment"
        android:label="fragment_leaderboard"
        tools:layout="@layout/fragment_leaderboard" />
    <fragment
        android:id="@+id/mainFragment"
        android:name="com.meetozan.caloriecounter.MainFragment"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main">
        <action
            android:id="@+id/action_mainFragment_to_addMealFragment"
            app:destination="@id/addMealFragment" />
        <action
            android:id="@+id/action_mainFragment_to_calendarFragment"
            app:destination="@id/calendarFragment" />
        <action
            android:id="@+id/action_mainFragment_to_foodsFragment"
            app:destination="@id/foodsFragment" />
        <action
            android:id="@+id/action_mainFragment_to_leaderboardFragment"
            app:destination="@id/leaderboardFragment" />
        <argument
            android:name="email"
            app:argType="string"
            app:nullable="true" />
    </fragment>
    <activity
        android:id="@+id/loginActivity"
        android:name="com.meetozan.caloriecounter.LoginActivity"
        android:label="activity_login"
        tools:layout="@layout/activity_login" />
</navigation>
czq61nw1

czq61nw11#

这里的问题是,您在LoginActivity中创建了一个Fragment示例,为该Fragment设置了参数,然后您启动了一个新的ActivityMainActivity。您没有使用此Fragment引用执行任何操作,在您更改Activity后,它基本上被遗忘了。
为了更好地理解这一点,你应该提醒自己面向对象编程的基础知识+Android片段背后的逻辑+活动。
我建议删除LoginActivity中的Fragment创建。然后您可以做的是:
1.首先将电子邮件添加到MainActivity Intent extras中。
1.现在您的MainActivity中有了电子邮件,您可以将其传递到navGraph startDestination。您可以在其他线程中找到有关如何执行此操作的信息,例如:Navigation Architecture Component- Passing argument data to the startDestination
1.或者,您也可以在Fragment中使用requireActivity()来访问Activity,但我不推荐这样做。

ezykj2lf

ezykj2lf2#

正如Mert Ozan所提到的,在LoginActivity.kt中创建的Fragment引用在Main Activity中没有被引用。
而不是尝试将电子邮件地址从登录活动传递到主活动。您可以直接在主活动中访问当前登录用户的电子邮件。
类似于:

private lateinit var auth: FirebaseAuth
...
override fun onCreate(..)..{ // (or onCreateView depending where u want to access the email)
    ...

    auth = Firebase.getInstance()
    val email = auth.currentUser?.email.toString()

    ...
}

相关问题