'How to set exactly same height for Android bottom navigation bar with these codes?
I am writing codes for Android app. The layout is scrollview fragment is up, and bottom navigation bar down. It displays menu items well and click event works well, however, depending on contents amount displayed in fragment, bottom navigation bar's height is slightly changing.
What solution for this phenomenon? The following is the codes for this:
MainActivity.kt
package info.shutterpress.idols
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import androidx.databinding.DataBindingUtil.setContentView
import com.google.android.material.bottomnavigation.BottomNavigationView
import info.shutterpress.idols.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var view: View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView<ActivityMainBinding>(this, R.layout.activity_main)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
val mBottomNavView = findViewById<BottomNavigationView>(R.id.bottom_navigation_view)
mBottomNavView.setupWithNavController(navController)
mBottomNavView.visibility = View.VISIBLE
view = mBottomNavView
val mBottomNavigationView = view as BottomNavigationView
mBottomNavigationView.setOnNavigationItemSelectedListener { mi ->
when (mi.itemId) {
R.id.home_dest -> {
navController.navigate(R.id.main_fragment)
}
R.id.list_dest -> {
navController.navigate(R.id.recyclerview_fragment)
}
R.id.quiz_dest -> {
}
}
true
}
}
}
MainFragment.kt
package info.shutterpress.idols
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import info.shutterpress.idols.databinding.FragmentMainBinding
class MainFragment : Fragment() {
lateinit var bind: FragmentMainBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
bind = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
return bind.root
}
}
ListFragment.kt
package info.shutterpress.idols
import android.content.res.TypedArray
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.RecyclerView
import info.shutterpress.idols.databinding.FragmentRecyclerviewBinding
class ListFragment : Fragment() {
lateinit var bind: FragmentRecyclerviewBinding
var title: Array<String>? = null
var image: TypedArray? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
bind = DataBindingUtil.inflate(inflater, R.layout.fragment_recyclerview, container, false)
title = resources.getStringArray(R.array.idols_title_array)
image = resources.obtainTypedArray(R.array.idols_list_image_array)
var adapter = IdolsListAdapter(image, title) {
position -> onListItemClick(position)
}
bind.idolsList.adapter = adapter
return bind.root
}
private fun onListItemClick(position: Int) {
val action = ListFragmentDirections.actionRecyclerviewFragmentToDetailFragment(position)
findNavController().navigate(action)
}
inner class ListHolder(
view: View,
private val onItemClicked: (position: Int) -> Unit
) : RecyclerView.ViewHolder(view), View.OnClickListener {
var titleTextView: TextView = view.findViewById(R.id.detail_item_title)
var imageView: ImageView = view.findViewById(R.id.detail_item_image)
init {
view.setOnClickListener(this)
}
override fun onClick(v: View) {
val position = adapterPosition
onItemClicked(position)
}
}
inner class IdolsListAdapter(
var image: TypedArray?,
var title: Array<String>?,
val onItemClicked: (position: Int) -> Unit) :
RecyclerView.Adapter<ListHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : ListHolder {
val view = layoutInflater.inflate(R.layout.item_view, parent, false)
return ListHolder(view, onItemClicked)
}
override fun getItemCount() = title!!.size
override fun onBindViewHolder(holder: ListHolder, position: Int) {
var _image = image!!.getResourceId(position, -1)
var _title = title!![position]
holder.apply {
titleTextView.text = _title
imageView.setImageResource(_image)
}
}
}
}
DetailFragment.kt
package info.shutterpress.idols
import android.content.res.TypedArray
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import info.shutterpress.idols.databinding.FragmentDetailBinding
class DetailFragment : Fragment() {
lateinit var bind: FragmentDetailBinding
var title: Array<String>? = null
var image: TypedArray? = null
var description: Array<String>? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
bind = DataBindingUtil.inflate(inflater, R.layout.fragment_detail, container, false)
val args by navArgs<DetailFragmentArgs>()
var _position = args.positionDatum
title = resources.getStringArray(R.array.idols_title_array)
image = resources.obtainTypedArray(R.array.idols_list_image_array)
description = resources.getStringArray(R.array.idols_description_array)
bind.writingDetailTitle.text = title!![_position]
bind.writingDetailImage.setImageResource(image!!.getResourceId(_position, -1))
bind.writingDetailContent.text = description!![_position]
return bind.root
}
}
activity_main.xml
<layout 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">
<data/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkBeige"
android:layout_margin="0dp"
android:paddingBottom="0dp"
android:orientation="vertical"
tools:context="info.shutterpress.idols.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_main" />
<com.google.android.material.bottomnavigation.BottomNavigationView
app:menu="@menu/menu_bottom_navigation"
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:padding="10dp"
android:theme="@style/Theme.bottomNavApp"
app:backgroundTint="@color/beige"
app:background="@color/beige"
app:itemIconTint="@color/black"
app:itemTextColor="@color/black" />
</LinearLayout>
</layout>
fragment_detail.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<LinearLayout
android:id="@+id/detail_outermost_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_margin="0dp"
android:background="@color/darkBeige"
android:gravity="start"
android:orientation="vertical">
<TextView
android:id="@+id/writing_detail_title"
android:padding="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:paddingTop="10dp"
android:gravity="center"
android:textSize="35sp"
android:textColor="#FFFFFF"
android:textStyle="bold"/>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkBeige"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:scrollbarSize="12dip" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_marginTop="20dp"
android:background="@color/darkBeige"
android:gravity="start"
android:orientation="vertical">
<ImageView
android:id="@+id/writing_detail_image"
android:layout_width="320dp"
android:layout_height="320dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
app:srcCompat="@drawable/idols1" />
<TextView
android:id="@+id/writing_detail_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkBeige"
android:layout_marginTop="20dp"
android:layout_marginBottom="25dp"
android:paddingTop="0dp"
android:padding="20dp"
android:gravity="start"
android:textSize="@dimen/text_size_main"
android:textColor="#de000000"
android:lineSpacingExtra="@dimen/line_spacing_main"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>
fragment_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_margin="0dp"
android:background="@color/darkBeige"
android:gravity="start"
android:orientation="vertical">
<TextView
android:padding="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:paddingTop="10dp"
android:gravity="center"
android:textSize="35sp"
android:textColor="#FFFFFF"
android:textStyle="bold"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkBeige"
android:layout_margin="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:scrollbarSize="12dip" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_margin="0dp"
android:background="@color/darkBeige"
android:gravity="start"
android:orientation="vertical">
<TextView
android:id="@+id/welcome_message"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/darkBeige"
android:layout_margin="0dp"
android:paddingTop="0dp"
android:padding="20dp"
android:gravity="start"
android:textSize="@dimen/text_size_main"
android:lineSpacingExtra="@dimen/line_spacing_main"
android:text="@string/welcome_message"
android:textColor="#de000000" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>
fragment_recyclerview.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="35dp"
android:id="@+id/recyclerview_fragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/idols_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:context="info.shutterpress.idols.MainActivity"
tools:listitem="@layout/item_view"/>
</LinearLayout>
</layout>
Solution 1:[1]
I have asked expert and he gave me appropriate solution! This works!
First, from activity_main.xml,
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" // this should be 0dp
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_main" />
<com.google.android.material.bottomnavigation.BottomNavigationView
app:menu="@menu/menu_bottom_navigation"
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".1" // this should be deleted
android:padding="10dp"
android:theme="@style/Theme.bottomNavApp"
app:backgroundTint="@color/beige"
app:background="@color/beige"
app:itemIconTint="@color/black"
app:itemTextColor="@color/black" />
This works! It was layout XML problem, not Kotlin code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | bluenote1982 |
