切换家庭,我的修改名称,手机号
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
package com.example.defenseapplication.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.databinding.ItemSwitchFamilyBinding
|
||||
import com.example.defenseapplication.model.FamilyItem
|
||||
|
||||
class FamilySwitchAdapter(
|
||||
private val familyList: List<FamilyItem>,
|
||||
private val onItemClickListener: (FamilyItem) -> Unit
|
||||
) : RecyclerView.Adapter<FamilySwitchAdapter.FamilyViewHolder>() {
|
||||
|
||||
private var selectedPosition = 0
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FamilyViewHolder {
|
||||
val binding = ItemSwitchFamilyBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
return FamilyViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: FamilyViewHolder, position: Int) {
|
||||
holder.bind(familyList[position], position == selectedPosition)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = familyList.size
|
||||
|
||||
fun selectPosition(position: Int) {
|
||||
val previousPosition = selectedPosition
|
||||
selectedPosition = position
|
||||
notifyItemChanged(previousPosition)
|
||||
notifyItemChanged(selectedPosition)
|
||||
}
|
||||
|
||||
fun getSelectedItem(): FamilyItem = familyList[selectedPosition]
|
||||
|
||||
inner class FamilyViewHolder(
|
||||
private val binding: ItemSwitchFamilyBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(item: FamilyItem, isSelected: Boolean) {
|
||||
binding.tvFamilyName.text = item.name
|
||||
|
||||
binding.root.setBackgroundColor(
|
||||
ContextCompat.getColor(
|
||||
binding.root.context,
|
||||
if (isSelected) R.color.bg_gray else R.color.white
|
||||
)
|
||||
)
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
val position = bindingAdapterPosition
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
selectPosition(position)
|
||||
onItemClickListener(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,11 +21,14 @@ class ConnectDeviceActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ConnectDeviceActivityBinding
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
// 每一帧对应的步骤文字和提示
|
||||
private val steps = listOf(
|
||||
StepData("请保持手机蓝牙开启并将手机尽量靠近设备", "向设备传输信息","设备连接网络"),
|
||||
StepData("请保持手机蓝牙开启并将手机尽量靠近设备", "设备连接网络请将设备尽量靠近路由器",""),
|
||||
StepData("请将设备尽量靠近路由器", "","")
|
||||
)
|
||||
// 用 lazy 延迟初始化
|
||||
private val steps: List<StepData> by lazy {
|
||||
listOf(
|
||||
StepData(getString(R.string.bluetooth_keep_enabled), getString(R.string.transmit_info_to_device), getString(R.string.device_connect_network)),
|
||||
StepData(getString(R.string.bluetooth_keep_enabled), getString(R.string.device_connect_near_router), ""),
|
||||
StepData(getString(R.string.keep_device_near_router), "", "")
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@@ -11,6 +11,7 @@ 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.FamilySwitchDialog
|
||||
import com.example.defenseapplication.view.LanguageDialog
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
|
||||
@@ -43,6 +44,10 @@ class PersonalFragment : Fragment() {
|
||||
binding.itemLanguage.setOnClickListener {
|
||||
showLanguageDialog()
|
||||
}
|
||||
// 切换家庭点击事件
|
||||
binding.itemSwitchFamily.setOnClickListener {
|
||||
showFamilySwitchDialog()
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@@ -67,6 +72,16 @@ class PersonalFragment : Fragment() {
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示家庭切换对话框
|
||||
*/
|
||||
private fun showFamilySwitchDialog() {
|
||||
val dialog = FamilySwitchDialog(requireContext()) { familyName ->
|
||||
binding.tvCurrentFamily.text = familyName
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null // 避免内存泄漏
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.example.defenseapplication.model
|
||||
|
||||
data class FamilyItem(
|
||||
val id: String,
|
||||
val name: String
|
||||
)
|
||||
@@ -5,9 +5,13 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import android.widget.Toast
|
||||
|
||||
import com.bumptech.glide.Glide
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.databinding.PersonalProfileActivityBinding
|
||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
||||
import com.example.defenseapplication.view.PhoneModifyDialogFragment
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
|
||||
class PersonalProfileActivity : AppCompatActivity() {
|
||||
@@ -15,24 +19,19 @@ class PersonalProfileActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
binding = PersonalProfileActivityBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ImmersionBar.with(this)
|
||||
.statusBarDarkFont(true)
|
||||
.titleBar(binding.topBar)
|
||||
.init()
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.ivBack.setOnClickListener { finish() }
|
||||
binding.ivBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
Glide.with(this)
|
||||
.load(R.drawable.img)
|
||||
@@ -42,9 +41,43 @@ class PersonalProfileActivity : AppCompatActivity() {
|
||||
binding.tvNickname.text = getString(R.string.nickname_default)
|
||||
binding.tvPhone.text = "13589898989"
|
||||
|
||||
// 点击行可跳转到“修改昵称/修改手机号”等页面
|
||||
//binding.itemAvatar.setOnClickListener { /* TODO */ }
|
||||
//binding.itemNickname.setOnClickListener { /* TODO */ }
|
||||
//binding.itemPhone.setOnClickListener { /* TODO */ }
|
||||
binding.itemNickname.setOnClickListener {
|
||||
showNicknameDialog()
|
||||
}
|
||||
|
||||
binding.itemPhone.setOnClickListener {
|
||||
showPhoneDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNicknameDialog() {
|
||||
val currentNickname = binding.tvNickname.text.toString()
|
||||
val dialog = CustomDialogFragmentText()
|
||||
.setTitle(getString(R.string.set_name))
|
||||
.setMessage("")
|
||||
.setInputHint(getString(R.string.nickname_hint))
|
||||
.setInputText(currentNickname)
|
||||
.setShowInput(true)
|
||||
.setPositiveText(getString(R.string.confirm))
|
||||
.setNegativeText("")
|
||||
.setOnConfirmListener { newNickname ->
|
||||
if (newNickname.isNotBlank()) {
|
||||
binding.tvNickname.text = newNickname
|
||||
Toast.makeText(this, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
dialog.show(supportFragmentManager, "nickname_dialog")
|
||||
}
|
||||
|
||||
private fun showPhoneDialog() {
|
||||
val dialog = PhoneModifyDialogFragment()
|
||||
.setTitle(getString(R.string.modify_phone))
|
||||
.setNegativeText(getString(R.string.cancel))
|
||||
.setPositiveText(getString(R.string.verify_and_bind))
|
||||
.setOnConfirmListener { phone, code ->
|
||||
binding.tvPhone.text = phone
|
||||
Toast.makeText(this, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
dialog.show(supportFragmentManager, "phone_dialog")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +60,14 @@ class CustomDialogFragmentText : DialogFragment() {
|
||||
return this
|
||||
}
|
||||
|
||||
fun setOnConfirmListener(listener: (String) -> Unit) {
|
||||
fun setOnConfirmListener(listener: (String) -> Unit): CustomDialogFragmentText {
|
||||
this.onConfirmListener = listener
|
||||
return this
|
||||
}
|
||||
|
||||
fun setOnDismissListener(listener: () -> Unit) {
|
||||
fun setOnDismissListener(listener: () -> Unit): CustomDialogFragmentText {
|
||||
this.onDismissListener = listener
|
||||
return this
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.example.defenseapplication.view
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.adapter.FamilySwitchAdapter
|
||||
import com.example.defenseapplication.model.FamilyItem
|
||||
|
||||
/**
|
||||
* 家庭切换对话框
|
||||
*/
|
||||
class FamilySwitchDialog(
|
||||
context: Context,
|
||||
private val onFamilySelected: (String) -> Unit
|
||||
) : Dialog(context, R.style.BottomDialogStyle) {
|
||||
|
||||
private lateinit var adapter: FamilySwitchAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
setContentView(R.layout.dialog_family_switch)
|
||||
|
||||
val window = window
|
||||
val params = window?.attributes
|
||||
params?.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||
params?.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
params?.gravity = Gravity.BOTTOM
|
||||
window?.attributes = params
|
||||
window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||
window?.setDimAmount(0.5f)
|
||||
|
||||
initViews()
|
||||
}
|
||||
|
||||
private fun initViews() {
|
||||
val tvCancel = findViewById<TextView>(R.id.tvCancel)
|
||||
val tvConfirm = findViewById<TextView>(R.id.tvConfirm)
|
||||
val rvMessageList = findViewById<RecyclerView>(R.id.rvMessageList)
|
||||
|
||||
val familyList = listOf(
|
||||
FamilyItem("1", context.getString(R.string.my_family)),
|
||||
FamilyItem("2", context.getString(R.string.zhangsan_family))
|
||||
)
|
||||
|
||||
adapter = FamilySwitchAdapter(familyList) { familyItem ->
|
||||
}
|
||||
|
||||
rvMessageList.layoutManager = LinearLayoutManager(context)
|
||||
rvMessageList.adapter = adapter
|
||||
|
||||
tvCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
tvConfirm.setOnClickListener {
|
||||
val selectedFamily = adapter.getSelectedItem()
|
||||
onFamilySelected(selectedFamily.name)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.example.defenseapplication.view
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.databinding.DialogPhoneModifyBinding
|
||||
|
||||
//手机号弹窗
|
||||
class PhoneModifyDialogFragment : DialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogPhoneModifyBinding
|
||||
private var title: String = ""
|
||||
private var negativeText: String = ""
|
||||
private var positiveText: String = ""
|
||||
private var onConfirmListener: ((String, String) -> Unit)? = null
|
||||
private var onDismissListener: (() -> Unit)? = null
|
||||
private var countDownTimer: CountDownTimer? = null
|
||||
|
||||
fun setTitle(title: String): PhoneModifyDialogFragment {
|
||||
this.title = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun setNegativeText(text: String): PhoneModifyDialogFragment {
|
||||
this.negativeText = text
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPositiveText(text: String): PhoneModifyDialogFragment {
|
||||
this.positiveText = text
|
||||
return this
|
||||
}
|
||||
|
||||
fun setOnConfirmListener(listener: (phone: String, code: String) -> Unit): PhoneModifyDialogFragment {
|
||||
this.onConfirmListener = listener
|
||||
return this
|
||||
}
|
||||
|
||||
fun setOnDismissListener(listener: () -> Unit): PhoneModifyDialogFragment {
|
||||
this.onDismissListener = listener
|
||||
return this
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val dialog = super.onCreateDialog(savedInstanceState)
|
||||
dialog.window?.let {
|
||||
val params = it.attributes
|
||||
params.gravity = Gravity.CENTER
|
||||
params.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||
params.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
it.attributes = params
|
||||
it.setBackgroundDrawableResource(R.drawable.round_bg)
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = DialogPhoneModifyBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
if (negativeText.isEmpty()) negativeText = getString(R.string.cancel)
|
||||
if (positiveText.isEmpty()) positiveText = getString(R.string.confirm)
|
||||
|
||||
binding.tvTitle.text = title
|
||||
binding.btnNegative.text = negativeText
|
||||
binding.btnPositive.text = positiveText
|
||||
|
||||
binding.tvSendCode.setOnClickListener {
|
||||
val phone = binding.etPhone.text.toString()
|
||||
if (phone.length != 11) {
|
||||
ToastUtils.showToast(requireContext(), getString(R.string.invalid_phone))
|
||||
return@setOnClickListener
|
||||
}
|
||||
startCountDown()
|
||||
}
|
||||
|
||||
binding.btnNegative.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.btnPositive.setOnClickListener {
|
||||
val phone = binding.etPhone.text.toString()
|
||||
val code = binding.etCode.text.toString()
|
||||
if (phone.length != 11) {
|
||||
ToastUtils.showToast(requireContext(), getString(R.string.invalid_phone))
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (code.isEmpty()) {
|
||||
ToastUtils.showToast(requireContext(), getString(R.string.enter_verification_code))
|
||||
return@setOnClickListener
|
||||
}
|
||||
onConfirmListener?.invoke(phone, code)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startCountDown() {
|
||||
binding.tvSendCode.isEnabled = false
|
||||
countDownTimer = object : CountDownTimer(60000, 1000) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
binding.tvSendCode.text = String.format("%ds", millisUntilFinished / 1000)
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
binding.tvSendCode.text = getString(R.string.send_sms_code)
|
||||
binding.tvSendCode.isEnabled = true
|
||||
}
|
||||
}
|
||||
countDownTimer?.start()
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
countDownTimer?.cancel()
|
||||
onDismissListener?.invoke()
|
||||
onConfirmListener = null
|
||||
onDismissListener = null
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,14 @@ object ToastUtils {
|
||||
|
||||
private var currentToast: Toast? = null
|
||||
|
||||
fun showToast(context: Context, message: String, duration: Int = Toast.LENGTH_SHORT) {
|
||||
currentToast?.cancel()
|
||||
val toast = Toast.makeText(context.applicationContext, message, duration)
|
||||
toast.setGravity(Gravity.CENTER, 0, 0)
|
||||
currentToast = toast
|
||||
toast.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示成功提示
|
||||
* @param message 提示文字
|
||||
|
||||
Reference in New Issue
Block a user