切换家庭联动
This commit is contained in:
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@@ -4,10 +4,10 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-05-14T00:25:02.182359600Z">
|
<DropdownSelection timestamp="2026-05-16T03:07:32.812890200Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=AMRF025926116461" />
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=80bece4" />
|
||||||
</handle>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ class DeviceAdapter(
|
|||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: DeviceUi) {
|
fun bind(item: DeviceUi) {
|
||||||
binding.tvDeviceName.text = item.name
|
binding.tvDeviceType.text = item.name
|
||||||
if (item.isOnline) {
|
if (item.isOnline) {
|
||||||
binding.tvDeviceName.text = "\u25CF 正在运行"
|
|
||||||
binding.tvDeviceName.setTextColor(binding.root.context.getColor(R.color.green))
|
binding.tvDeviceName.setTextColor(binding.root.context.getColor(R.color.green))
|
||||||
|
binding.tvDeviceName.text = "\u25CF 正在运行"
|
||||||
} else {
|
} else {
|
||||||
binding.tvDeviceName.text = "\u25CF 离线"
|
|
||||||
binding.tvDeviceName.setTextColor(binding.root.context.getColor(R.color.red))
|
binding.tvDeviceName.setTextColor(binding.root.context.getColor(R.color.red))
|
||||||
|
binding.tvDeviceName.text = "\u25CF 离线"
|
||||||
}
|
}
|
||||||
binding.root.setOnClickListener {
|
binding.root.setOnClickListener {
|
||||||
onItemClick(item)
|
onItemClick(item)
|
||||||
|
|||||||
@@ -37,7 +37,12 @@ class FamilyAdapter(
|
|||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: FamilyBean) {
|
fun bind(item: FamilyBean) {
|
||||||
binding.tvFamilyName.text = item.parentName
|
val isAdmin = item.role == "appadmin"
|
||||||
|
if (isAdmin) {
|
||||||
|
binding.tvFamilyName.text = binding.root.context.getString(R.string.my_family)
|
||||||
|
} else {
|
||||||
|
binding.tvFamilyName.text = "${item.parentName}${binding.root.context.getString(R.string.family_with_normal)}"
|
||||||
|
}
|
||||||
binding.tvFamilyRole.text = getRoleText(item.role)
|
binding.tvFamilyRole.text = getRoleText(item.role)
|
||||||
|
|
||||||
val isSelected = item.parentName == selectedFamily
|
val isSelected = item.parentName == selectedFamily
|
||||||
@@ -48,7 +53,7 @@ class FamilyAdapter(
|
|||||||
|
|
||||||
private fun getRoleText(role: String): String {
|
private fun getRoleText(role: String): String {
|
||||||
return when (role) {
|
return when (role) {
|
||||||
"appadmin" ->binding.root.context.getString(R.string.admin_user)
|
"appadmin" -> binding.root.context.getString(R.string.admin_user)
|
||||||
else -> binding.root.context.getString(R.string.normal_user)
|
else -> binding.root.context.getString(R.string.normal_user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,18 @@ import com.example.defenseapplication.databinding.ItemSwitchFamilyBinding
|
|||||||
import com.example.defenseapplication.model.FamilyItem
|
import com.example.defenseapplication.model.FamilyItem
|
||||||
|
|
||||||
class FamilySwitchAdapter(
|
class FamilySwitchAdapter(
|
||||||
private val familyList: List<FamilyItem>,
|
private var familyList: List<FamilyItem>,
|
||||||
private val onItemClickListener: (FamilyItem) -> Unit
|
private val onItemClickListener: (FamilyItem) -> Unit
|
||||||
) : RecyclerView.Adapter<FamilySwitchAdapter.FamilyViewHolder>() {
|
) : RecyclerView.Adapter<FamilySwitchAdapter.FamilyViewHolder>() {
|
||||||
|
|
||||||
private var selectedPosition = 0
|
private var selectedPosition = 0
|
||||||
|
|
||||||
|
fun updateList(newList: List<FamilyItem>) {
|
||||||
|
familyList = newList
|
||||||
|
selectedPosition = 0
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FamilyViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FamilyViewHolder {
|
||||||
val binding = ItemSwitchFamilyBinding.inflate(
|
val binding = ItemSwitchFamilyBinding.inflate(
|
||||||
LayoutInflater.from(parent.context),
|
LayoutInflater.from(parent.context),
|
||||||
|
|||||||
@@ -1,10 +1,29 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.example.defenseapplication.bean
|
||||||
|
|
||||||
data class DeviceBean(
|
data class DeviceBean(
|
||||||
val id: String,
|
val alertAudio: String,
|
||||||
|
val audioContet: Any,
|
||||||
|
val container: Any,
|
||||||
|
val countNum: Any,
|
||||||
|
val deviceEm: String,
|
||||||
|
val deviceFamilyId: String,
|
||||||
|
val deviceImg: Any,
|
||||||
val deviceName: String,
|
val deviceName: String,
|
||||||
|
val deviceNo: String,
|
||||||
|
val deviceSn: String,
|
||||||
|
val endTime: Any,
|
||||||
|
val expirationTime: String,
|
||||||
|
val fwVer: String,
|
||||||
|
val id: String,
|
||||||
|
val light: String,
|
||||||
|
val patternPerception: Any,
|
||||||
|
val startTime: Any,
|
||||||
val status: String,
|
val status: String,
|
||||||
val deviceType: String,
|
val strikeInterval: Any,
|
||||||
val parentId: String,
|
val strikePosition: Any,
|
||||||
val createTime: String?
|
val strikeRange: Any,
|
||||||
|
val userId: String,
|
||||||
|
val wifiName: String,
|
||||||
|
val wifiPassword: String,
|
||||||
|
val workMode: String
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.example.defenseapplication.bean
|
||||||
|
|
||||||
|
data class MessageItem(
|
||||||
|
val id: String,
|
||||||
|
val userId: String,
|
||||||
|
val deviceId: String,
|
||||||
|
val category: Int,
|
||||||
|
val categoryName: String,
|
||||||
|
val image: String?,
|
||||||
|
val imageUrl: String?,
|
||||||
|
val video: String?,
|
||||||
|
val createTime: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class MessageGroup(
|
||||||
|
val time: String,
|
||||||
|
val list: List<MessageItem>
|
||||||
|
)
|
||||||
@@ -5,6 +5,7 @@ import android.graphics.Color
|
|||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@@ -22,6 +23,8 @@ import com.example.defenseapplication.bean.DeviceBean
|
|||||||
import com.example.defenseapplication.bean.FamilyBean
|
import com.example.defenseapplication.bean.FamilyBean
|
||||||
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
||||||
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
|
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
|
||||||
|
import com.example.defenseapplication.utils.FamilySwitchEvent
|
||||||
|
import com.example.defenseapplication.utils.MessageStatusManager
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.example.defenseapplication.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.utils.UserinfoUtil
|
import com.example.defenseapplication.utils.UserinfoUtil
|
||||||
import com.example.defenseapplication.view.DefenseDialogs
|
import com.example.defenseapplication.view.DefenseDialogs
|
||||||
@@ -42,6 +45,33 @@ class HomeMenuFragment : Fragment() {
|
|||||||
private var isFamilyExpanded = false
|
private var isFamilyExpanded = false
|
||||||
private lateinit var currentFamily: String
|
private lateinit var currentFamily: String
|
||||||
|
|
||||||
|
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
||||||
|
override fun onUnreadCountChanged(count: Int) {
|
||||||
|
updateUnreadCountUI(count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val familySwitchListener = object : FamilySwitchEvent.FamilySwitchListener {
|
||||||
|
override fun onFamilySwitched(familyName: String) {
|
||||||
|
if (familyName != currentFamily) {
|
||||||
|
currentFamily = familyName
|
||||||
|
updateFamilyDisplayText(familyName)
|
||||||
|
familyAdapter.submitList(familyBeanList, currentFamily)
|
||||||
|
switchToFamily(familyName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateFamilyDisplayText(familyName: String) {
|
||||||
|
val familyBean = familyBeanList.find { it.parentName == familyName }
|
||||||
|
val isAdmin = familyBean?.role == "appadmin"
|
||||||
|
binding.tvCurrentFamily.text = if (isAdmin) {
|
||||||
|
getString(R.string.my_family)
|
||||||
|
} else {
|
||||||
|
"${familyName}${getString(R.string.family_with_normal)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var familyList: List<String> = emptyList()
|
private var familyList: List<String> = emptyList()
|
||||||
private var familyBeanList: List<FamilyBean> = emptyList()
|
private var familyBeanList: List<FamilyBean> = emptyList()
|
||||||
private var deviceBeanList: List<DeviceBean> = emptyList()
|
private var deviceBeanList: List<DeviceBean> = emptyList()
|
||||||
@@ -87,6 +117,11 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchFamilyList()
|
fetchFamilyList()
|
||||||
|
fetchUnreadMessageCount()
|
||||||
|
|
||||||
|
MessageStatusManager.addListener(unreadCountChangeListener)
|
||||||
|
FamilySwitchEvent.addListener(familySwitchListener)
|
||||||
|
updateUnreadCountUI(MessageStatusManager.getUnreadCount())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initView() {
|
private fun initView() {
|
||||||
@@ -111,17 +146,49 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun fetchUnreadMessageCount() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getMessage()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val messageGroups = response.data as List<*>
|
||||||
|
var unreadCount = 0
|
||||||
|
messageGroups.forEach { group ->
|
||||||
|
if (group is Map<*, *>) {
|
||||||
|
val list = group["list"] as? List<*>
|
||||||
|
list?.let { unreadCount += it.size }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MessageStatusManager.setUnreadCount(unreadCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateUnreadCountUI(count: Int) {
|
||||||
|
if (count > 0) {
|
||||||
|
binding.tvUnreadCount.visibility = View.VISIBLE
|
||||||
|
binding.tvUnreadCount.text = if (count > 99) "99+" else count.toString()
|
||||||
|
} else {
|
||||||
|
binding.tvUnreadCount.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun fetchFamilyList() {
|
private fun fetchFamilyList() {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getFamilyList()
|
val response = RetrofitNetwork.getNetworkService().getFamilyList()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200 && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
familyBeanList = response.data
|
familyBeanList = response.data.reversed()
|
||||||
familyList = response.data.map { it.parentName }
|
familyList = response.data.map { it.parentName }.reversed()
|
||||||
if (familyList.isNotEmpty()) {
|
if (familyList.isNotEmpty()) {
|
||||||
currentFamily = familyList.first()
|
currentFamily = familyList.first()
|
||||||
binding.tvCurrentFamily.text = currentFamily
|
updateFamilyDisplayText(currentFamily)
|
||||||
familyAdapter.submitList(familyBeanList, currentFamily)
|
familyAdapter.submitList(familyBeanList, currentFamily)
|
||||||
|
|
||||||
val userInfo = UserinfoUtil.getUserInfo()
|
val userInfo = UserinfoUtil.getUserInfo()
|
||||||
@@ -144,6 +211,7 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateAdminUI() {
|
private fun updateAdminUI() {
|
||||||
|
Log.d("HomeMenuFragment", "canViewDevice = $canViewDevice")
|
||||||
if (canViewDevice) {
|
if (canViewDevice) {
|
||||||
binding.tvDeviceTitle.visibility = View.VISIBLE
|
binding.tvDeviceTitle.visibility = View.VISIBLE
|
||||||
binding.rvDeviceList.visibility = View.VISIBLE
|
binding.rvDeviceList.visibility = View.VISIBLE
|
||||||
@@ -180,7 +248,9 @@ class HomeMenuFragment : Fragment() {
|
|||||||
val userInfo = UserinfoUtil.getUserInfo()
|
val userInfo = UserinfoUtil.getUserInfo()
|
||||||
canViewDevice = userInfo?.role == "appadmin" && familyBean.role != "member"
|
canViewDevice = userInfo?.role == "appadmin" && familyBean.role != "member"
|
||||||
updateAdminUI()
|
updateAdminUI()
|
||||||
|
updateFamilyDisplayText(familyName)
|
||||||
fetchDeviceList()
|
fetchDeviceList()
|
||||||
|
FamilySwitchEvent.notifyFamilySwitched(familyName)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
@@ -200,8 +270,10 @@ class HomeMenuFragment : Fragment() {
|
|||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getDeviceList()
|
val response = RetrofitNetwork.getNetworkService().getDeviceList()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
Log.d("DeviceList", "code = ${response.code}, data = ${response.data}")
|
||||||
if (response.code == 200 && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
deviceBeanList = response.data
|
deviceBeanList = response.data
|
||||||
|
Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
|
||||||
updateDeviceList()
|
updateDeviceList()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
||||||
@@ -237,15 +309,8 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDeviceList() {
|
private fun updateDeviceList() {
|
||||||
val currentFamilyId = currentFamilyBean?.id
|
val deviceUiList = deviceBeanList.map {
|
||||||
val filteredDevices = if (currentFamilyId != null) {
|
DeviceUi(it.deviceName, it.status == "0")
|
||||||
deviceBeanList.filter { it.parentId == currentFamilyId }
|
|
||||||
} else {
|
|
||||||
deviceBeanList
|
|
||||||
}
|
|
||||||
|
|
||||||
val deviceUiList = filteredDevices.map {
|
|
||||||
DeviceUi(it.deviceName, it.status == "online")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceUiList.isEmpty()) {
|
if (deviceUiList.isEmpty()) {
|
||||||
@@ -307,6 +372,8 @@ class HomeMenuFragment : Fragment() {
|
|||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
binding.rvFamilyList.adapter = null
|
binding.rvFamilyList.adapter = null
|
||||||
binding.rvDeviceList.adapter = null
|
binding.rvDeviceList.adapter = null
|
||||||
|
MessageStatusManager.removeListener(unreadCountChangeListener)
|
||||||
|
FamilySwitchEvent.removeListener(familySwitchListener)
|
||||||
_binding = null // 避免内存泄漏
|
_binding = null // 避免内存泄漏
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.example.defenseapplication.home
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
@@ -8,8 +9,16 @@ import androidx.core.view.WindowInsetsCompat
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.example.defenseapplication.adapter.MessageListAdapter
|
import com.example.defenseapplication.adapter.MessageListAdapter
|
||||||
import com.example.defenseapplication.adapter.MessageListItem
|
import com.example.defenseapplication.adapter.MessageListItem
|
||||||
|
import com.example.defenseapplication.bean.MessageGroup
|
||||||
|
import com.example.defenseapplication.bean.MessageItem
|
||||||
import com.example.defenseapplication.databinding.MessageActivityBinding
|
import com.example.defenseapplication.databinding.MessageActivityBinding
|
||||||
|
import com.example.defenseapplication.utils.MessageStatusManager
|
||||||
|
import com.example.defenseapplication.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
//消息通知页面
|
//消息通知页面
|
||||||
class MessageActivity : AppCompatActivity() {
|
class MessageActivity : AppCompatActivity() {
|
||||||
private lateinit var binding: MessageActivityBinding
|
private lateinit var binding: MessageActivityBinding
|
||||||
@@ -17,80 +26,94 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
|
||||||
binding = MessageActivityBinding.inflate(layoutInflater)
|
binding = MessageActivityBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
ImmersionBar.with(this)
|
ImmersionBar.with(this)
|
||||||
.statusBarDarkFont(true)
|
.statusBarDarkFont(true)
|
||||||
.titleBar(binding.topBar)
|
.titleBar(binding.topBar)
|
||||||
.init()
|
.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()
|
initView()
|
||||||
|
MessageStatusManager.clearUnreadCount()
|
||||||
|
loadMessageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initView() {
|
private fun initView() {
|
||||||
binding.ivBack.setOnClickListener { finish() }
|
binding.ivBack.setOnClickListener { finish() }
|
||||||
binding.rvMessageList.layoutManager = LinearLayoutManager(this)
|
binding.rvMessageList.layoutManager = LinearLayoutManager(this)
|
||||||
binding.rvMessageList.adapter = messageAdapter
|
binding.rvMessageList.adapter = messageAdapter
|
||||||
messageAdapter.submitList(buildMockData())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildMockData(): List<MessageListItem> {
|
private fun loadMessageList() {
|
||||||
return listOf(
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
MessageListItem.Header("今天"),
|
try {
|
||||||
MessageListItem.Message(
|
val response = RetrofitNetwork.getNetworkService().getMessage()
|
||||||
time = "15:54",
|
if (response.code == 0 && response.data != null) {
|
||||||
title = "有人入侵",
|
val messageGroups = response.data as List<MessageGroup>
|
||||||
dateTime = "2026-05-06 15:54:25",
|
val items = convertToMessageListItems(messageGroups)
|
||||||
unread = true
|
withContext(Dispatchers.Main) {
|
||||||
),
|
if (items.isEmpty()) {
|
||||||
MessageListItem.Message(
|
showEmptyState()
|
||||||
time = "12:54",
|
} else {
|
||||||
title = "有人入侵",
|
hideEmptyState()
|
||||||
dateTime = "2026-05-06 15:54:25",
|
messageAdapter.submitList(items)
|
||||||
unread = true
|
}
|
||||||
),
|
}
|
||||||
MessageListItem.Message(
|
} else {
|
||||||
time = "11:54",
|
withContext(Dispatchers.Main) {
|
||||||
title = "有人入侵",
|
showEmptyState()
|
||||||
dateTime = "2026-05-06 15:54:25",
|
}
|
||||||
unread = true
|
}
|
||||||
),
|
} catch (e: Exception) {
|
||||||
MessageListItem.Header("05-05"),
|
e.printStackTrace()
|
||||||
MessageListItem.Message(
|
withContext(Dispatchers.Main) {
|
||||||
time = "15:54",
|
showEmptyState()
|
||||||
title = "设备故障",
|
}
|
||||||
dateTime = "2026-05-06 15:54:25",
|
}
|
||||||
unread = false
|
}
|
||||||
),
|
}
|
||||||
MessageListItem.Message(
|
|
||||||
time = "08:07",
|
private fun showEmptyState() {
|
||||||
title = "设备离线",
|
binding.contentLayout.visibility = View.GONE
|
||||||
dateTime = "2026-05-06 15:54:25",
|
binding.emptyLayout.visibility = View.VISIBLE
|
||||||
unread = false
|
}
|
||||||
),
|
|
||||||
MessageListItem.Message(
|
private fun hideEmptyState() {
|
||||||
time = "08:07",
|
binding.contentLayout.visibility = View.VISIBLE
|
||||||
title = "到期提醒",
|
binding.emptyLayout.visibility = View.GONE
|
||||||
dateTime = "2026-05-06 15:54:25",
|
}
|
||||||
unread = false
|
|
||||||
),
|
private fun convertToMessageListItems(groups: List<MessageGroup>): List<MessageListItem> {
|
||||||
MessageListItem.Message(
|
val items = mutableListOf<MessageListItem>()
|
||||||
time = "11:54",
|
groups.forEach { group ->
|
||||||
title = "有人入侵",
|
val headerTitle = formatDate(group.time)
|
||||||
dateTime = "2026-05-06 15:54:25",
|
items.add(MessageListItem.Header(headerTitle))
|
||||||
unread = false
|
group.list.forEach { message ->
|
||||||
),
|
items.add(
|
||||||
MessageListItem.Message(
|
MessageListItem.Message(
|
||||||
time = "11:54",
|
time = extractTime(message.createTime),
|
||||||
title = "有人入侵",
|
title = message.categoryName,
|
||||||
dateTime = "2026-05-06 15:54:25",
|
dateTime = message.createTime,
|
||||||
unread = false
|
unread = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatDate(dateStr: String): String {
|
||||||
|
return if (dateStr == "今天" || dateStr.contains("今天")) {
|
||||||
|
"今天"
|
||||||
|
} else {
|
||||||
|
dateStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractTime(dateTime: String): String {
|
||||||
|
return if (dateTime.contains(" ")) {
|
||||||
|
dateTime.split(" ")[1].substring(0, 5)
|
||||||
|
} else {
|
||||||
|
dateTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import androidx.fragment.app.Fragment
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.example.defenseapplication.R
|
import com.example.defenseapplication.R
|
||||||
import com.example.defenseapplication.databinding.PersonalFragmentBinding
|
import com.example.defenseapplication.databinding.PersonalFragmentBinding
|
||||||
@@ -13,9 +14,15 @@ import com.example.defenseapplication.liveVideo.LinkedUserActivity
|
|||||||
import com.example.defenseapplication.personal.PasswordManagementActivity
|
import com.example.defenseapplication.personal.PasswordManagementActivity
|
||||||
import com.example.defenseapplication.personal.PersonalProfileActivity
|
import com.example.defenseapplication.personal.PersonalProfileActivity
|
||||||
import com.example.defenseapplication.utils.LanguageUtil
|
import com.example.defenseapplication.utils.LanguageUtil
|
||||||
|
import com.example.defenseapplication.utils.RetrofitNetwork
|
||||||
|
import com.example.defenseapplication.utils.UserinfoUtil
|
||||||
import com.example.defenseapplication.view.FamilySwitchDialog
|
import com.example.defenseapplication.view.FamilySwitchDialog
|
||||||
import com.example.defenseapplication.view.LanguageDialog
|
import com.example.defenseapplication.view.LanguageDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
//我的碎片
|
//我的碎片
|
||||||
class PersonalFragment : Fragment() {
|
class PersonalFragment : Fragment() {
|
||||||
// ViewBinding
|
// ViewBinding
|
||||||
@@ -61,9 +68,36 @@ class PersonalFragment : Fragment() {
|
|||||||
val intent= Intent(requireContext(), PasswordManagementActivity::class.java)
|
val intent= Intent(requireContext(), PasswordManagementActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
fetchCurrentFamily()
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun fetchCurrentFamily() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getFamilyList()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val userInfo = UserinfoUtil.getUserInfo()
|
||||||
|
val currentFamily = response.data.find {
|
||||||
|
it.role == userInfo?.role && it.role != "member"
|
||||||
|
} ?: response.data.firstOrNull()
|
||||||
|
currentFamily?.let {
|
||||||
|
val isAdmin = it.role == "appadmin"
|
||||||
|
if (isAdmin) {
|
||||||
|
binding.tvCurrentFamily.text = getString(R.string.my_family)
|
||||||
|
} else {
|
||||||
|
binding.tvCurrentFamily.text = "${it.parentName}${getString(R.string.family_with_normal)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新当前语言显示
|
* 更新当前语言显示
|
||||||
@@ -90,11 +124,39 @@ class PersonalFragment : Fragment() {
|
|||||||
*/
|
*/
|
||||||
private fun showFamilySwitchDialog() {
|
private fun showFamilySwitchDialog() {
|
||||||
val dialog = FamilySwitchDialog(requireContext()) { familyName ->
|
val dialog = FamilySwitchDialog(requireContext()) { familyName ->
|
||||||
binding.tvCurrentFamily.text = familyName
|
updateFamilyDisplay(familyName)
|
||||||
}
|
}
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateFamilyDisplay(familyName: String) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getFamilyList()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val family = response.data.find { it.parentName == familyName }
|
||||||
|
family?.let {
|
||||||
|
val isAdmin = it.role == "appadmin"
|
||||||
|
if (isAdmin) {
|
||||||
|
binding.tvCurrentFamily.text = getString(R.string.my_family)
|
||||||
|
} else {
|
||||||
|
binding.tvCurrentFamily.text = "${it.parentName}${getString(R.string.family_with_normal)}"
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
binding.tvCurrentFamily.text = familyName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
binding.tvCurrentFamily.text = familyName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
binding.tvCurrentFamily.text = familyName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null // 避免内存泄漏
|
_binding = null // 避免内存泄漏
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.example.defenseapplication.bean.GetCodeBean
|
|||||||
import bean.LoginBean
|
import bean.LoginBean
|
||||||
import bean.LoginRequest
|
import bean.LoginRequest
|
||||||
import bean.RegisterRequest
|
import bean.RegisterRequest
|
||||||
|
import com.example.defenseapplication.bean.MessageGroup
|
||||||
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
@@ -55,6 +56,12 @@ interface ApiService {
|
|||||||
*/
|
*/
|
||||||
@GET("/app/getdeviceList")
|
@GET("/app/getdeviceList")
|
||||||
suspend fun getDeviceList(): GetCodeBean<List<DeviceBean>>
|
suspend fun getDeviceList(): GetCodeBean<List<DeviceBean>>
|
||||||
|
/**
|
||||||
|
* 查看消息列表
|
||||||
|
*/
|
||||||
|
@GET("/app/appMessage/list")
|
||||||
|
suspend fun getMessage(): GetCodeBean<List<MessageGroup>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.example.defenseapplication.utils
|
||||||
|
|
||||||
|
object FamilySwitchEvent {
|
||||||
|
private val listeners = mutableListOf<FamilySwitchListener>()
|
||||||
|
|
||||||
|
interface FamilySwitchListener {
|
||||||
|
fun onFamilySwitched(familyName: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addListener(listener: FamilySwitchListener) {
|
||||||
|
if (!listeners.contains(listener)) {
|
||||||
|
listeners.add(listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener(listener: FamilySwitchListener) {
|
||||||
|
listeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notifyFamilySwitched(familyName: String) {
|
||||||
|
listeners.forEach { it.onFamilySwitched(familyName) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.example.defenseapplication.utils
|
||||||
|
|
||||||
|
object MessageStatusManager {
|
||||||
|
private var unreadCount = 0
|
||||||
|
private val listeners = mutableListOf<UnreadCountChangeListener>()
|
||||||
|
|
||||||
|
fun getUnreadCount(): Int {
|
||||||
|
return unreadCount
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setUnreadCount(count: Int) {
|
||||||
|
unreadCount = if (count > 99) 99 else count
|
||||||
|
notifyListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun incrementUnreadCount() {
|
||||||
|
unreadCount++
|
||||||
|
if (unreadCount > 99) unreadCount = 99
|
||||||
|
notifyListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearUnreadCount() {
|
||||||
|
unreadCount = 0
|
||||||
|
notifyListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addListener(listener: UnreadCountChangeListener) {
|
||||||
|
if (!listeners.contains(listener)) {
|
||||||
|
listeners.add(listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener(listener: UnreadCountChangeListener) {
|
||||||
|
listeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notifyListeners() {
|
||||||
|
listeners.forEach { it.onUnreadCountChanged(unreadCount) }
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UnreadCountChangeListener {
|
||||||
|
fun onUnreadCountChanged(count: Int)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,21 +7,30 @@ import android.view.Gravity
|
|||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.example.defenseapplication.R
|
||||||
import com.example.defenseapplication.adapter.FamilySwitchAdapter
|
import com.example.defenseapplication.adapter.FamilySwitchAdapter
|
||||||
|
import com.example.defenseapplication.bean.FamilyBean
|
||||||
|
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
||||||
import com.example.defenseapplication.model.FamilyItem
|
import com.example.defenseapplication.model.FamilyItem
|
||||||
|
import com.example.defenseapplication.utils.FamilySwitchEvent
|
||||||
|
import com.example.defenseapplication.utils.RetrofitNetwork
|
||||||
|
import com.example.defenseapplication.utils.UserinfoUtil
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/**
|
|
||||||
* 家庭切换对话框
|
|
||||||
*/
|
|
||||||
class FamilySwitchDialog(
|
class FamilySwitchDialog(
|
||||||
context: Context,
|
context: Context,
|
||||||
private val onFamilySelected: (String) -> Unit
|
private val onFamilySelected: (String) -> Unit
|
||||||
) : Dialog(context, R.style.BottomDialogStyle) {
|
) : Dialog(context, R.style.BottomDialogStyle) {
|
||||||
|
|
||||||
private lateinit var adapter: FamilySwitchAdapter
|
private lateinit var adapter: FamilySwitchAdapter
|
||||||
|
private var familyBeanList: List<FamilyBean> = emptyList()
|
||||||
|
private var currentFamilyName: String = ""
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -38,6 +47,7 @@ class FamilySwitchDialog(
|
|||||||
window?.setDimAmount(0.5f)
|
window?.setDimAmount(0.5f)
|
||||||
|
|
||||||
initViews()
|
initViews()
|
||||||
|
fetchFamilyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initViews() {
|
private fun initViews() {
|
||||||
@@ -45,12 +55,7 @@ class FamilySwitchDialog(
|
|||||||
val tvConfirm = findViewById<TextView>(R.id.tvConfirm)
|
val tvConfirm = findViewById<TextView>(R.id.tvConfirm)
|
||||||
val rvMessageList = findViewById<RecyclerView>(R.id.rvMessageList)
|
val rvMessageList = findViewById<RecyclerView>(R.id.rvMessageList)
|
||||||
|
|
||||||
val familyList = listOf(
|
adapter = FamilySwitchAdapter(emptyList()) { familyItem ->
|
||||||
FamilyItem("1", context.getString(R.string.my_family)),
|
|
||||||
FamilyItem("2", "张三的家庭")
|
|
||||||
)
|
|
||||||
|
|
||||||
adapter = FamilySwitchAdapter(familyList) { familyItem ->
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rvMessageList.layoutManager = LinearLayoutManager(context)
|
rvMessageList.layoutManager = LinearLayoutManager(context)
|
||||||
@@ -61,9 +66,67 @@ class FamilySwitchDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
tvConfirm.setOnClickListener {
|
tvConfirm.setOnClickListener {
|
||||||
val selectedFamily = adapter.getSelectedItem()
|
val selectedItem = adapter.getSelectedItem()
|
||||||
onFamilySelected(selectedFamily.name)
|
val selectedFamily = familyBeanList.find { it.parentName == selectedItem.name }
|
||||||
dismiss()
|
selectedFamily?.let {
|
||||||
|
switchToFamily(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchFamilyList() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getFamilyList()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
familyBeanList = response.data.reversed()
|
||||||
|
val familyItems = familyBeanList.map { FamilyItem(it.id, it.parentName) }
|
||||||
|
adapter.updateList(familyItems)
|
||||||
|
|
||||||
|
familyBeanList.firstOrNull()?.let {
|
||||||
|
currentFamilyName = it.parentName
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(context, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast.makeText(context, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun switchToFamily(familyBean: FamilyBean) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val userInfo = UserinfoUtil.getUserInfo()
|
||||||
|
val request = SwitchFamilyRequest(
|
||||||
|
clientId = "428a8310cd442757ae699df5d894f051",
|
||||||
|
grantType = "switch",
|
||||||
|
id = familyBean.id,
|
||||||
|
userType = "app_user",
|
||||||
|
role = userInfo?.role ?: ""
|
||||||
|
)
|
||||||
|
val response = RetrofitNetwork.getNetworkService().switchFamily(request)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200) {
|
||||||
|
onFamilySelected(familyBean.parentName)
|
||||||
|
FamilySwitchEvent.notifyFamilySwitched(familyBean.parentName)
|
||||||
|
dismiss()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(context, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast.makeText(context, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
9
app/src/main/res/drawable/bg_family_popup.xml
Normal file
9
app/src/main/res/drawable/bg_family_popup.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="#EEEEEE" />
|
||||||
|
</shape>
|
||||||
6
app/src/main/res/drawable/bg_family_selected.xml
Normal file
6
app/src/main/res/drawable/bg_family_selected.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="#00CED1" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
9
app/src/main/res/drawable/ic_check_white.xml
Normal file
9
app/src/main/res/drawable/ic_check_white.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable/no_message.png
Normal file
BIN
app/src/main/res/drawable/no_message.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -78,11 +78,18 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:src="@drawable/message"/>
|
android:src="@drawable/message"/>
|
||||||
|
|
||||||
<View
|
<TextView
|
||||||
android:layout_width="10dp"
|
android:id="@+id/tvUnreadCount"
|
||||||
android:layout_height="10dp"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end|top"
|
android:layout_gravity="end|top"
|
||||||
android:background="@drawable/ic_red_dot" />
|
android:background="@drawable/bg_unread_dot"
|
||||||
|
android:minWidth="16dp"
|
||||||
|
android:height="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:visibility="gone" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:background="@drawable/bg_white"
|
android:background="@drawable/bg_white"
|
||||||
android:layout_marginBottom="14dp"
|
android:layout_marginBottom="14dp"
|
||||||
@@ -29,22 +28,28 @@
|
|||||||
android:src="@drawable/go_up" />
|
android:src="@drawable/go_up" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:text="防雨机"
|
||||||
android:id="@+id/tvDeviceType"
|
android:id="@+id/tvDeviceType"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="12dp" />
|
android:textSize="14dp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:text="离线"
|
||||||
android:id="@+id/tvDeviceName"
|
android:id="@+id/tvDeviceName"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="12dp" />
|
android:textSize="12dp"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
|
android:padding="16dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/message_bg"
|
android:background="@color/message_bg"
|
||||||
android:orientation="vertical"
|
|
||||||
tools:context=".home.MessageActivity">
|
tools:context=".home.MessageActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -35,15 +35,35 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<LinearLayout
|
||||||
android:id="@+id/rvMessageList"
|
android:id="@+id/contentLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:orientation="vertical"
|
||||||
android:paddingStart="16dp"
|
android:padding="16dp">
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingBottom="16dp"
|
|
||||||
tools:listitem="@layout/item_message_notice" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvMessageList"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
tools:listitem="@layout/item_message_notice" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/emptyLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/no_message" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@@ -15,9 +15,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="16dp">
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/backIcon"
|
android:id="@+id/backIcon"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
|
|||||||
@@ -109,6 +109,8 @@
|
|||||||
<string name="join_family">加入家庭</string>
|
<string name="join_family">加入家庭</string>
|
||||||
<string name="family_code">家庭码</string>
|
<string name="family_code">家庭码</string>
|
||||||
<string name="enter_family_code">请输入家庭码</string>
|
<string name="enter_family_code">请输入家庭码</string>
|
||||||
|
<string name="family_with_normal">的家庭</string>
|
||||||
|
<string name="no_device">暂无设备</string>
|
||||||
|
|
||||||
<!-- User Management -->
|
<!-- User Management -->
|
||||||
<string name="user_management">用户管理</string>
|
<string name="user_management">用户管理</string>
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
<string name="profile">Profile</string>
|
<string name="profile">Profile</string>
|
||||||
<string name="admin_user">Administrator</string>
|
<string name="admin_user">Administrator</string>
|
||||||
<string name="normal_user">Ordinary User</string>
|
<string name="normal_user">Ordinary User</string>
|
||||||
|
<string name="family_with_normal">s Family</string>
|
||||||
|
|
||||||
|
|
||||||
<!-- Home Menu -->
|
<!-- Home Menu -->
|
||||||
|
|||||||
Reference in New Issue
Block a user