Home > Mobile >  Save color of a button in shared preferences (kotlin)
Save color of a button in shared preferences (kotlin)

Time:11-15

I like to save the color of a button in shared preferences.

<Button
    android:id="@ id/farbe1"
    android:layout_width="20dp"
    android:layout_height="60dp"
    android:layout_marginTop="10dp"
    android:backgroundTint="@color/teal_700"
    app:layout_constraintStart_toEndOf="@ id/FachMontag1"
    app:layout_constraintTop_toTopOf="@ id/view5" />

The button has the ability that it changes its color whenever it is pressed.

 override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_montag)
 
    val pref = getPreferences(Context.MODE_PRIVATE)

    val Fach1 = pref.getString("FACHMONTAG1", "")
    val Fach2 = pref.getString("FACHMONTAG2", "")
    val Fach3 = pref.getString("FACHMONTAG3", "")
    val Fach4 = pref.getString("FACHMONTAG4", "")
    val Fach5 = pref.getString("FACHMONTAG5", "")
    val Fach6 = pref.getString("FACHMONTAG6", "")

    val FachMontag1 = findViewById<EditText>(R.id.FachMontag1)
    FachMontag1.setText(Fach1)
    val FachMontag2 = findViewById<EditText>(R.id.FachMontag2)
    FachMontag2.setText(Fach2)
    val FachMontag3 = findViewById<EditText>(R.id.FachMontag3)
    FachMontag3.setText(Fach3)
    val FachMontag4 = findViewById<EditText>(R.id.FachMontag4)
    FachMontag4.setText(Fach4)
    val FachMontag5 = findViewById<EditText>(R.id.FachMontag5)
    FachMontag5.setText(Fach5)
    val FachMontag6 = findViewById<EditText>(R.id.FachMontag6)
    FachMontag6.setText(Fach6)


    val Farbe1 = findViewById<Button>(R.id.farbe1)
    Farbe1.setOnClickListener {
        val Farbe1 = findViewById<Button>(R.id.farbe1)

        number_of_clicks  
        if (number_of_clicks == 1) {
            Farbe1.setBackgroundColor(getColor(R.color.white))
            number_of_clicks   1
        } else if (number_of_clicks == 2) {
            Farbe1.setBackgroundColor(getColor(R.color.yellow))
            number_of_clicks   1
        } else if (number_of_clicks == 3) {
            Farbe1.setBackgroundColor(getColor(R.color.green))
            number_of_clicks   1
        } else if (number_of_clicks == 4) {
            Farbe1.setBackgroundColor(getColor(R.color.red))
            number_of_clicks   1
        } else if (number_of_clicks == 5) {
            Farbe1.setBackgroundColor(getColor(R.color.blue))
            number_of_clicks   1
        } else if (number_of_clicks == 6) {
            Farbe1.setBackgroundColor(getColor(R.color.purple))
            number_of_clicks   1
        } else if (number_of_clicks == 7) {
            Farbe1.setBackgroundColor(getColor(R.color.teal_700))
            number_of_clicks = 0
        }
    }
}

I have a button that saves also some other stuff from my app (edit text).

 fun onSave(view: android.view.View) {


        val pref = getPreferences(Context.MODE_PRIVATE)
        val editor = pref.edit()

        val FachMontag1 = findViewById<EditText>(R.id.FachMontag1)
        editor.putString("FACHMONTAG1", FachMontag1.text.toString())
        val FachMontag2 = findViewById<EditText>(R.id.FachMontag2)
        editor.putString("FACHMONTAG2", FachMontag2.text.toString())
        val FachMontag3 = findViewById<EditText>(R.id.FachMontag3)
        editor.putString("FACHMONTAG3", FachMontag3.text.toString())
        val FachMontag4 = findViewById<EditText>(R.id.FachMontag4)
        editor.putString("FACHMONTAG4", FachMontag4.text.toString())
        val FachMontag5 = findViewById<EditText>(R.id.FachMontag5)
        editor.putString("FACHMONTAG5", FachMontag5.text.toString())
        val FachMontag6 = findViewById<EditText>(R.id.FachMontag5)
        editor.putString("FACHMONTAG6", FachMontag6.text.toString())
 
   editor.commit()
}

I would like to save the color of the button like i do with the edit text but could not quite figure out how to adjust the code for the color.

CodePudding user response:

You'll want to retrieve the color as an Int value so you can store it. You can't reliably store the resource ID Int, because there's no guarantee the value will be interpretted the same way the next time the app is compiled.

Also, I would use a list of colors to simplify your code.

val Farbe1 = findViewById<Button>(R.id.farbe1)
val colors = listOf(
    R.color.white,
    R.color.yellow,
    R.color.green,
    //etc.
).map(::getColor)
Farbe1.setBackgroundColor(pref.getInt(“FARBE1”, colors[0])
Farbe1.setOnClickListener { view ->
    number_of_clicks  
    setBackgroundColor(colors[number_of_clicks % colors.length])
}

//...

val Farbe1 = findViewById<Button>(R.id.farbe1)
editor.putInt("FARBE1", (Farbe1.getBackgroundDrawable() as ColorDrawable).getColor())

However, storing the actual color won’t be able to make it resume from the same place in the color list. You might just want to store the index from the colors list. For example:

editor.putInt("FARBE1", number_of_clicks)

And I suggest you use view binding so you don't have to use findViewById all over the place.

CodePudding user response:

Not really an answer to the question, but just as a tip - if you make a map associating FACHMONTAG keys with R.id.FachMontag IDs, you can make some little functions that handle the whole "pull the data with this key and set it on this view`` thing. And because it's in a map, you can just iterate over all the entries to save or load the data

val keysToIds = mapOf {
    "FACHMONTAG1" to R.id.FachMontag1,
    "FACHMONTAG2" to R.id.FachMontag2,
    "FACHMONTAG3" to R.id.FachMontag3,
    "FACHMONTAG4" to R.id.FachMontag4,
    "FACHMONTAG5" to R.id.FachMontag5,
    "FACHMONTAG1" to R.id.FachMontag6
}

fun loadEditTextData(prefs: SharedPreferences) {
    keysToIds.forEach { key, id ->
        val data = prefs.getString(key, "")
        findViewById<EditText>(id).setText(data)
    }
}

fun saveEditTextData(prefs: SharedPreferences) {
    keysToIds.forEach { key, id ->
        val data = findViewById<EditText>(id).text.toString()
        prefs.putString(key, data)
    }
}

and that way you can load or save to prefs just by passing an instance in.

You could also lookup all those views once (or use view binding) and generate a key -> EditText map (so you don't keep running findViewById) but it's up to you if it's worth it - I'm guessing this doesn't fire that often

  • Related