Good day
I have a customized spinner and it shows the string array without any issue. But when I add the onItemSelectedListener my application will crash when loading the fragment.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
auth = Firebase.auth
// show back button
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
val result = inflater.inflate(R.layout.fragment_new_key, container, false)
val spinner: Spinner = result.findViewById(R.id.spinner_Category)
ArrayAdapter.createFromResource(
requireContext(), R.array.keyCategory, R.layout.spinner_item
).also { adapter ->
spinner.adapter = adapter
}
// without adding the below, the application will work smoothly
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
TODO("Not yet implemented")
}
}
return result
}
Could you please help, is there something conflicting with the spinner that pushed the application to crash?
Thank you.
Remove these lines
TODO("Not yet implemented")
TODO throws NotImplementedError
Related
How do you restore the Spinners selected item index a view model?
Right now I have a setup where you set a selectedIndex property on the ViewModel within the spinners OnItemSelectedListener.
The problem I'm running into is that every time the Fragment recreates, the selected listener gets re-assigned to the spinner, and the OnItemSelectedListener get fired for index 0, overriding whatever is stored in the ViewModel.
I feel like I'm missing something super simple here.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Set the spinners onItemSelectedListener
binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
viewModel.setSelectedItem(p2)
}
override fun onNothingSelected(p0: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
// Restore spinner to previously selected state
viewModel.getSelectedCompanyIndex().let {
binding.spinner.setSelection(it)
}
// Observe the spinner data.
viewModel.spinnerData.observe(this) { spinnerArray ->
ArrayAdapter(
requireContext(),
R.layout.simple_spinner_dropdown_item,
spinnerArray
).also {
binding.spinner.adapter = it
}
}
I have a problem with the spinner inside a fragment. The spinner is filled with data, but when I select an item I don't see logs, and in the spinner, it does not select elements. When I used nearly the same code as an activity it worked (Just changed the context to this in the adapter)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_edit_stoper, container, false)
val tagSpinner = view.findViewById<Spinner>(R.id.editSpinner)
val items: MutableList<String> = ArrayList("a","b","c")
tagSpinner.adapter = ArrayAdapter(this.requireActivity(), android.R.layout.simple_spinner_item, items) as SpinnerAdapter
tagSpinner.onItemSelectedListener = this
return view
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
Log.d(TAG,"OnItemSelected: $type")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
Log.d(TAG,"error")
}
}
Is your fragment really a listener for spinner?
Write a custom listener and use that instead of your fragment.
inner class SpinnerStateChangeListener : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
// do sth here
}
override fun onNothingSelected(parent: AdapterView<*>?) {
// do sth here
}
}
Now you can set your listener like this:
tagSpinner.onItemSelectedListener = SpinnerStateChangeListener()
Try moving your implementation from Fragment directly to spinner. remove override from class and instead of
tagSpinner.onItemSelectedListener = this
do
tagSpinner.onItemSelectedListener = object :AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
Log.d(TAG,"error")
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
Log.d(TAG,"OnItemSelected: $type")
}
}
The solution is to add requireActivity().applicationContext in the adapter to change the activityFragment to a context:
...
val items: MutableList<String> = ArrayList("a","b","c")
tagSpinner.adapter = ArrayAdapter(requireActivity().applicationContext, android.R.layout.simple_spinner_item, items) as SpinnerAdapter
tagSpinner.onItemSelectedListener = this
...
my spinner is not populating
#RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val adapter = ArrayAdapter.createFromResource(requireContext(), R.array.duration, android.R.layout.simple_spinner_item) as SpinnerAdapter
_binding?.duration?.adapter = adapter
_binding?.duration?.onItemSelectedListener = object :
AdapterView.OnItemSelectedListener {
#RequiresApi(Build.VERSION_CODES.O)
override fun onItemSelected(parent: AdapterView<*>,
view: View, position: Int, id: Long) {
val followeredata = followerData()
var followercount = followeredata.getcount(position)
Log.i("menu selected"," on item is selected")
}
override fun onNothingSelected(parent: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
I have tried different methods of creating adapter but none of them are able to populate the spinner. but if I create them from XML:entries it works fine. how do I populate my spinner from code
I have a simple recycler view that reads a list from the database, I can see data when I log them to the console, but it doesn't show in the recycler view
The function below is in the kotlin fragment class for the xml layout containing the recycler view
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment_chat_list, container, false)
view.recyclerView?.setHasFixedSize(true)
view.recyclerView?.layoutManager = LinearLayoutManager(context)
ref?.addChildEventListener(object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
val bal = snapshot.getValue<UserInfo.Uids>()
if (bal != null) {
UserInfo.Uids(bal.email,bal.uid,bal.displayName)
}
Log.d("RecyclerView", UserInfo.Uids().toString())
Log.d("RecyclerView", bal.toString())
adapter = BalAdapter(requireContext(), ArrayList<UserInfo.Uids>(), R.layout.users)
adapter!!.notifyDataSetChanged()
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
TODO("Not yet implemented")
}
override fun onChildRemoved(snapshot: DataSnapshot) {
TODO("Not yet implemented")
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
TODO("Not yet implemented")
}
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
adapter = BalAdapter(requireContext(), ArrayList<UserInfo.Uids>(), R.layout.users)
view.recyclerView.adapter = adapter
adapter?.notifyDataSetChanged()
return view
}
R.layout.fragment_chat_list is the xml containing the recycler view tag
R.layout.users is the data xml
view.recyclerView is the recycler view tag
BalAdapter is the adapter class, can be provided on request, but I feel the code there is correct
UserInfo.Uids is the data class, contains name and email
adapter variable was declared before the override fun onCreateView
I am trying to use a spinner inside a fragment but whenever I click on it nothing happens (meaning it doesn't show me anything to select)
private fun prioritySpinner() {
//the array with all the string values
val searchPriority = resources.getStringArray(R.array.PriorityArray)
// Initializing an ArrayAdapter
val adapter = context?.let {
ArrayAdapter(
it, // Context
android.R.layout.simple_spinner_item, // Layout
searchPriority // Array
)
}
// Set the drop down view resource
adapter?.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line)
//searchPriority_ShowBugsFragment_spinner is my spinner
// Finally, data bind the spinner object with adapter
searchPriority_ShowBugsFragment_spinner?.adapter = adapter
// Set an on item selected listener for spinner object
searchPriority_ShowBugsFragment_spinner?.onItemSelectedListener = object: AdapterView.OnItemSelectedListener{
override fun onItemSelected(parent:AdapterView<*>, view: View, position: Int, id: Long){
// Display the selected item text on text view
Toast.makeText(context,"Selected "+ searchPriority[position], Toast.LENGTH_SHORT).show()
}
override fun onNothingSelected(parent: AdapterView<*>){
// Another interface callback
}
}
}
It doesn't change anything if I call the function inside the onCreateView or inside the onCreate
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
prioritySpinner()
return inflater.inflate(R.layout.fragment_show_bugs,container,false)
}
or
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
prioritySpinner()
}