在主/详细流程中使用androidx.navigation.ui

时间:2019-11-16 15:00:16

标签: android kotlin androidx

我制作了一个使用标准DrawerLayout模板的应用程序,但是,当尝试将布局调整为较大显示的主/详细布局时,我偶然发现了一些奇怪的行为。而且我不确定在过渡之间如何保持交互/行为相同。

手机的布局是;

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" >

    <include layout="@layout/toolbar"
        android:id="@+id/toolbar_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar_layout"
        app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

<com.google.android.material.navigation.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

平板电脑的布局为;

<?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:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<include layout="@layout/toolbar"
    android:id="@+id/toolbar_layout"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.navigation.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="300dp"
    android:layout_height="0dp"
    app:elevation="3dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@id/nav_host_fragment"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/toolbar_layout"
    app:menu="@menu/activity_main_drawer" />

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/nav_view"
    app:layout_constraintTop_toBottomOf="@id/toolbar_layout"
    app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

附带的工具栏是;

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay" >

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    />

</com.google.android.material.appbar.AppBarLayout>

MainActivity.kt是;

class MainActivity : AppCompatActivity() {

private lateinit var appBarConfiguration: AppBarConfiguration

private var mTablet = false
private lateinit var navController: NavController

override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val toolbar: Toolbar = findViewById(R.id.toolbar)
    setSupportActionBar(toolbar)

     val drawerLayout: DrawerLayout? = findViewById(R.id.drawer_layout)
    if (drawerLayout == null) {
        mTablet = true
    }

    val navView: NavigationView = findViewById(R.id.nav_view)
    navController = findNavController(R.id.nav_host_fragment)
    // Passing each menu ID as a set of Ids because each
    // menu should be considered as top level destinations.
    val navSet = setOf(
        R.id.nav_journal, R.id.nav_reports, R.id.nav_calendar,
        R.id.nav_templates, R.id.nav_copyright, R.id.nav_instructions,
        R.id.nav_settings, R.id.nav_social, R.id.nav_support
    )

    if (mTablet == false) {
        appBarConfiguration = AppBarConfiguration(navSet, drawerLayout)
        setupActionBarWithNavController(navController, appBarConfiguration)
    } else {
        //TODO setup action bar with Nav Controller
        //appBarConfiguration = AppBarConfiguration(navSet, toolbar)
        //val navigationView: ViewGroup = findViewById(R.id.navigation_fragment)
    }

    navView.setupWithNavController(navController)
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
        R.id.action_settings -> {
            navController.navigate(R.id.nav_settings)
        }
        R.id.action_support -> {
            navController.navigate(R.id.nav_support)
        }
        R.id.action_social -> {
            navController.navigate(R.id.nav_social)
        }
        R.id.action_instructions -> {
            navController.navigate(R.id.nav_instructions)
        }
        R.id.action_copyright -> {
            navController.navigate(R.id.nav_copyright)
        }
    }
    return super.onOptionsItemSelected(item)
}

override fun onSupportNavigateUp(): Boolean {
    val navController = findNavController(R.id.nav_host_fragment)
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}

导航xml没有层次结构,它只是片段的集合,我稍后将对其进行扩展。

问题在于主/详细信息流没有DrawerLayout,因此,如果不使用{{1,则无法将工具栏的功能更改为当前显示的片段的标题。 }}。

我意识到Kotlin是null安全的,并且代码无论如何都可以工作,但是,这似乎是在迫使人们接受nullpointer异常的疏忽。

我一直在寻找文档,以找到一种使用不同的构造方法的方法,该方法可以接受工具栏对象(因为正在更新的对象)或其他种类的布局,但无法找到任何东西。是我们应该接受不太理想的代码,还是我缺少其他解决方案?

我正在使用Android Studio在Kotlin中编写我的应用。

0 个答案:

没有答案