Home > front end >  Kotlin: Spinner won't show
Kotlin: Spinner won't show

Time:06-21

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.

CodePudding user response:

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.

  • Related