导航不会呈现片段
Navigation won't render fragments
我最近开始在 android 工作室为学校项目编程,但我似乎无法使用底部导航。我看过多个关于如何使用片段进行导航的视频。问题是,每次我尝试导航到一个片段时,它都会让图标被选中,但它不会呈现片段本身
菜单项
<item android:id="@+id/mainActivity" android:enabled="true" android:icon="@drawable/receipt" android:title=""/> <item android:id="@+id/firstFragment" android:enabled="true" android:icon="@drawable/search" android:title="" />
主要activity
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView);
val navController = findNavController(R.id.fragment)
bottomNavigationView.setupWithNavController(navController)
主要 activity XML
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:itemIconTint="@color/black"
app:itemTextColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:menu="@menu/menu"/>
<fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="411dp"
android:layout_marginRight="411dp"
android:layout_marginBottom="731dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/bottomNavigationView"
app:navGraph="@navigation/my_nav"/>
导航
<activity
android:id="@+id/mainActivity"
android:name="nl.bunus.bunusmobileapp.MainActivity"
android:label="activity_main"
tools:layout="@layout/activity_main" />
<fragment
android:id="@+id/firstFragment"
android:name="nl.bunus.bunusmobileapp.firstFragment"
android:label="fragment_first"
tools:layout="@layout/fragment_first" />
问题
你提供的代码太不重要了,但这就是我重建你的目标的原因。确实发生了一些错误。主要是依赖项和 gradle 版本。我认为最好将整个代码作为片段提供,最后作为项目文件下载。
解决方案
GRADLE & 依赖项
因为 gradle 很重要,所以我想更详细地指出这一点。你的 build.gradle("projectname")
:
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
还有你的 build.gradle(module)
依赖项:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.kotlinapplication"
minSdk 30
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
ACTIVITY
让我们从包含 BottomNavigationView
和 loadFragment()
方法的 MainActivity.kt
开始。
重要:不要忘记下面显示的binding
import
!:
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title=resources.getString(R.string.fragment1)
loadFragment(FirstFragment())
navigationView.setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.navigation_appoint-> {
title=resources.getString(R.string.fragment1)
loadFragment(FirstFragment())
return@setOnNavigationItemSelectedListener true
}
R.id.navigation_new_appoint-> {
title=resources.getString(R.string.second_menu)
loadFragment(SecondFragment())
return@setOnNavigationItemSelectedListener true
}
R.id.navigation_settings-> {
title=resources.getString(R.string.third_menu)
loadFragment(ThirdFragment())
return@setOnNavigationItemSelectedListener true
}
}
false
}
}
private fun loadFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.container, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
它的布局 activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navigationView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
片段
现在我们已经 Activity
完成了,还剩下 3 Fragment
个。为简单起见,我只是 post FirstFragment.kt
和它的布局 fragment_first.xml
。当然,您需要对 SecondFragment
和 ThirdFragment
执行相同的操作。
class FirstFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_first, container, false)
}
}
匹配布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF9800">
<TextView android:layout_width="match_parent"
android:layout_centerInParent="true"
android:textAlignment="center"
android:textSize="18sp"
android:text="@string/first_menu"
android:layout_height="wrap_content"/>
</RelativeLayout>
菜单
现在我们要在 res/menu
中创建一个名为 bottom_navigation.xml
的 menu
,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_appoint"
android:icon="@drawable/ic_menu_black_24dp"
android:title="@string/fragment1"/>
<item
android:id="@+id/navigation_new_appoint"
android:icon="@drawable/ic_menu_black_24dp"
android:title="@string/fragment2"/>
<item
android:id="@+id/navigation_settings"
android:icon="@drawable/ic_menu_black_24dp"
android:title="@string/fragment3"/>
</menu>
字符串和图标
我们需要在strings.xml
中为TextView
定义字符串:
<resources>
<string name="app_name">KotlinApplication</string>
<string name="fragment1">Fragment 1</string>
<string name="fragment2">Fragment 2</string>
<string name="fragment3">Fragment 3</string>
<string name="first_menu">First Fragment</string>
<string name="second_menu">Second Fragment</string>
<string name="third_menu">Third Fragment</string>
</resources>
并且不要忘记在 res/drawable
中添加图标(这里我只为所有片段使用一个)名为 ic_menu_black_24dp
。
下载项目
您可以下载完整的项目here(主办方:Workupload)
结果
最后我们有一个 BottomNavigationView
可以在其项目中导航 3 Fragments
。
我最近开始在 android 工作室为学校项目编程,但我似乎无法使用底部导航。我看过多个关于如何使用片段进行导航的视频。问题是,每次我尝试导航到一个片段时,它都会让图标被选中,但它不会呈现片段本身
菜单项
<item android:id="@+id/mainActivity" android:enabled="true" android:icon="@drawable/receipt" android:title=""/> <item android:id="@+id/firstFragment" android:enabled="true" android:icon="@drawable/search" android:title="" />
主要activity
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView);
val navController = findNavController(R.id.fragment)
bottomNavigationView.setupWithNavController(navController)
主要 activity XML
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:itemIconTint="@color/black"
app:itemTextColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:menu="@menu/menu"/>
<fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="411dp"
android:layout_marginRight="411dp"
android:layout_marginBottom="731dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/bottomNavigationView"
app:navGraph="@navigation/my_nav"/>
导航
<activity
android:id="@+id/mainActivity"
android:name="nl.bunus.bunusmobileapp.MainActivity"
android:label="activity_main"
tools:layout="@layout/activity_main" />
<fragment
android:id="@+id/firstFragment"
android:name="nl.bunus.bunusmobileapp.firstFragment"
android:label="fragment_first"
tools:layout="@layout/fragment_first" />
问题
你提供的代码太不重要了,但这就是我重建你的目标的原因。确实发生了一些错误。主要是依赖项和 gradle 版本。我认为最好将整个代码作为片段提供,最后作为项目文件下载。
解决方案
GRADLE & 依赖项
因为 gradle 很重要,所以我想更详细地指出这一点。你的 build.gradle("projectname")
:
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
还有你的 build.gradle(module)
依赖项:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.kotlinapplication"
minSdk 30
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
ACTIVITY
让我们从包含 BottomNavigationView
和 loadFragment()
方法的 MainActivity.kt
开始。
重要:不要忘记下面显示的binding
import
!:
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title=resources.getString(R.string.fragment1)
loadFragment(FirstFragment())
navigationView.setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.navigation_appoint-> {
title=resources.getString(R.string.fragment1)
loadFragment(FirstFragment())
return@setOnNavigationItemSelectedListener true
}
R.id.navigation_new_appoint-> {
title=resources.getString(R.string.second_menu)
loadFragment(SecondFragment())
return@setOnNavigationItemSelectedListener true
}
R.id.navigation_settings-> {
title=resources.getString(R.string.third_menu)
loadFragment(ThirdFragment())
return@setOnNavigationItemSelectedListener true
}
}
false
}
}
private fun loadFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.container, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
它的布局 activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navigationView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
片段
现在我们已经 Activity
完成了,还剩下 3 Fragment
个。为简单起见,我只是 post FirstFragment.kt
和它的布局 fragment_first.xml
。当然,您需要对 SecondFragment
和 ThirdFragment
执行相同的操作。
class FirstFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_first, container, false)
}
}
匹配布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF9800">
<TextView android:layout_width="match_parent"
android:layout_centerInParent="true"
android:textAlignment="center"
android:textSize="18sp"
android:text="@string/first_menu"
android:layout_height="wrap_content"/>
</RelativeLayout>
菜单
现在我们要在 res/menu
中创建一个名为 bottom_navigation.xml
的 menu
,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_appoint"
android:icon="@drawable/ic_menu_black_24dp"
android:title="@string/fragment1"/>
<item
android:id="@+id/navigation_new_appoint"
android:icon="@drawable/ic_menu_black_24dp"
android:title="@string/fragment2"/>
<item
android:id="@+id/navigation_settings"
android:icon="@drawable/ic_menu_black_24dp"
android:title="@string/fragment3"/>
</menu>
字符串和图标
我们需要在strings.xml
中为TextView
定义字符串:
<resources>
<string name="app_name">KotlinApplication</string>
<string name="fragment1">Fragment 1</string>
<string name="fragment2">Fragment 2</string>
<string name="fragment3">Fragment 3</string>
<string name="first_menu">First Fragment</string>
<string name="second_menu">Second Fragment</string>
<string name="third_menu">Third Fragment</string>
</resources>
并且不要忘记在 res/drawable
中添加图标(这里我只为所有片段使用一个)名为 ic_menu_black_24dp
。
下载项目
您可以下载完整的项目here(主办方:Workupload)
结果
最后我们有一个 BottomNavigationView
可以在其项目中导航 3 Fragments
。