You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

鸟类观测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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:30:59