diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1aeaa6b..fa6f916 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -50,6 +50,7 @@ dependencies {
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
+ implementation("de.hdodenhof:circleimageview:3.1.0")
// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
// Gson 转换器
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9ac6a21..78bae90 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,10 @@
+
+
+
+
+
+
diff --git a/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt
new file mode 100644
index 0000000..e6f181a
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt
@@ -0,0 +1,40 @@
+package com.example.defenseapplication.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.example.defenseapplication.R
+
+data class Device(
+ val name: String,
+ val icon: String
+)
+class AddDeviceAdapter(private val devices: List, private val onItemClick: (Device) -> Unit) :
+ RecyclerView.Adapter() {
+
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val ivIcon: ImageView = itemView.findViewById(R.id.ivDeviceIcon2)
+ val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2) // 注意:ID 要和布局中一致
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val view = LayoutInflater.from(parent.context).inflate(R.layout.item_device2, parent, false)
+ return ViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val device = devices[position]
+ holder.tvName.text = device.name
+ // 根据 icon 字符串加载对应图片(假设 icon 是本地 drawable 的名称)
+ val resId = holder.itemView.context.resources.getIdentifier(device.icon, "drawable", holder.itemView.context.packageName)
+ if (resId != 0) holder.ivIcon.setImageResource(resId) else holder.ivIcon.setImageResource(R.drawable.img)
+
+ // 设置点击事件
+ holder.itemView.setOnClickListener { onItemClick(device) }
+ }
+
+ override fun getItemCount(): Int = devices.size
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/adapter/DeviceAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/DeviceAdapter.kt
index 4dedce7..4b54ecc 100644
--- a/app/src/main/java/com/example/defenseapplication/adapter/DeviceAdapter.kt
+++ b/app/src/main/java/com/example/defenseapplication/adapter/DeviceAdapter.kt
@@ -40,11 +40,11 @@ class DeviceAdapter(
fun bind(item: DeviceUi) {
binding.tvDeviceName.text = item.name
if (item.isOnline) {
- binding.tvDeviceStatus.text = "\u25CF 正在运行"
- binding.tvDeviceStatus.setTextColor(binding.root.context.getColor(R.color.green))
+ binding.tvDeviceName.text = "\u25CF 正在运行"
+ binding.tvDeviceName.setTextColor(binding.root.context.getColor(R.color.green))
} else {
- binding.tvDeviceStatus.text = "\u25CF 离线"
- binding.tvDeviceStatus.setTextColor(binding.root.context.getColor(R.color.red))
+ binding.tvDeviceName.text = "\u25CF 离线"
+ binding.tvDeviceName.setTextColor(binding.root.context.getColor(R.color.red))
}
binding.root.setOnClickListener {
onItemClick(item)
diff --git a/app/src/main/java/com/example/defenseapplication/home/AddDeviceActivity.kt b/app/src/main/java/com/example/defenseapplication/home/AddDeviceActivity.kt
index 7d07526..90bc425 100644
--- a/app/src/main/java/com/example/defenseapplication/home/AddDeviceActivity.kt
+++ b/app/src/main/java/com/example/defenseapplication/home/AddDeviceActivity.kt
@@ -1,21 +1,52 @@
package com.example.defenseapplication.home
+import android.content.Intent
import android.os.Bundle
-import androidx.activity.enableEdgeToEdge
+import android.view.View
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
-import com.example.defenseapplication.R
+import androidx.recyclerview.widget.GridLayoutManager
+import com.example.defenseapplication.adapter.AddDeviceAdapter
+import com.example.defenseapplication.adapter.Device
+import com.example.defenseapplication.databinding.AddDeviceActivityBinding
class AddDeviceActivity : AppCompatActivity() {
+
+ private lateinit var binding: AddDeviceActivityBinding
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- enableEdgeToEdge()
- setContentView(R.layout.add_device_activity)
- ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
- val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
- v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
- insets
+ binding = AddDeviceActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ setupDeviceList()
+ }
+
+ private fun setupDeviceList() {
+ val devices = listOf(
+ Device("智能挂式防御机", "device1"),
+ Device("智能防御机", "device2")
+ )
+
+ if (devices.isEmpty()) {
+ binding.emptyState.visibility = View.VISIBLE
+ binding.rvDevices.visibility = View.GONE
+ } else {
+ binding.emptyState.visibility = View.GONE
+ binding.rvDevices.visibility = View.VISIBLE
+
+ binding.rvDevices.layoutManager = GridLayoutManager(this, 2)
+ // 传入点击回调
+ binding.rvDevices.adapter = AddDeviceAdapter(devices) { device ->
+ // 跳转到 AddFamilyActivity(选择Wi-Fi页面)
+ val intent = Intent(this, AddFamilyActivity::class.java)
+ intent.putExtra("device_name", device.name)
+ startActivity(intent)
+ }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/home/AddFamilyActivity.kt b/app/src/main/java/com/example/defenseapplication/home/AddFamilyActivity.kt
new file mode 100644
index 0000000..97343e6
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/home/AddFamilyActivity.kt
@@ -0,0 +1,158 @@
+package com.example.defenseapplication.home
+
+import android.Manifest
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.net.wifi.ScanResult
+import android.net.wifi.WifiManager
+import android.os.Bundle
+import android.text.Editable
+import android.text.TextWatcher
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import android.widget.PopupWindow
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.defenseapplication.R
+import com.example.defenseapplication.adapter.WifiListAdapter
+import com.example.defenseapplication.databinding.AddFamilyActivityBinding
+import com.example.defenseapplication.databinding.DialogWifiListBinding
+
+class AddFamilyActivity : AppCompatActivity() {
+
+ private lateinit var binding: AddFamilyActivityBinding
+ private lateinit var wifiManager: WifiManager
+ private lateinit var wifiScanReceiver: BroadcastReceiver
+ private var popupWindow: PopupWindow? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = AddFamilyActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ binding.btnSelectWifi.setOnClickListener {
+ showWifiListDialog()
+ }
+
+ binding.etWifiName.addTextChangedListener(object : TextWatcher {
+ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
+
+ override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
+
+ override fun afterTextChanged(s: Editable?) {
+ updateBottomButtonVisibility()
+ }
+ })
+
+ binding.btnConfirm.setOnClickListener {
+ // 确认添加设备逻辑
+ }
+
+ wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
+
+ wifiScanReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
+ if (success) {
+ updateWifiList()
+ }
+ }
+ }
+
+ val deviceName = intent.getStringExtra("device_name")
+
+ binding.btnConfirm.setOnClickListener {
+ val intent=Intent(this, SetNameActivity::class.java)
+ startActivity( intent)
+ }
+ }
+
+ private fun showWifiListDialog() {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED ||
+ ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(this,
+ arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE),
+ 1001)
+ return
+ }
+
+ if (!wifiManager.isWifiEnabled) {
+ wifiManager.isWifiEnabled = true
+ }
+
+ wifiManager.startScan()
+
+ val dialogBinding = DialogWifiListBinding.inflate(LayoutInflater.from(this))
+ popupWindow = PopupWindow(
+ dialogBinding.root,
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ).apply {
+ isFocusable = true
+ setBackgroundDrawable(null)
+ setOnDismissListener {
+ binding.maskView.visibility = android.view.View.GONE
+ }
+ showAtLocation(window.decorView, Gravity.BOTTOM, 0, 0)
+ }
+
+ binding.maskView.visibility = android.view.View.VISIBLE
+
+ dialogBinding.rvWifiList.layoutManager = LinearLayoutManager(this@AddFamilyActivity)
+
+ val wifiList = getWifiList()
+ dialogBinding.rvWifiList.adapter = WifiListAdapter(wifiList) { wifiName ->
+ binding.etWifiName.setText(wifiName)
+ popupWindow?.dismiss()
+ }
+ }
+
+ private fun updateBottomButtonVisibility() {
+ val wifiName = binding.etWifiName.text.toString().trim()
+ binding.bottomButtonLayout.visibility =
+ if (wifiName.isNotEmpty()) android.view.View.VISIBLE else android.view.View.GONE
+ }
+
+ private fun getWifiList(): List {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED) {
+ return emptyList()
+ }
+ val results: List = wifiManager.scanResults
+ return results.map { it.SSID }.distinct()
+ }
+
+ private fun updateWifiList() {
+ popupWindow?.contentView?.findViewById(R.id.rvWifiList)?.let { recyclerView ->
+ val wifiList = getWifiList()
+ recyclerView.adapter = WifiListAdapter(wifiList) { wifiName ->
+ binding.etWifiName.setText(wifiName)
+ popupWindow?.dismiss()
+ }
+ }
+ }
+
+ override fun onStart() {
+ super.onStart()
+ val intentFilter = IntentFilter()
+ intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
+ registerReceiver(wifiScanReceiver, intentFilter)
+ }
+
+ override fun onStop() {
+ super.onStop()
+ unregisterReceiver(wifiScanReceiver)
+ popupWindow?.dismiss()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt b/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt
index 856ea9c..c3a001c 100644
--- a/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt
+++ b/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt
@@ -70,6 +70,14 @@ class HomeMenuFragment : Fragment() {
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(), AddFamilyActivity::class.java)
+ startActivity(intent)
+ }
}
private fun initView() {
diff --git a/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt b/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt
new file mode 100644
index 0000000..3070a7f
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt
@@ -0,0 +1,25 @@
+package com.example.defenseapplication.home
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.example.defenseapplication.databinding.SetNameActivityBinding
+
+class SetNameActivity : AppCompatActivity() {
+
+ private lateinit var binding: SetNameActivityBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = SetNameActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ binding.btnConfirm.setOnClickListener {
+ val deviceName = binding.etName.text.toString().trim()
+ finish()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/back.png b/app/src/main/res/drawable/back.png
new file mode 100644
index 0000000..65c0eaa
Binary files /dev/null and b/app/src/main/res/drawable/back.png differ
diff --git a/app/src/main/res/drawable/go_up.png b/app/src/main/res/drawable/go_up.png
new file mode 100644
index 0000000..2c54b4c
Binary files /dev/null and b/app/src/main/res/drawable/go_up.png differ
diff --git a/app/src/main/res/drawable/ic_lock.png b/app/src/main/res/drawable/ic_lock.png
new file mode 100644
index 0000000..e6d5f52
Binary files /dev/null and b/app/src/main/res/drawable/ic_lock.png differ
diff --git a/app/src/main/res/drawable/ic_wifi.png b/app/src/main/res/drawable/ic_wifi.png
new file mode 100644
index 0000000..1186ba0
Binary files /dev/null and b/app/src/main/res/drawable/ic_wifi.png differ
diff --git a/app/src/main/res/layout/add_device_activity.xml b/app/src/main/res/layout/add_device_activity.xml
index 8ff8b1c..0f75742 100644
--- a/app/src/main/res/layout/add_device_activity.xml
+++ b/app/src/main/res/layout/add_device_activity.xml
@@ -5,6 +5,127 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="@color/white"
tools:context=".home.AddDeviceActivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/add_family_activity.xml b/app/src/main/res/layout/add_family_activity.xml
new file mode 100644
index 0000000..9a0ae7d
--- /dev/null
+++ b/app/src/main/res/layout/add_family_activity.xml
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/home_menu_fragment.xml b/app/src/main/res/layout/home_menu_fragment.xml
index bfebc08..367263b 100644
--- a/app/src/main/res/layout/home_menu_fragment.xml
+++ b/app/src/main/res/layout/home_menu_fragment.xml
@@ -77,6 +77,7 @@
+ android:background="@drawable/bg_white"
+ android:layout_marginBottom="14dp"
+ android:layout_gravity="center_horizontal"
+ android:padding="8dp">
-
-
+ android:layout_height="80dp"
+ android:layout_weight="1"
+ android:scaleType="centerInside"
+ android:src="@mipmap/ic_launcher_round" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/go_up" />
-
+ android:layout_marginTop="4dp"
+ android:textColor="@color/black"
+ android:textSize="12dp" />
-
+
-
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_device2.xml b/app/src/main/res/layout/item_device2.xml
new file mode 100644
index 0000000..4860241
--- /dev/null
+++ b/app/src/main/res/layout/item_device2.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/personal_profile_activity.xml b/app/src/main/res/layout/personal_profile_activity.xml
index 0d4435e..cd1b63a 100644
--- a/app/src/main/res/layout/personal_profile_activity.xml
+++ b/app/src/main/res/layout/personal_profile_activity.xml
@@ -5,7 +5,7 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/message_bg"
+ android:background="@color/white"
android:orientation="vertical"
tools:context=".personal.PersonalProfileActivity">
@@ -47,22 +47,20 @@
android:id="@+id/ivAvatar"
android:layout_width="112dp"
android:layout_height="112dp"
- android:padding="2dp"
- android:src="@mipmap/ic_launcher_round" />
+ android:src="@mipmap/ic_launcher_round"/>
+ android:layout_marginEnd="5dp">
@@ -78,6 +76,7 @@
android:id="@+id/itemNickname"
android:layout_width="match_parent"
android:layout_height="60dp"
+ android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp">
@@ -120,6 +119,7 @@
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="8dp"
+ android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp">
@@ -132,7 +132,7 @@
android:textSize="16dp" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file