I'm migrating my app to Kotlin and a spinner which was previously working fine (while in Java) stopped working in Kotlin.
This is my CustomShareSpinnerAdapter class:
class CustomShareSpinnerAdapter(
applicationContext: Context?,
private val shareOptions: Array<String>
) : BaseAdapter() {
private val inflter: LayoutInflater
override fun getCount(): Int {
return shareOptions.size
}
override fun getItem(i: Int): Any? {
return null
}
override fun getItemId(i: Int): Long {
return 0
}
@SuppressLint("InflateParams")
override fun getDropDownView(position: Int, _convertView: View?, parent: ViewGroup): View {
var convertView = _convertView
if (convertView == null) {
val vi =
parent.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
convertView = vi.inflate(R.layout.share_spinner_row, null)
}
val llLayout = super.getDropDownView(position, convertView, parent)
if (parent.parent!=null)
roundCorners(parent)
return llLayout
}
private fun roundCorners(parent: ViewGroup) {
val container2Round = parent.parent as View
val gd = GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(Color.WHITE, Color.WHITE)
)
val radius = AWScreen.dp2px(10)
gd.cornerRadius = radius.toFloat()
container2Round.background = gd
}
override fun getView(i: Int, _view: View?, viewGroup: ViewGroup): View {
val view = _view ?:
inflter.inflate(R.layout.share_spinner_row, viewGroup, false)
val tvShare = view.findViewById<TextView>(R.id.share)
tvShare.text = shareOptions[i]
if (shareOptions[i] == "") tvShare.visibility = View.GONE
setListItemRoundedCorners(tvShare, i)
if (i == shareOptions.size - 1) {
val padding = AWScreen.sp2px(10f, view.context)
tvShare.setPadding(padding, padding, padding, padding)
}
return view
}
private fun setListItemRoundedCorners(tvShare: TextView, i: Int) {
if (i == 1) {
tvShare.setBackgroundResource(R.drawable.rounded_border_top)
} else {
if (i == 2) {
tvShare.setBackgroundResource(R.drawable.rounded_border_bottom)
}
}
}
init {
inflter = LayoutInflater.from(applicationContext)
}
}
share_spinner_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/shareLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/share"
android:textSize="20sp"
android:textColor="#000"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
This is where I set ShareSpinner:
private fun setShareSpinner() {
val shareOptions = arrayOf(
"",
getStringResourceByName("displaythoughtactivity_sharespinner_text0"),
getStringResourceByName("displaythoughtactivity_sharespinner_text1"),
getStringResourceByName("displaythoughtactivity_sharespinner_text2")
)
val customAdapter = CustomShareSpinnerAdapter(this, shareOptions)
binding!!.shareSpinner.adapter = customAdapter
binding!!.shareSpinner.onItemSelectedListener = this
}
onItemSelected:
override fun onItemSelected(arg0: AdapterView<*>, arg1: View, position: Int, id: Long) {
val shareSpinnerId = R.id.shareSpinner
val saveSpinnerId = R.id.saveSpinner
when (arg0.id) {
shareSpinnerId -> {
onShareSpinnerItemSelected(position)
binding!!.shareSpinner.setSelection(0)
}
saveSpinnerId -> {
onSaveSpinnerItemSelected(position)
binding!!.saveSpinner.setSelection(0)
}
else -> loadAnimSpinnerItem(position)
}
}
The spinner is just not displaying when you click on the share icon.
No exceptions, no crash, no error on Logcat, it just won't show.
I'm quite sure it'll ended being something stupid, but not being able to figure it out.
Edit 1:
On the other hand, even I'm not an expert on the spinner lifecycle, I don't understand why it's passing through getView twice (and not only once) during spinner set and like 20 times from getDropDownView on icon touch when I have only 4 items in my spinner.
Ok, this is how I made it to work:
getDropDownView:
@SuppressLint("InflateParams")
override fun getDropDownView(position: Int, _convertView: View?, parent: ViewGroup): View? {
val viewHolder = if (_convertView==null) ViewHolder1() else _convertView.tag as ViewHolder1
var view = _convertView
if (view==null){
view = inflater.inflate(R.layout.share_spinner_row, parent, false)
viewHolder.spinnerRow = view.findViewById(R.id.share)
view!!.tag = viewHolder
}
val llLayout = super.getDropDownView(position, _convertView, parent)
if (parent.parent!=null)
roundCorners(parent)
return llLayout
}
getView:
override fun getView(i: Int, _view: View?, viewGroup: ViewGroup): View {
val viewHolder = if (_view==null) ViewHolder1() else _view.tag as ViewHolder1
var view = _view
if (view==null){
view = inflater.inflate(R.layout.share_spinner_row, viewGroup, false)
viewHolder.spinnerRow = view.findViewById(R.id.share)
view!!.tag = viewHolder
}
val tvShare = viewHolder.spinnerRow
tvShare!!.text = shareOptions[i]
if (shareOptions[i] == "") tvShare.visibility = View.GONE else tvShare.visibility = View.VISIBLE
setListItemRoundedCorners(tvShare, i)
if (i == shareOptions.size - 1) {
val padding = AWScreen.sp2px(10f, view.context)
tvShare.setPadding(padding, padding, padding, padding)
}
return view
}
class ViewHolder1:
class ViewHolder1 {
var spinnerRow: TextView? = null
}
Now it shows correctly and with rounded corners as expected.