Reputation: 3804
I am trying to set a badge to a BottomNavigationView
by following this straightforward approach.
However, when I initialize the BottomNavigationView I get:
java.lang.IllegalStateException: view.findViewById(R.id.bottom_navigation_view) must not be null
I am initializing the BottomNativigationView from a fragment. I am guessing that is the issue, but I cannot figure out the solution.
private lateinit var bottomNavigation: BottomNavigationView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_home, container, false)
bottomNavigation = view.findViewById(R.id.bottom_navigation_view)
}
Here is the BottomNavigationView xml for the Activity that sets up navigation for the fragments.
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorWhite"
app:itemIconTint="@color/navigation_tint"
app:itemTextColor="@color/navigation_tint"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_navigation" />
It feels like I am missing something simple, but I cannot figure out what. Thanks!
Upvotes: 0
Views: 740
Reputation: 40810
You can access the activity from its fragment by casting activity
to your activity class, and inflate the views then.
bottomNavigation = (activity as MyActivityName).findViewById(R.id.bottom_navigation_view)
Upvotes: 1
Reputation: 4230
You have many options to communicate betwean fragments - activity and between fragment's itself..
You should not try access activity views from fragment.
Solution 1: Share data with the host activity
class ItemViewModel : ViewModel() {
private val mutableSelectedItem = MutableLiveData<Item>()
val selectedItem: LiveData<Item> get() = mutableSelectedItem
fun selectItem(item: Item) {
mutableSelectedItem.value = item
}
}
class MainActivity : AppCompatActivity() {
// Using the viewModels() Kotlin property delegate from the activity-ktx
// artifact to retrieve the ViewModel in the activity scope
private val viewModel: ItemViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.selectedItem.observe(this, Observer { item ->
// Perform an action with the latest item data
})
}
}
class ListFragment : Fragment() {
// Using the activityViewModels() Kotlin property delegate from the
// fragment-ktx artifact to retrieve the ViewModel in the activity scope
private val viewModel: ItemViewModel by activityViewModels()
// Called when the item is clicked
fun onItemClicked(item: Item) {
// Set a new item
viewModel.selectItem(item)
}
}
Solution 2: Receive results in the host activity
button.setOnClickListener {
val result = "result"
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.setFragmentResultListener("requestKey", this) { requestKey, bundle ->
// We use a String here, but any type that can be put in a Bundle is supported
val result = bundle.getString("bundleKey")
// Do something with the result
}
}
}
There is many more ways but these are latest approaches from Google.
Check this reference: https://developer.android.com/guide/fragments/communicate
Upvotes: 1