I have a main activity with a heading and a search field (edit text), I want to be able to search and the results are immediately shown in the fragment, like an onChange instead of waiting for the user to click a button to filter results. (which is in the activity).
I can get it working if I include the Edit Text in my fragment too, but I don't want it that way for design purposes, I'd like to retrieve the user values as they are typed from the activity, and get them in my fragment to filter results
I've tried Bundles but could not get it working, and also not sure If i could use Bundles to get the results as they are being input.
Here's a screenshot to help understand better
CodePudding user response:
You can make it happen using ViewModel MVVM architecture.
MainActivity:
binding.editText.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
viewModel.updateSearchText(s)
}
})
ViewModel:
private val _searchText = MutableLiveData<Editable?>()
val searchText: LiveData<Editable?> get() = _searchText
fun updateSearchText(text: Editable?) {
_searchText.value = s
}
Fragment:
searchText.observe(viewLifecycleOwner) {
// TODO: handle the searched query using [it] keyword.
}
If you don't know what View Model is or how to implement it, use the official Google tutorial: https://developer.android.com/codelabs/basic-android-kotlin-training-viewmodel
CodePudding user response:
Another way to achieve this (besides using an Android ViewModel) is use the Fragment Result API.
For instance, if you place the EditText
into a fragment (let's call it QueryFragment
), you can get the result of the QueryFragment
in your SearchResults
fragment like so:
// In QueryFragment
editText.addTextChangedListener(object: TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
override fun afterTextChanged(s: Editable?) {
setFragmentResult("searchQueryRequestKey", bundleOf("searchQuery" to s.toString()))
}
})
// In SearchResultsFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Retrieve the searched string from QueryFragment
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResultListener("searchQueryRequestKey") { requestKey, bundle ->
val searchQuery = bundle.getString("searchQuery")
// Perform the search using the searchQuery and display the search results
}
}