适配中英文切换
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
package com.example.defenseapplication
|
||||
|
||||
import android.app.Application
|
||||
import com.blankj.utilcode.util.Utils;
|
||||
class MyApplication : Application(){
|
||||
import android.content.Context
|
||||
import com.blankj.utilcode.util.Utils
|
||||
import com.example.defenseapplication.utils.LanguageUtil
|
||||
|
||||
class MyApplication : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Utils.init(this) // 初始化 AndroidUtilCode
|
||||
}
|
||||
}
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
// 在应用启动时应用语言设置
|
||||
val context = LanguageUtil.attachBaseContext(base)
|
||||
super.attachBaseContext(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.example.defenseapplication.base
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.example.defenseapplication.utils.LanguageUtil
|
||||
|
||||
/**
|
||||
* 支持语言切换的 Activity 基类
|
||||
* 所有需要支持多语言的 Activity 都应该继承此类
|
||||
*/
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
|
||||
override fun attachBaseContext(newBase: Context) {
|
||||
// 在 Activity 创建前应用语言设置
|
||||
val context = LanguageUtil.attachBaseContext(newBase)
|
||||
super.attachBaseContext(context)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// 确保语言设置被应用
|
||||
LanguageUtil.updateResources(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换语言
|
||||
* 调用后会重新创建 Activity 以应用新语言
|
||||
*/
|
||||
protected fun switchLanguage(language: String) {
|
||||
val currentLang = LanguageUtil.getCurrentLanguage(this)
|
||||
if (currentLang != language) {
|
||||
LanguageUtil.switchLanguage(this, language)
|
||||
// 重新创建 Activity 以应用新语言
|
||||
recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.adapter.AddDeviceAdapter
|
||||
import com.example.defenseapplication.adapter.Device
|
||||
import com.example.defenseapplication.databinding.AddDeviceActivityBinding
|
||||
@@ -32,8 +33,8 @@ class AddDeviceActivity : AppCompatActivity() {
|
||||
|
||||
private fun setupDeviceList() {
|
||||
val devices = listOf(
|
||||
Device("智能挂式防御机", "device1"),
|
||||
Device("智能防御机", "device2")
|
||||
Device(getString(R.string.smart_hanging_defense), "device1"),
|
||||
Device(getString(R.string.smart_defense_device), "device2")
|
||||
)
|
||||
|
||||
if (devices.isEmpty()) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.example.defenseapplication.home
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
@@ -13,6 +14,7 @@ import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.adapter.DeviceAdapter
|
||||
import com.example.defenseapplication.adapter.DeviceUi
|
||||
import com.example.defenseapplication.adapter.FamilyAdapter
|
||||
@@ -28,24 +30,32 @@ class HomeMenuFragment : Fragment() {
|
||||
private val deviceAdapter by lazy { DeviceAdapter(::onDeviceClicked) }
|
||||
|
||||
private var isFamilyExpanded = false
|
||||
private var currentFamily = "我的家庭"
|
||||
private lateinit var currentFamily: String
|
||||
|
||||
private val familyList = listOf("我的家庭", "工作室", "父母家")
|
||||
private val familyDeviceMap = mapOf(
|
||||
"我的家庭" to listOf(
|
||||
DeviceUi("智能挂式防御机", true),
|
||||
DeviceUi("智能防御机", false),
|
||||
DeviceUi("智能轨道防御机", false)
|
||||
),
|
||||
"工作室" to listOf(
|
||||
DeviceUi("走廊防御机", true),
|
||||
DeviceUi("门禁防御机", true)
|
||||
),
|
||||
"父母家" to listOf(
|
||||
DeviceUi("客厅防御机", false),
|
||||
DeviceUi("阳台防御机", true)
|
||||
private val familyList: List<String> by lazy {
|
||||
listOf(
|
||||
getString(R.string.my_family_home),
|
||||
getString(R.string.workshop),
|
||||
getString(R.string.parents_home)
|
||||
)
|
||||
)
|
||||
}
|
||||
private val familyDeviceMap: Map<String, List<DeviceUi>> by lazy {
|
||||
mapOf(
|
||||
getString(R.string.my_family_home) to listOf(
|
||||
DeviceUi(getString(R.string.smart_hanging_defense), true),
|
||||
DeviceUi(getString(R.string.smart_defense_device), false),
|
||||
DeviceUi(getString(R.string.smart_rail_defense), false)
|
||||
),
|
||||
getString(R.string.workshop) to listOf(
|
||||
DeviceUi(getString(R.string.corridor_defense), true),
|
||||
DeviceUi(getString(R.string.door_defense), true)
|
||||
),
|
||||
getString(R.string.parents_home) to listOf(
|
||||
DeviceUi(getString(R.string.living_room_defense), false),
|
||||
DeviceUi(getString(R.string.balcony_defense), true)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -81,6 +91,7 @@ class HomeMenuFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
currentFamily = familyList.first()
|
||||
binding.rvFamilyList.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.rvFamilyList.adapter = familyAdapter
|
||||
familyAdapter.submitList(familyList, currentFamily)
|
||||
@@ -133,7 +144,7 @@ class HomeMenuFragment : Fragment() {
|
||||
private fun onDeviceClicked(device: DeviceUi) {
|
||||
if (device.isOnline) return
|
||||
showDefenseDialog(
|
||||
config = DefenseDialogs.deviceOfflineConfig()
|
||||
config = DefenseDialogs.deviceOfflineConfig(requireContext())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import com.bumptech.glide.Glide
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.databinding.PersonalFragmentBinding
|
||||
import com.example.defenseapplication.personal.PersonalProfileActivity
|
||||
import com.example.defenseapplication.utils.LanguageUtil
|
||||
import com.example.defenseapplication.view.LanguageDialog
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
|
||||
class PersonalFragment : Fragment() {
|
||||
@@ -37,9 +39,36 @@ class PersonalFragment : Fragment() {
|
||||
val intent= Intent(requireContext(), PersonalProfileActivity::class.java)
|
||||
startActivity(intent)
|
||||
}
|
||||
// 更新当前语言显示
|
||||
updateCurrentLanguageDisplay()
|
||||
// 语言设置点击事件
|
||||
binding.itemLanguage.setOnClickListener {
|
||||
showLanguageDialog()
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新当前语言显示
|
||||
*/
|
||||
private fun updateCurrentLanguageDisplay() {
|
||||
val currentLang = LanguageUtil.getCurrentLanguage(requireContext())
|
||||
binding.tvCurrentLanguage.text = LanguageUtil.getLanguageDisplayName(currentLang)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示语言选择对话框
|
||||
*/
|
||||
private fun showLanguageDialog() {
|
||||
val dialog = LanguageDialog(requireContext()) { language ->
|
||||
LanguageUtil.switchLanguage(requireContext(), language)
|
||||
// 刷新当前页面以应用新语言
|
||||
requireActivity().recreate()
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null // 避免内存泄漏
|
||||
|
||||
@@ -56,7 +56,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
if (isGranted) {
|
||||
startRecordingMode()
|
||||
} else {
|
||||
Toast.makeText(this, "需要录音权限才能使用控制功能", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.recording_permission_needed, Toast.LENGTH_SHORT).show()
|
||||
isRecording = false
|
||||
}
|
||||
}
|
||||
@@ -108,29 +108,29 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
mp.isLooping = true
|
||||
mp.start()
|
||||
this@LiveVideoActivity.isPlaying = true
|
||||
Toast.makeText(this@LiveVideoActivity, "视频准备完成", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LiveVideoActivity, R.string.video_ready, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
setOnCompletionListener {
|
||||
this@LiveVideoActivity.isPlaying = false
|
||||
Toast.makeText(this@LiveVideoActivity, "播放完成", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LiveVideoActivity, R.string.playback_complete, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
setOnErrorListener { _, what, extra ->
|
||||
Toast.makeText(this@LiveVideoActivity, "播放错误: $what, $extra", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LiveVideoActivity, getString(R.string.video_error_format, what, extra), Toast.LENGTH_SHORT).show()
|
||||
releaseMediaPlayer()
|
||||
true
|
||||
}
|
||||
|
||||
setOnBufferingUpdateListener { _, percent ->
|
||||
if (percent < 100) {
|
||||
Toast.makeText(this@LiveVideoActivity, "缓冲中: $percent%", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LiveVideoActivity, getString(R.string.buffering_format, percent), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this@LiveVideoActivity, "无法加载视频", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LiveVideoActivity, R.string.cannot_load_video, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
binding.llAlarmLog.setOnClickListener {
|
||||
Toast.makeText(this, "查看告警日志", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.view_alarm_log, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
// 点击xq箭头跳转到AlarmLogActivity
|
||||
@@ -207,11 +207,11 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
if (mp.isPlaying) {
|
||||
mp.pause()
|
||||
isPlaying = false
|
||||
Toast.makeText(this, "已暂停", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.paused, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
mp.start()
|
||||
isPlaying = true
|
||||
Toast.makeText(this, "继续播放", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.resume_playback, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
|
||||
binding.ivFullscreen.setImageResource(com.example.defenseapplication.R.drawable.back)
|
||||
|
||||
Toast.makeText(this, "已进入全屏", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.entered_fullscreen, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun exitFullscreen() {
|
||||
@@ -274,7 +274,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
|
||||
binding.ivFullscreen.setImageResource(com.example.defenseapplication.R.drawable.full_screen)
|
||||
|
||||
Toast.makeText(this, "已退出全屏", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.exited_fullscreen, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun toggleVoice() {
|
||||
@@ -283,11 +283,11 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
if (isVoiceEnabled) {
|
||||
mediaPlayer?.setVolume(1.0f, 1.0f)
|
||||
binding.ivVoice.setImageResource(com.example.defenseapplication.R.drawable.voice_on_open)
|
||||
Toast.makeText(this, "声音已开启", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.sound_on, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
mediaPlayer?.setVolume(0.0f, 0.0f)
|
||||
binding.ivVoice.setImageResource(com.example.defenseapplication.R.drawable.voice)
|
||||
Toast.makeText(this, "声音已关闭", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.sound_off, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,10 +296,10 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
|
||||
if (isLightOn) {
|
||||
binding.ivLight.setImageResource(com.example.defenseapplication.R.drawable.light_on_open)
|
||||
Toast.makeText(this, "灯光已开启", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.light_on, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
binding.ivLight.setImageResource(com.example.defenseapplication.R.drawable.light_on)
|
||||
Toast.makeText(this, "灯光已关闭", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.light_off, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
// 启动麦克风脉冲动画
|
||||
//startMicPulseAnimation()
|
||||
|
||||
Toast.makeText(this, "开始控制模式", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.start_control_mode, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
private fun stopRecordingMode() {
|
||||
@@ -365,7 +365,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
// 停止麦克风脉冲动画
|
||||
stopMicPulseAnimation()
|
||||
|
||||
Toast.makeText(this, "停止控制模式", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.stop_control_mode, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
// private fun startMicPulseAnimation() {
|
||||
@@ -408,7 +408,7 @@ class LiveVideoActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
start()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this@LiveVideoActivity, "录音启动失败", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@LiveVideoActivity, R.string.recording_start_failed, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package com.example.defenseapplication.liveVideo
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.base.BaseActivity
|
||||
import com.example.defenseapplication.databinding.SettingsActivityBinding
|
||||
import com.example.defenseapplication.utils.LanguageUtil
|
||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
||||
import com.example.defenseapplication.view.LanguageDialog
|
||||
import com.example.defenseapplication.view.RecognitionModeDialog
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
|
||||
class SettingsActivity : AppCompatActivity() {
|
||||
class SettingsActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: SettingsActivityBinding
|
||||
|
||||
@@ -34,8 +37,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||
|
||||
binding.itemDeviceName.setOnClickListener {
|
||||
val dialog = CustomDialogFragmentText()
|
||||
.setTitle("设备名称")
|
||||
.setInputHint("请输入设备名称")
|
||||
.setTitle(getString(R.string.device_name))
|
||||
.setInputText(binding.tvDeviceName.text.toString())
|
||||
dialog.setOnConfirmListener { name ->
|
||||
binding.tvDeviceName.text = name
|
||||
@@ -45,15 +47,18 @@ class SettingsActivity : AppCompatActivity() {
|
||||
|
||||
binding.itemUnbindDevice.setOnClickListener {
|
||||
val dialog = CustomDialogFragmentText()
|
||||
.setTitle("提示")
|
||||
.setMessage("确定解除该设备的绑定?")
|
||||
.setNegativeText("取消")
|
||||
.setPositiveText("确定")
|
||||
.setTitle(getString(R.string.tip))
|
||||
.setMessage(getString(R.string.logout_confirm))
|
||||
.setNegativeText(getString(R.string.cancel))
|
||||
.setPositiveText(getString(R.string.confirm))
|
||||
.setShowInput(false)
|
||||
dialog.setOnConfirmListener {
|
||||
finish()
|
||||
}
|
||||
dialog.show(supportFragmentManager, "CustomDialogFragment")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class FaceLoginActivity : AppCompatActivity() {
|
||||
binding.btnStartVerification.setOnClickListener {
|
||||
val intent= Intent(this, FaceVerificationActivity::class.java)
|
||||
startActivity(intent)
|
||||
Toast.makeText(this, "跳转到人脸识别页面", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.redirect_face_recognition_page, Toast.LENGTH_SHORT).show()
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -114,24 +114,24 @@ class LoginActivity : AppCompatActivity() {
|
||||
binding.loginBtn.setOnClickListener {
|
||||
val phone = binding.etPhone.text.toString()
|
||||
if (phone.isEmpty()) {
|
||||
Toast.makeText(this, "请输入手机号", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.enter_phone_number, Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
when (currentLoginMode) {
|
||||
LoginMode.SMS -> {
|
||||
val code = binding.etSmsCode.text.toString()
|
||||
if (code.isEmpty()) {
|
||||
Toast.makeText(this, "请输入验证码", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.enter_verification_code_pls, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "验证码登录成功\n手机号:$phone\n验证码:$code", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, getString(R.string.sms_login_success, phone, code), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
LoginMode.PASSWORD -> {
|
||||
val pwd = binding.etPassword.text.toString()
|
||||
if (pwd.isEmpty()) {
|
||||
Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.password_hint, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "密码登录成功\n手机号:$phone\n密码:$pwd", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, getString(R.string.password_login_success, phone, pwd), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,23 +140,23 @@ class LoginActivity : AppCompatActivity() {
|
||||
binding.sendCodeBtn.setOnClickListener {
|
||||
val phone = binding.etPhone.text.toString()
|
||||
if (phone.isEmpty()) {
|
||||
Toast.makeText(this, "请先输入手机号", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.phone_hint, Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
Toast.makeText(this, "验证码已发送至 $phone", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, getString(R.string.code_sent_to, phone), Toast.LENGTH_SHORT).show()
|
||||
startCountDown()
|
||||
}
|
||||
|
||||
binding.registerText.setOnClickListener {
|
||||
val intent= Intent(this, RegisterActivity::class.java)
|
||||
startActivity(intent)
|
||||
Toast.makeText(this, "跳转到注册页面", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.redirect_register_page, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
binding.forgetText.setOnClickListener {
|
||||
val intent= Intent(this, ForgetPasswordActivity::class.java)
|
||||
startActivity(intent)
|
||||
Toast.makeText(this, "找回密码", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.forgot_password_page, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,10 +164,10 @@ class LoginActivity : AppCompatActivity() {
|
||||
binding.sendCodeBtn.isEnabled = false
|
||||
object : CountDownTimer(60000, 1000) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
binding.sendCodeBtn.text = "${millisUntilFinished / 1000}秒后重试"
|
||||
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
|
||||
}
|
||||
override fun onFinish() {
|
||||
binding.sendCodeBtn.text = "发送验证码"
|
||||
binding.sendCodeBtn.text = getString(R.string.send_code)
|
||||
binding.sendCodeBtn.isEnabled = true
|
||||
}
|
||||
}.start()
|
||||
|
||||
@@ -39,7 +39,7 @@ class PersonalProfileActivity : AppCompatActivity() {
|
||||
.circleCrop()
|
||||
.into(binding.ivAvatar)
|
||||
|
||||
binding.tvNickname.text = "这里是我的昵称"
|
||||
binding.tvNickname.text = getString(R.string.nickname_default)
|
||||
binding.tvPhone.text = "13589898989"
|
||||
|
||||
// 点击行可跳转到“修改昵称/修改手机号”等页面
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.example.defenseapplication.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import android.os.LocaleList
|
||||
import java.util.Locale
|
||||
|
||||
object LanguageUtil {
|
||||
|
||||
private const val PREF_NAME = "language_pref"
|
||||
private const val KEY_LANGUAGE = "selected_language"
|
||||
|
||||
const val LANGUAGE_CHINESE = "zh"
|
||||
const val LANGUAGE_ENGLISH = "en"
|
||||
|
||||
/**
|
||||
* 切换语言
|
||||
* @param context 上下文
|
||||
* @param language 语言代码: "zh" 中文, "en" 英文
|
||||
*/
|
||||
fun switchLanguage(context: Context, language: String) {
|
||||
saveLanguage(context, language)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前设置的语言
|
||||
*/
|
||||
fun getCurrentLanguage(context: Context): String {
|
||||
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
return prefs.getString(KEY_LANGUAGE, LANGUAGE_CHINESE) ?: LANGUAGE_CHINESE
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存语言设置
|
||||
*/
|
||||
private fun saveLanguage(context: Context, language: String) {
|
||||
val prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||
prefs.edit().putString(KEY_LANGUAGE, language).apply()
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前是否是中文
|
||||
*/
|
||||
fun isChinese(context: Context): Boolean {
|
||||
return getCurrentLanguage(context) == LANGUAGE_CHINESE
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地化的 Context(用于在应用内切换语言)
|
||||
* 在 attachBaseContext 中调用
|
||||
*/
|
||||
fun attachBaseContext(context: Context): Context {
|
||||
val language = getCurrentLanguage(context)
|
||||
return createLocalizedContext(context, language)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建本地化的 Context
|
||||
*/
|
||||
private fun createLocalizedContext(context: Context, language: String): Context {
|
||||
val locale = Locale(language)
|
||||
Locale.setDefault(locale)
|
||||
|
||||
val resources = context.resources
|
||||
val configuration = resources.configuration
|
||||
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// Android 7.0 及以上
|
||||
val localeList = LocaleList(locale)
|
||||
configuration.setLocales(localeList)
|
||||
context.createConfigurationContext(configuration)
|
||||
} else {
|
||||
// Android 7.0 以下
|
||||
configuration.locale = locale
|
||||
resources.updateConfiguration(configuration, resources.displayMetrics)
|
||||
context
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新应用语言(用于在 Activity 中动态切换)
|
||||
*/
|
||||
fun updateResources(context: Context): Context {
|
||||
val language = getCurrentLanguage(context)
|
||||
val locale = Locale(language)
|
||||
Locale.setDefault(locale)
|
||||
|
||||
val resources = context.resources
|
||||
val configuration = resources.configuration
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val localeList = LocaleList(locale)
|
||||
configuration.setLocales(localeList)
|
||||
} else {
|
||||
configuration.locale = locale
|
||||
}
|
||||
|
||||
resources.updateConfiguration(configuration, resources.displayMetrics)
|
||||
return context
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取语言显示名称
|
||||
*/
|
||||
fun getLanguageDisplayName(language: String): String {
|
||||
return when (language) {
|
||||
LANGUAGE_CHINESE -> "中文"
|
||||
LANGUAGE_ENGLISH -> "English"
|
||||
else -> "中文"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ class CustomDialogFragmentText : DialogFragment() {
|
||||
private var message: String = ""
|
||||
private var inputHint: String = ""
|
||||
private var inputText: String = ""
|
||||
private var negativeText: String = "取消"
|
||||
private var positiveText: String = "确定"
|
||||
private var negativeText: String = ""
|
||||
private var positiveText: String = ""
|
||||
private var showInput: Boolean = true
|
||||
private var onConfirmListener: ((String) -> Unit)? = null
|
||||
|
||||
@@ -87,6 +87,9 @@ class CustomDialogFragmentText : DialogFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
// Set defaults if not explicitly configured
|
||||
if (negativeText.isEmpty()) negativeText = getString(R.string.cancel)
|
||||
if (positiveText.isEmpty()) positiveText = getString(R.string.confirm)
|
||||
binding.tvTitle.text = title
|
||||
binding.tvMessage.text = message
|
||||
binding.etInput.hint = inputHint
|
||||
|
||||
@@ -183,41 +183,41 @@ object DefenseDialogs {
|
||||
.also { it.show(fragment.parentFragmentManager, tag) }
|
||||
}
|
||||
|
||||
fun intrusionAlertConfig(deviceName: String, timeText: String): CustomDialogFragment.Config {
|
||||
fun intrusionAlertConfig(ctx: android.content.Context, deviceName: String, timeText: String): CustomDialogFragment.Config {
|
||||
return CustomDialogFragment.Config(
|
||||
title = "入侵告警",
|
||||
message = "${timeText}有人入侵\n【${deviceName}】",
|
||||
positiveText = "去看一下",
|
||||
negativeText = "取消"
|
||||
title = ctx.getString(R.string.intrusion_alarm),
|
||||
message = "${timeText}${ctx.getString(R.string.someone_invaded)}\n【${deviceName}】",
|
||||
positiveText = ctx.getString(R.string.go_check),
|
||||
negativeText = ctx.getString(R.string.cancel)
|
||||
)
|
||||
}
|
||||
|
||||
fun warmPromptConfig(deviceName: String, runDays: Int): CustomDialogFragment.Config {
|
||||
fun warmPromptConfig(ctx: android.content.Context, deviceName: String, runDays: Int): CustomDialogFragment.Config {
|
||||
return CustomDialogFragment.Config(
|
||||
title = "温馨提示",
|
||||
message = "【${deviceName}】设备已经运行\n${runDays}天请及时维护",
|
||||
positiveText = "知道了",
|
||||
title = ctx.getString(R.string.notice),
|
||||
message = "【${deviceName}】${ctx.getString(R.string.device_running_days, runDays)}",
|
||||
positiveText = ctx.getString(R.string.got_it),
|
||||
negativeText = null
|
||||
)
|
||||
}
|
||||
|
||||
fun deviceOfflineConfig(): CustomDialogFragment.Config {
|
||||
fun deviceOfflineConfig(ctx: android.content.Context): CustomDialogFragment.Config {
|
||||
return CustomDialogFragment.Config(
|
||||
title = "设备离线",
|
||||
message = "设备已离线,请检查设备的WIF及电\n源情况",
|
||||
positiveText = "知道了",
|
||||
title = ctx.getString(R.string.device_offline),
|
||||
message = ctx.getString(R.string.device_offline_message),
|
||||
positiveText = ctx.getString(R.string.got_it),
|
||||
negativeText = null
|
||||
)
|
||||
}
|
||||
|
||||
fun strikeDistanceConfig(defaultDistance: String): CustomDialogFragment.Config {
|
||||
fun strikeDistanceConfig(ctx: android.content.Context, defaultDistance: String): CustomDialogFragment.Config {
|
||||
return CustomDialogFragment.Config(
|
||||
title = "打击距离",
|
||||
title = ctx.getString(R.string.strike_distance),
|
||||
message = "",
|
||||
positiveText = "确定",
|
||||
negativeText = "取消",
|
||||
positiveText = ctx.getString(R.string.confirm),
|
||||
negativeText = ctx.getString(R.string.cancel),
|
||||
showInput = true,
|
||||
inputHint = "请输入打击距离",
|
||||
inputHint = ctx.getString(R.string.enter_strike_distance),
|
||||
inputText = defaultDistance,
|
||||
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
|
||||
)
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.example.defenseapplication.view
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Window
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.utils.LanguageUtil
|
||||
|
||||
/**
|
||||
* 语言选择对话框
|
||||
*/
|
||||
class LanguageDialog(
|
||||
context: Context,
|
||||
private val onLanguageSelected: (String) -> Unit
|
||||
) : Dialog(context) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
setContentView(R.layout.dialog_language)
|
||||
|
||||
// 设置对话框宽度为屏幕宽度的80%
|
||||
window?.setLayout(
|
||||
(context.resources.displayMetrics.widthPixels * 0.8).toInt(),
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
|
||||
initViews()
|
||||
}
|
||||
|
||||
private fun initViews() {
|
||||
val tvChinese = findViewById<TextView>(R.id.tvChinese)
|
||||
val tvEnglish = findViewById<TextView>(R.id.tvEnglish)
|
||||
val tvCancel = findViewById<TextView>(R.id.tvCancel)
|
||||
|
||||
val currentLang = LanguageUtil.getCurrentLanguage(context)
|
||||
|
||||
// 根据当前语言高亮显示
|
||||
if (currentLang == LanguageUtil.LANGUAGE_CHINESE) {
|
||||
tvChinese.setTextColor(context.getColor(R.color.green))
|
||||
} else {
|
||||
tvEnglish.setTextColor(context.getColor(R.color.green))
|
||||
}
|
||||
|
||||
tvChinese.setOnClickListener {
|
||||
onLanguageSelected(LanguageUtil.LANGUAGE_CHINESE)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
tvEnglish.setOnClickListener {
|
||||
onLanguageSelected(LanguageUtil.LANGUAGE_ENGLISH)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
tvCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,12 +39,12 @@ class RecognitionModeDialog(context: Context) : Dialog(context) {
|
||||
}
|
||||
|
||||
binding.itemBluetooth.setOnClickListener {
|
||||
selectedMode = "蓝牙识别"
|
||||
selectedMode = context.getString(R.string.bluetooth_recognition)
|
||||
updateSelectedBackground(binding.itemBluetooth)
|
||||
}
|
||||
|
||||
binding.itemBluetoothFace.setOnClickListener {
|
||||
selectedMode = "蓝牙+人脸识别"
|
||||
selectedMode = context.getString(R.string.bluetooth_face_recognition)
|
||||
updateSelectedBackground(binding.itemBluetoothFace)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user