Ive recently started programming in android studio for a school project, and i cant seem to get this bottom navigation working. I've watched multiple video's on how to make a navigation using fragments. The problem is that everytime i try to navigate to a fragment it will make the icon go selected, but it won't render the fragment itself
Menu items
<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="" />
Main activity
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView);
val navController = findNavController(R.id.fragment)
bottomNavigationView.setupWithNavController(navController)
Main 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"/>
Navigation
<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" />
CodePudding user response:
Problem
You provide too less important code, but that's why I rebuild your target. And indeed there are some errors occuring. Mostly with dependencies and gradle versions. I think it would be best for all that I provide the whole code as snippets and at the end as project file download.
Solution
GRADLE & DEPENDENCIES
Because of the gradle is important I want to point out that more closly. Your 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
}
And also your build.gradle(module)
with dependencies:
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
Let's start with the MainActivity.kt
that contains the BottomNavigationView
with the loadFragment()
method.
Important: Don't forget the binding
import
shown below!:
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()
}
}
And it's layout 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>
FRAGMENT
Now we have the Activity
done there are 3 Fragment
left. For simplicity I just post FirstFragment.kt
and it's layout fragment_first.xml
. You need to do the same for SecondFragment
and ThirdFragment
of course.
class FirstFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_first, container, false)
}
}
Matching layout:
<?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>
MENU
Now we are going to create a menu
called bottom_navigation.xml
in res/menu
like this:
<?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 AND ICON
We need to define the strings for the TextView
in strings.xml
:
<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>
And also don't forget to add the icon (here I only used one for all fragments) in res/drawable
called ic_menu_black_24dp
.