Search code examples
javaandroidkotlinspinnerandroid-spinner

How to create a spinner with different colors in each row


I would like to create a sppiner with different colors in each row, I know that there are many explanations similar to my question but they are all in Java and it has been complicated for me, I carry out the steps.

My code

val lista = listOf<Mood>(
    Mood(resources.getColor(R.color.blue, null), "Color1"),
    Mood(resources.getColor(R.color.purple, null), "Color2"),
    Mood(resources.getColor(R.color.green, null), "Color3"),
    Mood(resources.getColor(R.color.darkred, null), "Color4")
)

val adaptador = MoodArrayAdapter(this, lista)
spinner1.adapter = adaptador

spinner1.onItemSelectedListener = object :
    AdapterView.OnItemSelectedListener {
    override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
        when (spinner1.selectedItem.toString()) {
            "Color1" -> textView.setBackgroundResource(R.color.blue)
            "Color2" -> textView.setBackgroundResource(R.color.purple)
            "Color3" -> textView.setBackgroundResource(R.color.green)
            "Color4" -> textView.setBackgroundResource(R.color.darkred)
        }
    }
    override fun onNothingSelected(p0: AdapterView<*>?) {
        TODO("Not yet implemented")
    }
}

I want to create my spinner in this way

enter image description here


Solution

  • You've not shared the complete code though, but here's what you actually have to do.

    1. Change the data model as :

      data class Mood(val backgroundColor: Color, 
          val description: String)
      
    2. Change the item layout as (You don't need the ImageView though, you don't even need the ConstraintLayout though for a single TextView layout, but I'm keeping it for now) :

      <android.support.constraint.ConstraintLayout
          android:id="@+id/rootLayout"
          ...>
          <TextView
              android:id="@+id/moodText"
              android:layout_width="wrap_content"
              android:layout_height="20dp"
              app:layout_constraintTop_toTopOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintBottom_toBottomOf="parent"
              android:layout_marginStart="8dp"
              android:layout_marginEnd="8dp"/>
      </android.support.constraint.ConstraintLayout>
      
    3. Change the Adapter class as :

      class MoodArrayAdapter(ctx: Context,
          moods: List<Mood>) :
          ArrayAdapter<Mood>(ctx, 0, moods) {
          override fun getView(position: Int, recycledView: View?, parent: ViewGroup): View {
              return this.createView(position, recycledView, parent)
          }
          override fun getDropDownView(position: Int, recycledView: View?, parent: ViewGroup): View {
              return this.createView(position, recycledView, parent)
          }
          private fun createView(position: Int, recycledView: View?, parent: ViewGroup): View {
              val mood = getItem(position)
              val view = recycledView ?: LayoutInflater.from(context).inflate(
                  R.layout.demo_spinner,
                  parent,
                  false
              )
              view.rootLayout.setBackgroundColor(mood.backgroundColor)
              view.moodText.text = mood.description
              return view
          }
      }
      
    4. Finally, set the adapter to the spinner as :

      moodSpinner.adapter = MoodArrayAdapter(
          this,
          listOf(
              Mood(Color.RED, "Angry"),
              Mood(Color.GRAY, "Happy"),
              Mood(Color.CYAN, "Playful"),
              Mood(Color.GREEN, "Wondering")
          )
      )
      

    Now, you can change the variables/names where word "mood" is written as it suits you. Furthermore, I'm passing colors, you can use Color.ValueOf(r,g,b) for custom colors or you can change the DataType of backgroundColor in the data model to int and pass color resources from colors.xml.

    Edit -> To access a color resource for this, pass it as :

    From Activity -> Mood(resources.getColor(R.color.blue,null), "Angry")
    From Fragment -> Mood(context.resources.getColor(R.color.blue,null), "Angry")
    

    So, change your code accordingly as :

    moodSpinner.adapter = MoodArrayAdapter(
        this,
        listOf(
        Mood(resources.getColor(R.color.blue,null), "Angry"),
        Mood(resources.getColor(R.color.red,null), "Happy"),
        Mood(Color.CYAN, "Playful"),
        Mood(Color.GREEN, "Wondering")
        )
    )