鸟类观测App设置功能开发求助:实现单位切换与距离设置
鸟类观测App设置功能完整实现
功能需求
- 支持公制(千米)与英制(英里)单位的互斥切换
- 通过SeekBar设置前往观鸟热点的最大出行距离,实时显示当前数值与对应单位
完整实现代码
import android.content.SharedPreferences import android.os.Bundle import android.widget.SeekBar import android.widget.Switch import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.preference.PreferenceManager class SettingsActivity : AppCompatActivity() { private lateinit var switchMetric: Switch private lateinit var switchImperial: Switch private lateinit var maxDistanceSeekbar: SeekBar private lateinit var maxDistanceTextView: TextView private lateinit var sharedPrefs: SharedPreferences // 偏好设置键名常量 companion object { const val PREF_UNIT_SYSTEM = "unit_system" const val PREF_MAX_DISTANCE = "max_distance" const val UNIT_METRIC = "metric" const val UNIT_IMPERIAL = "imperial" const val DEFAULT_MAX_DISTANCE = 20 const val DEFAULT_UNIT = UNIT_METRIC } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_settings) // 初始化SharedPreferences用于持久化存储设置 sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this) // 绑定UI组件 switchMetric = findViewById(R.id.switch1) switchImperial = findViewById(R.id.switch2) maxDistanceSeekbar = findViewById(R.id.maxDistanceSeekbar) maxDistanceTextView = findViewById(R.id.maxDistanceTextView) // 公制Switch选中逻辑 switchMetric.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { switchImperial.isChecked = false updateUserPreferences(PREF_UNIT_SYSTEM, UNIT_METRIC) updateDistanceDisplay() } } // 英制Switch选中逻辑 switchImperial.setOnCheckedChangeListener { _, isChecked -> if (isChecked) { switchMetric.isChecked = false updateUserPreferences(PREF_UNIT_SYSTEM, UNIT_IMPERIAL) updateDistanceDisplay() } } // 距离SeekBar调节逻辑 maxDistanceSeekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { if (fromUser) { updateUserPreferences(PREF_MAX_DISTANCE, progress) updateDistanceDisplay() } } override fun onStartTrackingTouch(seekBar: SeekBar?) {} override fun onStopTrackingTouch(seekBar: SeekBar?) {} }) // 初始化UI为用户保存的设置 initializeSettings() } // 更新用户偏好设置 private fun updateUserPreferences(key: String, value: Any) { val editor = sharedPrefs.edit() when (value) { is String -> editor.putString(key, value) is Int -> editor.putInt(key, value) } editor.apply() } // 从偏好读取设置并初始化UI private fun initializeSettings() { // 读取单位设置并同步Switch状态 val currentUnit = sharedPrefs.getString(PREF_UNIT_SYSTEM, DEFAULT_UNIT) switchMetric.isChecked = currentUnit == UNIT_METRIC switchImperial.isChecked = currentUnit == UNIT_IMPERIAL // 读取距离设置并同步SeekBar进度 val currentDistance = sharedPrefs.getInt(PREF_MAX_DISTANCE, DEFAULT_MAX_DISTANCE) maxDistanceSeekbar.progress = currentDistance // 初始化距离文本显示 updateDistanceDisplay() } // 根据当前单位更新距离文本的显示内容 private fun updateDistanceDisplay() { val currentDistance = maxDistanceSeekbar.progress val currentUnit = sharedPrefs.getString(PREF_UNIT_SYSTEM, DEFAULT_UNIT) val unitText = if (currentUnit == UNIT_METRIC) "km" else "miles" maxDistanceTextView.text = "$currentDistance $unitText" } }
关键逻辑说明
- 单位互斥处理:两个Switch的监听事件中,选中其中一个时自动取消另一个的选中状态,确保单位选择唯一
- 偏好持久化:使用
SharedPreferences存储用户设置,确保App重启后设置不会丢失 - 实时显示同步:切换单位或调节SeekBar时,调用
updateDistanceDisplay()方法同步更新距离文本的单位与数值 - 默认值设置:定义了默认单位为公里、默认最大距离为20,避免首次打开时出现空值或异常
内容的提问来源于stack exchange,提问作者nsovo
相关产品推荐
相关产品推荐

