I'm trying to program an android app with android studio that counts steps taken by the user. I'm trying to make a settings/options activity where the user can both set their height and preferred measure unit. I was able to code the height selection so that it is saved into SharedPreferences so that every time the user returns to the settings activity the height stays the same.
I'm trying to do the same to the measure unit selection but it doesn't seem to work. I've put the measure unit selection into RadioButtons that are both in the same RadioGroup and I've managed to do so that the selected RadioButtonId is shown below. That way I was able to confirm that the code knows when I'm selecting a different button. But for some reason it doesn't save the selected Id or load it when returning to the settings activity.
I'm very new into all of this and I feel I've tried to search the solution everywhere before this. Hopefully you can help me to get past this!
Here is the settings xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AsetuksetActivity">
<TextView
android:id="@ id/tv_asetukset"
android:layout_width="150dp"
android:layout_height="50dp"
android:fontFamily="@font/morrisromanalternate_black"
android:text="Settings"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="40sp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@ id/tv_distanceUnit"
android:layout_width="170dp"
android:layout_height="50dp"
android:layout_marginLeft="90dp"
android:layout_marginTop="50dp"
android:layout_marginRight="200dp"
android:fontFamily="@font/morrisromanalternate_black"
android:text="Measure Unit"
android:textColor="@color/black"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/tv_asetukset" />
<TextView
android:id="@ id/tv_userHeight"
android:layout_width="170dp"
android:layout_height="50dp"
android:layout_marginLeft="90dp"
android:layout_marginTop="20dp"
android:layout_marginRight="200dp"
android:fontFamily="@font/morrisromanalternate_black"
android:text="Your Height"
android:textColor="@color/black"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/tv_distanceUnit" />
<NumberPicker
android:id="@ id/user_height"
android:layout_width="60dp"
android:layout_height="90dp"
android:layout_marginBottom="19dp"
android:theme="@style/number_picker_text"
app:layout_constraintBottom_toTopOf="@ id/tv_ilmoitukset"
app:layout_constraintStart_toEndOf="@ id/tv_userHeight" />
<TextView
android:id="@ id/heightUnitCm"
android:layout_width="60dp"
android:layout_height="50dp"
android:layout_marginStart="4dp"
android:layout_marginBottom="28dp"
android:fontFamily="@font/morrisromanalternate_black"
android:text="cm"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="@ id/tv_ilmoitukset"
app:layout_constraintStart_toEndOf="@ id/user_height" />
<TextView
android:id="@ id/tv_ilmoitukset"
android:layout_width="200dp"
android:layout_height="50dp"
android:fontFamily="@font/morrisromanalternate_black"
android:text="Notifications"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="35sp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/tv_userHeight" />
<TextView
android:id="@ id/test_textHeight"
android:layout_width="280dp"
android:layout_height="50dp"
android:layout_marginTop="40dp"
android:text="Selected number"
android:textAlignment="center"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/tv_ilmoitukset" />
<TextView
android:id="@ id/test_textUnit"
android:layout_width="280dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:text="0"
android:textAlignment="center"
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/test_textHeight" />
<ImageView
android:id="@ id/koti_button"
android:layout_width="90dp"
android:layout_height="90dp"
android:elevation="10dp"
android:src="@drawable/koti"
android:layout_marginBottom="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<RadioGroup
android:id="@ id/radio_group"
android:layout_width="125dp"
android:layout_height="40dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@ id/user_height"
app:layout_constraintStart_toEndOf="@ id/tv_distanceUnit">
<RadioButton
android:id="@ id/radioBtn_km"
android:layout_width="60dp"
android:layout_height="40dp"
android:background="@drawable/background"
android:button="@android:color/transparent"
android:textAlignment="center"
android:fontFamily="@font/morrisromanalternate_black"
android:text="km"
android:textOff="km"
android:textOn="km"
android:textAllCaps="false"
android:textColor="@drawable/button_text_color"
android:textSize="25sp"/>
<RadioButton
android:id="@ id/radioBtn_mi"
android:layout_width="60dp"
android:layout_height="40dp"
android:background="@drawable/background"
android:button="@android:color/transparent"
android:fontFamily="@font/morrisromanalternate_black"
android:text="mi"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@drawable/button_text_color"
android:textOff="mi"
android:textOn="mi"
android:textSize="25sp"
android:layout_marginStart="5dp"/>
</RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
And here is the settings kotlin file:
package com.example.stepstomountdoom
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
class AsetuksetActivity : AppCompatActivity() {
private var cm = 0
private var unit = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_asetukset)
loadHeightData()
loadUnitData()
var button_settings = findViewById<ImageView>(R.id.koti_button)
button_settings.setOnClickListener {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
var test_textUnit = findViewById<TextView>(R.id.test_textUnit)
var radio_group = findViewById<RadioGroup>(R.id.radio_group)
var radioButton_km = findViewById<RadioButton>(R.id.radioBtn_km)
var radioButton_mi = findViewById<RadioButton>(R.id.radioBtn_mi)
radio_group.setOnCheckedChangeListener { radio_group, i ->
if (radioButton_km.isChecked) {
radioButton_km.id = radio_group.checkedRadioButtonId
} else {
radioButton_mi.id = radio_group.checkedRadioButtonId
}
test_textUnit.text = "${radio_group.checkedRadioButtonId}"
unit = radio_group.checkedRadioButtonId
saveUnitData()
}
val test_textHeight = findViewById<TextView>(R.id.test_textHeight)
val user_height = findViewById<NumberPicker>(R.id.user_height)
user_height.minValue = 0
user_height.maxValue = 250
user_height.wrapSelectorWheel = false
user_height.setOnValueChangedListener { numberPicker, oldValue, newValue ->
test_textHeight.text = "Selected number $newValue"
cm = newValue
saveHeightData()
}
}
override fun onResume () {
super.onResume()
val user_height = findViewById<NumberPicker>(R.id.user_height)
val radio_group = findViewById<RadioGroup>(R.id.radio_group)
user_height.value = cm
unit = radio_group.checkedRadioButtonId
}
private fun saveHeightData() {
val sharedPreferences = getSharedPreferences("myPrefs",Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putFloat("key",cm.toFloat())
editor.apply()
}
private fun loadHeightData() {
val sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE)
val savedNumber = sharedPreferences.getFloat("key", 0f)
Log.d("AsetuksetActivity", "$savedNumber")
cm = savedNumber.toInt()
}
private fun saveUnitData() {
val sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putFloat("key2",unit.toFloat())
editor.apply()
}
private fun loadUnitData() {
val sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE)
val savedId = sharedPreferences.getFloat("key2", 0f)
Log.d("AsetuksetActivity","$savedId")
unit = savedId.toInt()
}
}
CodePudding user response:
A number of things you can improve:
class AsetuksetActivity : AppCompatActivity() {
companion object{
/*
*Values to be saved to preference.
*Saving the compiled id of a view is not safe
*as it can vary on different builds
*/
private const val UNIT_KM = "km"
private const val UNIT_MI = "mi"
}
private var cm = 0
private var unit = "" //changed to string
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_asetukset)
...
radio_group.setOnCheckedChangeListener { radio_group, i ->
/*
if (radioButton_km.isChecked) {
radioButton_km.id == radio_group.checkedRadioButtonId
} else {
radioButton_mi.id == radio_group.checkedRadioButtonId
}
test_textUnit.text = "${radio_group.checkedRadioButtonId}"
radio_group.checkedRadioButtonId == unit
*/
/*Note: Don't confuse equality operator ==
with assignment operator =
*/
//should be
when(i){ //you can also use if else
R.id.radioBtn_km -> unit = UNIT_KM
R.id.radioBtn_mi -> unit = UNIT_MI
}
test_textUnit.text = unit
saveUnitData()
}
...
}
override fun onResume () {
super.onResume()
/*Consider using references of the ones declared in onCreate.
*Make same references accessable by class members
*/
val user_height = findViewById<NumberPicker>(R.id.user_height)
val radio_group = findViewById<RadioGroup>(R.id.radio_group)
user_height.value = cm
//unit == radio_group.checkedRadioButtonId
//should be
when (unit){
UNIT_KM -> radio_group.check(R.id.radioBtn_km)
UNIT_MI -> radio_group.check(R.id.radioBtn_mi)
}
}
...
private fun saveUnitData() {
...
//editor.putFloat("key2",unit.toFloat())
//Will save String instead
editor.putString("key2",unit)
editor.apply()
}
private fun loadUnitData() {
val sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE)
/*val savedId = sharedPreferences.getFloat("key2", 0f)
unit = savedId.toInt()
Log.d("AsetuksetActivity","$savedId")*/
unit = sharedPreferences.getString("key2", "")
Log.d("AsetuksetActivity", unit)
}
}
CodePudding user response:
Your radio button listener has things backwards:
radio_group.checkedRadioButtonId == unit
It should be
unit = radio_group.checkedRadioButtonId
so you're storing the current value in unit
, and then saving it. What you were actually doing is comparing unit
to the ID, using ==
.
CodePudding user response:
change
radio_group.checkedRadioButtonId == unit
to
radio_group.checkedRadioButtonId = unit
Besides, you're storing RadioButtonId
unit = radio_group.checkedRadioButtonId
try storing an Int instead of RadioButtonId, i parameter returns an indication for the selected radio button:
radio_group.setOnCheckedChangeListener { radio_group, i ->
...
unit = i
saveUnitData()
}
editor.putInt("key2",unit.toInt())