Files
SecurityDefenseDevice/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt

201 lines
7.0 KiB
Kotlin

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
import android.os.Bundle
import android.util.TypedValue
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
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
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
import com.example.defenseapplication.view.DefenseDialogs
import com.example.defenseapplication.view.showDefenseDialog
import com.gyf.immersionbar.ImmersionBar
class HomeMenuFragment : Fragment() {
// ViewBinding
private var _binding: HomeMenuFragmentBinding? = null
private val binding get() = _binding!!
private val familyAdapter by lazy { FamilyAdapter(::onFamilySelected) }
private val deviceAdapter by lazy { DeviceAdapter(::onDeviceClicked) }
private var isFamilyExpanded = false
private lateinit var currentFamily: String
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,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = HomeMenuFragmentBinding.inflate(inflater, container, false)
ImmersionBar.with(this)
.statusBarDarkFont(true)
.titleBar(binding.main)
.init()
initView()
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 为 LinearLayout 设置渐变背景
setGradientBackground(
view = binding.gradientLayout,
startColor = Color.parseColor("#EBDCED"),
endColor = Color.parseColor("#CAF4FF")
)
binding.message.setOnClickListener {
val intent = Intent(requireContext(), MessageActivity::class.java)
startActivity(intent)
}
binding.add.setOnClickListener {
val intent = Intent(requireContext(), AddDeviceActivity::class.java)
startActivity(intent)
}
binding.addFamily.setOnClickListener {
val intent = Intent(requireContext(), ScanActivity::class.java)
startActivity(intent)
}
}
private fun initView() {
currentFamily = familyList.first()
binding.rvFamilyList.layoutManager = LinearLayoutManager(requireContext())
binding.rvFamilyList.adapter = familyAdapter
familyAdapter.submitList(familyList, currentFamily)
binding.rvDeviceList.layoutManager = GridLayoutManager(requireContext(), 2)
binding.rvDeviceList.adapter = deviceAdapter
if (binding.rvDeviceList.itemDecorationCount == 0) {
binding.rvDeviceList.addItemDecoration(
GridHorizontalSpaceItemDecoration(horizontalSpace = dpToPx(8))
)
}
updateDeviceList()
binding.tvCurrentFamily.text = currentFamily
binding.familyHeaderLayout.setOnClickListener {
toggleFamilyList()
}
binding.familyPopupMask.setOnClickListener {
if (isFamilyExpanded) {
toggleFamilyList()
}
}
}
private fun toggleFamilyList() {
isFamilyExpanded = !isFamilyExpanded
val visibility = if (isFamilyExpanded) View.VISIBLE else View.GONE
binding.familyPopupMask.visibility = visibility
binding.familyPopupCard.visibility = visibility
binding.ivFamilyArrow.animate()
.rotation(if (isFamilyExpanded) 180f else 0f)
.setDuration(200L)
.start()
}
private fun onFamilySelected(familyName: String) {
currentFamily = familyName
binding.tvCurrentFamily.text = familyName
familyAdapter.submitList(familyList, currentFamily)
updateDeviceList()
if (isFamilyExpanded) {
toggleFamilyList()
}
}
private fun updateDeviceList() {
deviceAdapter.submitList(familyDeviceMap[currentFamily].orEmpty())
}
private fun onDeviceClicked(device: DeviceUi) {
if (device.isOnline) return
showDefenseDialog(
config = DefenseDialogs.deviceOfflineConfig(requireContext())
)
}
private fun dpToPx(dp: Int): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp.toFloat(),
resources.displayMetrics
).toInt()
}
private class GridHorizontalSpaceItemDecoration(
private val horizontalSpace: Int
) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildAdapterPosition(view)
if (position == RecyclerView.NO_POSITION) return
if (position % 2 == 0) {
outRect.right = horizontalSpace / 2
} else {
outRect.left = horizontalSpace / 2
}
}
}
private fun setGradientBackground(
view: View,
startColor: Int,
endColor: Int,
orientation: GradientDrawable.Orientation = GradientDrawable.Orientation.TL_BR
) {
val gradientDrawable = GradientDrawable(orientation, intArrayOf(startColor, endColor))
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
view.background = gradientDrawable
}
override fun onDestroyView() {
super.onDestroyView()
binding.rvFamilyList.adapter = null
binding.rvDeviceList.adapter = null
_binding = null // 避免内存泄漏
}
}