diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 28a58c9..e28f437 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,9 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.DefenseApplication"> + @@ -54,13 +57,7 @@ android:exported="false" /> - - - - - - + android:exported="false" /> @@ -84,7 +81,13 @@ android:exported="false" /> + android:exported="true"> + + + + + + diff --git a/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt index 9f8306e..e8637be 100644 --- a/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt +++ b/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt @@ -10,14 +10,33 @@ import com.example.defenseapplication.R data class Device( val name: String, - val icon: String + val icon: String // 暂时保留,不再实际使用静态图片 ) -class AddDeviceAdapter(private val devices: List, private val onItemClick: (Device) -> Unit) : - RecyclerView.Adapter() { + +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 要和布局中一致 + val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2) + + // 启动帧动画 + fun startAnimation() { + val drawable = ivIcon.drawable + if (drawable is android.graphics.drawable.AnimationDrawable && !drawable.isRunning) { + drawable.start() + } + } + + // 停止帧动画 + fun stopAnimation() { + val drawable = ivIcon.drawable + if (drawable is android.graphics.drawable.AnimationDrawable && drawable.isRunning) { + drawable.stop() + } + } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { @@ -28,13 +47,17 @@ class AddDeviceAdapter(private val devices: List, private val onItemClic 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.ivIcon.setImageResource(R.drawable.img) - // 设置点击事件 + // 点击事件 holder.itemView.setOnClickListener { onItemClick(device) } } + override fun onViewRecycled(holder: ViewHolder) { + super.onViewRecycled(holder) + // 视图被回收时停止动画,节省资源 + holder.stopAnimation() + } + override fun getItemCount(): Int = devices.size } \ No newline at end of file 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 15d3be2..997ffd1 100644 --- a/app/src/main/java/com/example/defenseapplication/home/AddDeviceActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/AddDeviceActivity.kt @@ -2,6 +2,8 @@ package com.example.defenseapplication.home import android.content.Intent import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity @@ -12,10 +14,12 @@ import com.example.defenseapplication.adapter.Device import com.example.defenseapplication.databinding.AddDeviceActivityBinding import com.gyf.immersionbar.ImmersionBar +//添加设备页面 class AddDeviceActivity : AppCompatActivity() { private lateinit var binding: AddDeviceActivityBinding - + private lateinit var adapter: AddDeviceAdapter + private val mainHandler = Handler(Looper.getMainLooper()) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = AddDeviceActivityBinding.inflate(layoutInflater) @@ -28,7 +32,31 @@ class AddDeviceActivity : AppCompatActivity() { finish() } - setupDeviceList() + // 开始播放扫描动画,动画结束后再显示设备列表 + startScanAnimationThenShowList() + } + + private fun startScanAnimationThenShowList() { + // 显示动画层 + binding.animationContainer.visibility = View.VISIBLE + binding.rvDevices.visibility = View.GONE + + // 设置帧动画并启动 + binding.ivScanAnimation.setImageResource(R.drawable.device_frame_animation) + val scanDrawable = binding.ivScanAnimation.drawable + if (scanDrawable is android.graphics.drawable.AnimationDrawable) { + scanDrawable.start() + } + + // 模拟扫描过程 + mainHandler.postDelayed({ + // 停止动画 + (binding.ivScanAnimation.drawable as? android.graphics.drawable.AnimationDrawable)?.stop() + // 隐藏动画层,显示列表 + binding.animationContainer.visibility = View.GONE + binding.rvDevices.visibility = View.VISIBLE + setupDeviceList() // 加载设备列表 + }, 3000) // 动画播放时长,可根据实际帧动画总时长调整 } private fun setupDeviceList() { @@ -38,20 +66,38 @@ class AddDeviceActivity : AppCompatActivity() { ) 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页面) + adapter = AddDeviceAdapter(devices) { device -> val intent = Intent(this, AddFamilyActivity::class.java) intent.putExtra("device_name", device.name) startActivity(intent) } + binding.rvDevices.adapter = adapter + } + } + override fun onPause() { + super.onPause() + // 停止所有可见 item 的动画 + for (i in 0 until binding.rvDevices.childCount) { + val child = binding.rvDevices.getChildAt(i) + val holder = binding.rvDevices.getChildViewHolder(child) as? AddDeviceAdapter.ViewHolder + holder?.stopAnimation() + } + } + + override fun onResume() { + super.onResume() + // 重新启动所有可见 item 的动画 + for (i in 0 until binding.rvDevices.childCount) { + val child = binding.rvDevices.getChildAt(i) + val holder = binding.rvDevices.getChildViewHolder(child) as? AddDeviceAdapter.ViewHolder + holder?.startAnimation() } } } \ 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 index caafdc8..f3cf3f0 100644 --- a/app/src/main/java/com/example/defenseapplication/home/AddFamilyActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/AddFamilyActivity.kt @@ -24,6 +24,7 @@ import com.example.defenseapplication.databinding.AddFamilyActivityBinding import com.example.defenseapplication.databinding.DialogWifiListBinding import com.gyf.immersionbar.ImmersionBar +//选择wifi页面 class AddFamilyActivity : AppCompatActivity() { private lateinit var binding: AddFamilyActivityBinding @@ -67,7 +68,7 @@ class AddFamilyActivity : AppCompatActivity() { } } binding.btnConfirm.setOnClickListener { - val intent=Intent(this, SetNameActivity::class.java) + val intent=Intent(this, ConnectDeviceActivity::class.java) startActivity( intent) } } diff --git a/app/src/main/java/com/example/defenseapplication/home/ConnectDeviceActivity.kt b/app/src/main/java/com/example/defenseapplication/home/ConnectDeviceActivity.kt new file mode 100644 index 0000000..6df6f66 --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/home/ConnectDeviceActivity.kt @@ -0,0 +1,109 @@ +package com.example.defenseapplication.home + +import android.content.Intent +import android.graphics.drawable.AnimationDrawable +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.View +import android.widget.Toast +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import com.example.defenseapplication.R +import com.example.defenseapplication.databinding.AddDeviceActivityBinding +import com.example.defenseapplication.databinding.ConnectDeviceActivityBinding +import com.gyf.immersionbar.ImmersionBar + +class ConnectDeviceActivity : AppCompatActivity() { + + private lateinit var binding: ConnectDeviceActivityBinding + private val handler = Handler(Looper.getMainLooper()) + // 每一帧对应的步骤文字和提示 + private val steps = listOf( + StepData("请保持手机蓝牙开启并将手机尽量靠近设备", "向设备传输信息","设备连接网络"), + StepData("请保持手机蓝牙开启并将手机尽量靠近设备", "设备连接网络请将设备尽量靠近路由器",""), + StepData("请将设备尽量靠近路由器", "","") + ) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ConnectDeviceActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + ImmersionBar.with(this) + .statusBarDarkFont(true) + .titleBar(binding.topBar) + .init() + binding.ivBack.setOnClickListener { + finish() + } + startFrameAnimation() + } + private fun startFrameAnimation() { + // 设置动画资源 + binding.ivAnimation.setImageResource(R.drawable.device_wifi_animation) + val animDrawable = binding.ivAnimation.drawable as AnimationDrawable + + // 监听每一帧的切换(AnimationDrawable 没有直接的回调,通过 Handler 定时更新文字) + var frameIndex = 0 + val totalFrames = steps.size + + // 先显示第一帧对应的文字 + updateTextForFrame(0) + + // 开始动画 + animDrawable.start() + + // 每隔对应帧的时长来更新文字(必须与动画中每帧 duration 一致) + val frameDurations = listOf(1500L, 1500L, 1500L) // 与 xml 中的 duration 对应 + val runnable = object : Runnable { + override fun run() { + frameIndex++ + if (frameIndex < totalFrames) { + updateTextForFrame(frameIndex) + handler.postDelayed(this, frameDurations[frameIndex]) + } else { + // 动画播放完毕,进行下一步操作(比如跳转或显示设备列表) + onAnimationComplete() + } + } + } + // 第一帧文字已经显示,所以延迟第一帧时长后再切换到第二帧 + handler.postDelayed(runnable, frameDurations[0]) + } + + private fun updateTextForFrame(index: Int) { + val step = steps[index] + binding.tvStepText.text = step.text + binding.tvHint.text = step.hint + binding.tvDeviceName.text = step.deviceName + } + + private fun onAnimationComplete() { + // 动画结束后的逻辑,显示“扫描完成”并跳转 + // 隐藏原来的动画相关视图 + binding.ivAnimation.visibility = View.GONE + binding.tvStepText.visibility = View.GONE + binding.tvHint.visibility = View.GONE + binding.tvDeviceName.visibility = View.GONE + // 显示图片 + 文字的布局 + val successLayout = binding.successLayout + successLayout.visibility = View.VISIBLE + + // 跳转到下一个界面或关闭当前页面 + // 使用 Handler 延迟跳转 + Handler(Looper.getMainLooper()).postDelayed({ + startActivity(Intent(this, SetNameActivity::class.java)) + finish() + }, 1000) // 1秒后跳转 + } + + data class StepData(val text: String, val hint: String, val deviceName: String) + + override fun onPause() { + super.onPause() + handler.removeCallbacksAndMessages(null) + (binding.ivAnimation.drawable as? AnimationDrawable)?.stop() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt b/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt index 6b49f2d..0da9361 100644 --- a/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/HomeActivity.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import com.example.defenseapplication.R import com.example.defenseapplication.databinding.HomeActivityBinding import com.example.defenseapplication.databinding.HomeMenuFragmentBinding +import com.gyf.immersionbar.ImmersionBar class HomeActivity : AppCompatActivity() { // ViewBinding 核心对象 @@ -23,7 +24,6 @@ class HomeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // 初始化 ViewBinding binding = HomeActivityBinding.inflate(layoutInflater) setContentView(binding.root) 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 ef5bc9d..55f4fcd 100644 --- a/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt +++ b/app/src/main/java/com/example/defenseapplication/home/HomeMenuFragment.kt @@ -21,6 +21,7 @@ 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 @@ -63,6 +64,10 @@ class HomeMenuFragment : Fragment() { savedInstanceState: Bundle? ): View { _binding = HomeMenuFragmentBinding.inflate(inflater, container, false) + ImmersionBar.with(this) + .statusBarDarkFont(true) + .titleBar(binding.main) + .init() initView() return binding.root } diff --git a/app/src/main/java/com/example/defenseapplication/home/MessageActivity.kt b/app/src/main/java/com/example/defenseapplication/home/MessageActivity.kt index 19701a5..63208a7 100644 --- a/app/src/main/java/com/example/defenseapplication/home/MessageActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/MessageActivity.kt @@ -10,7 +10,7 @@ import com.example.defenseapplication.adapter.MessageListAdapter import com.example.defenseapplication.adapter.MessageListItem import com.example.defenseapplication.databinding.MessageActivityBinding import com.gyf.immersionbar.ImmersionBar - +//消息通知页面 class MessageActivity : AppCompatActivity() { private lateinit var binding: MessageActivityBinding private val messageAdapter by lazy { MessageListAdapter() } diff --git a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt index 054c4d0..b8a7993 100644 --- a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt +++ b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt @@ -24,13 +24,11 @@ class PersonalFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - + _binding = PersonalFragmentBinding.inflate(inflater, container, false) ImmersionBar.with(this) .statusBarDarkFont(true) .titleBar(binding.headerLayout) .init() - - _binding = PersonalFragmentBinding.inflate(inflater, container, false) Glide.with(this) .load(R.drawable.img) .circleCrop() diff --git a/app/src/main/java/com/example/defenseapplication/home/ScanActivity.kt b/app/src/main/java/com/example/defenseapplication/home/ScanActivity.kt index bc23892..77faf5d 100644 --- a/app/src/main/java/com/example/defenseapplication/home/ScanActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/ScanActivity.kt @@ -28,7 +28,7 @@ import com.google.zxing.* import com.google.zxing.common.HybridBinarizer import com.gyf.immersionbar.ImmersionBar import java.util.* - +//扫一扫页面 class ScanActivity : AppCompatActivity(), SurfaceHolder.Callback { private lateinit var binding: ScanActivityBinding diff --git a/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt b/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt index fa951dd..2b78583 100644 --- a/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/home/SetNameActivity.kt @@ -4,7 +4,7 @@ import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.example.defenseapplication.databinding.SetNameActivityBinding import com.gyf.immersionbar.ImmersionBar - +//设置名字页面 class SetNameActivity : AppCompatActivity() { private lateinit var binding: SetNameActivityBinding diff --git a/app/src/main/res/drawable/connected_successfully.png b/app/src/main/res/drawable/connected_successfully.png new file mode 100644 index 0000000..0efb6fb Binary files /dev/null and b/app/src/main/res/drawable/connected_successfully.png differ diff --git a/app/src/main/res/drawable/device1.png b/app/src/main/res/drawable/device1.png new file mode 100644 index 0000000..fcb3eee Binary files /dev/null and b/app/src/main/res/drawable/device1.png differ diff --git a/app/src/main/res/drawable/device2.png b/app/src/main/res/drawable/device2.png new file mode 100644 index 0000000..da2f0f0 Binary files /dev/null and b/app/src/main/res/drawable/device2.png differ diff --git a/app/src/main/res/drawable/device3.png b/app/src/main/res/drawable/device3.png new file mode 100644 index 0000000..9ef6e9d Binary files /dev/null and b/app/src/main/res/drawable/device3.png differ diff --git a/app/src/main/res/drawable/device_frame_animation.xml b/app/src/main/res/drawable/device_frame_animation.xml new file mode 100644 index 0000000..575887c --- /dev/null +++ b/app/src/main/res/drawable/device_frame_animation.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/device_wifi_animation.xml b/app/src/main/res/drawable/device_wifi_animation.xml new file mode 100644 index 0000000..03e7ead --- /dev/null +++ b/app/src/main/res/drawable/device_wifi_animation.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/img_add_dev_aini_1.png b/app/src/main/res/drawable/img_add_dev_aini_1.png new file mode 100644 index 0000000..f5636fc Binary files /dev/null and b/app/src/main/res/drawable/img_add_dev_aini_1.png differ diff --git a/app/src/main/res/drawable/img_add_dev_aini_2.png b/app/src/main/res/drawable/img_add_dev_aini_2.png new file mode 100644 index 0000000..7100f4a Binary files /dev/null and b/app/src/main/res/drawable/img_add_dev_aini_2.png differ diff --git a/app/src/main/res/drawable/img_add_dev_aini_3.png b/app/src/main/res/drawable/img_add_dev_aini_3.png new file mode 100644 index 0000000..cb5c625 Binary files /dev/null and b/app/src/main/res/drawable/img_add_dev_aini_3.png differ diff --git a/app/src/main/res/drawable/img_connect_anim_phone1.png b/app/src/main/res/drawable/img_connect_anim_phone1.png new file mode 100644 index 0000000..a272213 Binary files /dev/null and b/app/src/main/res/drawable/img_connect_anim_phone1.png differ diff --git a/app/src/main/res/drawable/img_connect_anim_phone2.png b/app/src/main/res/drawable/img_connect_anim_phone2.png new file mode 100644 index 0000000..26b2ef2 Binary files /dev/null and b/app/src/main/res/drawable/img_connect_anim_phone2.png differ diff --git a/app/src/main/res/drawable/img_connect_anim_phone3.png b/app/src/main/res/drawable/img_connect_anim_phone3.png new file mode 100644 index 0000000..a29bebe Binary files /dev/null and b/app/src/main/res/drawable/img_connect_anim_phone3.png differ diff --git a/app/src/main/res/drawable/img_connect_anim_wifi1.png b/app/src/main/res/drawable/img_connect_anim_wifi1.png new file mode 100644 index 0000000..3763a1a Binary files /dev/null and b/app/src/main/res/drawable/img_connect_anim_wifi1.png differ diff --git a/app/src/main/res/drawable/img_connect_anim_wifi2.png b/app/src/main/res/drawable/img_connect_anim_wifi2.png new file mode 100644 index 0000000..315e076 Binary files /dev/null and b/app/src/main/res/drawable/img_connect_anim_wifi2.png differ diff --git a/app/src/main/res/drawable/img_connect_anim_wifi3.png b/app/src/main/res/drawable/img_connect_anim_wifi3.png new file mode 100644 index 0000000..315e076 Binary files /dev/null and b/app/src/main/res/drawable/img_connect_anim_wifi3.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 a7231ad..b5a0c80 100644 --- a/app/src/main/res/layout/add_device_activity.xml +++ b/app/src/main/res/layout/add_device_activity.xml @@ -5,7 +5,7 @@ android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/white" + android:background="@color/message_bg" tools:context=".home.AddDeviceActivity"> - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/set_name_activity.xml b/app/src/main/res/layout/set_name_activity.xml index b330634..027ebf5 100644 --- a/app/src/main/res/layout/set_name_activity.xml +++ b/app/src/main/res/layout/set_name_activity.xml @@ -75,7 +75,8 @@ 连接中... WiFi连接失败 WiFi连接成功 + 连接设备 提示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 50eaf27..210239b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -207,6 +207,7 @@ Connecting... WiFi Connection failed WiFi Connected successfully + Connect Device Tip