kotlin 在导航片段中使用片段

cvxl0en2  于 12个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(155)

代码

主要活动

// MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

个字符

Home Fragment(用于首页)

// HomeFragment.kt

class HomeFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = super.onCreateView(inflater, container, savedInstanceState)

        // init appbar
        var toolbarTitle = view?.findViewById<TextView>(R.id.toolbar_title)
        toolbarTitle?.text = resources.getString(R.string.app_name)

        // init route selection
        val routeSelectionFragment = RouteSelectionFragment(
            Route(Station.Konak, Station.Karsiyaka, Day.Monday)
        )
        requireActivity().supportFragmentManager.beginTransaction().apply {
            replace(R.id.fragmentContainer, routeSelectionFragment)
            commit()
        }

        return view;
    }
}
<!-- fragment_home.xml -->

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        >
        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
            android:textColor="@color/white"
            android:layout_gravity="center" />
    </androidx.appcompat.widget.Toolbar>

    <FrameLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

的字符串

路由选择片段(自定义底部导航栏)

// RouteSelectionFragment.kt

class RouteSelectionFragment(
    private val route: Route,
) : Fragment(R.layout.fragment_route_selection) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val startStationText = getView()?.findViewById<TextView>(R.id.startStationText)
        val endStationText = getView()?.findViewById<TextView>(R.id.endStationText)
        val dayText = getView()?.findViewById<TextView>(R.id.dayText)

        val dayString = resources.getString(
            resources.getIdentifier(
                route.day.nameId,
                "string",
                context?.packageName
            )
        )

        startStationText?.text = route.startStation.name
        endStationText?.text = route.endStation.name
        dayText?.text = dayString
    }
}
<!-- fragment_route_selection.xml -->

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".RouteSelectionFragment">

    <TextView
        android:id="@+id/startStationText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="---"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/imageView"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@drawable/baseline_arrow_right_alt_24"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/endStationText"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/startStationText"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/endStationText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="---"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/imageView3"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@drawable/baseline_alternate_email_24"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/dayText"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/endStationText"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/dayText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="---"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/imageView3"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

说明

我一直在尝试学习原生Android并测试一些东西。通常情况下,我将MainActivity作为我的主页,并将RouteSelectionFragment用作底部应用程序栏。
当我研究导航在原生Android中的工作原理时,我遇到了导航组件(主要是this video)。
因此,我认为使用导航组件将所有home表示移动到它自己的HomeFragment是合理的,它是我目前在项目中唯一的导航片段。
但是,当我启动应用程序时,我在运行时从logcat得到这个错误:

com.erayerdin.izmirferry             E  FATAL EXCEPTION: main
                                                                                                    Process: com.erayerdin.izmirferry, PID: 10751
                                                                                                    java.lang.IllegalArgumentException: No view found for id 0x7f0800c2 (com.erayerdin.izmirferry:id/fragmentContainer) for fragment RouteSelectionFragment{154b91b} (28b4afc2-7d5e-4594-88d4-2ffd409755b0 id=0x7f0800c2)
                                                                                                        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:514)
                                                                                                        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
                                                                                                        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1890)
                                                                                                        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1808)
                                                                                                        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1751)
                                                                                                        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2976)
                                                                                                        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2886)
                                                                                                        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:263)
                                                                                                        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:351)
                                                                                                        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
                                                                                                        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1543)
                                                                                                        at android.app.Activity.performStart(Activity.java:8330)
                                                                                                        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3670)
                                                                                                        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
                                                                                                        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
                                                                                                        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
                                                                                                        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
                                                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:201)
                                                                                                        at android.os.Looper.loop(Looper.java:288)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7872)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)


很明显,我不明白片段是如何工作的,我已经尝试了几个我在这里看到的东西,包括childFragmentManagerparentFragmentManager

epfja78i

epfja78i1#

1.在你的Activity中使用FrameLayout代替androidx.fragment.app.FragmentContainerView。不要忘记给予它一个id。在你的情况下,更好的方法是叫它“fragmentContainer”。
1.您应该在Activity中组织导航。将此代码从HomeFragment移出到Activity,并在用户与屏幕导航栏交互时调用它:

来自片段的代码:

// init route selection
val routeSelectionFragment = RouteSelectionFragment(
    Route(Station.Konak, Station.Karsiyaka, Day.Monday)
)
requireActivity().supportFragmentManager.beginTransaction().apply {
     replace(R.id.fragmentContainer, routeSelectionFragment)
     commit()
}

字符串

移动到Activity:

// init route selection
val routeSelectionFragment = RouteSelectionFragment(
    Route(Station.Konak, Station.Karsiyaka, Day.Monday)
)
supportFragmentManager.beginTransaction().apply {
     replace(R.id.fragmentContainer, routeSelectionFragment)
     commitAllowingStateLoss() // <-- I recommend to use this method
}


您还可以从HomeFragment中删除fragmentContainer

相关问题