feat(activity): 新增 BaseActivity 沉浸式基类和 HomeActivity 首页,统一 Activity 继承关系
- 新增 BaseActivity:继承 ComponentActivity,隐藏状态栏和导航栏,底部上滑可临时唤出导航栏 - 新增 HomeActivity(XML 版本)及对应布局 activity_home.xml,作为应用启动入口 - GoodsListActivity、FoodCollectionActivity、LocalImagePreviewActivity、PurchaseOrderActivity 统一改为继承 BaseActivity - 更新 AndroidManifest.xml:HomeActivity 注册为启动入口 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".activity.HomeActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
@@ -59,6 +59,10 @@
|
||||
android:windowSoftInputMode="adjustPan" />
|
||||
<activity android:name="com.sw.inbound.activity.LocalImagePreviewActivity" />
|
||||
<activity android:name="com.sw.inbound.activity.PurchaseOrderActivity" />
|
||||
<!-- 首页 Activity(XML 版本,对应 HomeScreen.kt Compose 版本) -->
|
||||
<activity
|
||||
android:name="com.sw.inbound.MainActivity"
|
||||
android:screenOrientation="landscape" />
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".InitActivity"-->
|
||||
|
||||
@@ -10,7 +10,7 @@ import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.sw.inbound.base.BaseActivity
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.view.updateLayoutParams
|
||||
@@ -68,7 +68,7 @@ import java.io.File
|
||||
*/
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
@AndroidEntryPoint
|
||||
class FoodCollectionActivity : ComponentActivity() {
|
||||
class FoodCollectionActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "FoodCollectionActivity"
|
||||
|
||||
@@ -9,7 +9,7 @@ import android.text.style.ForegroundColorSpan
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.sw.inbound.base.BaseActivity
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.view.PreviewView
|
||||
@@ -70,7 +70,7 @@ import kotlin.math.min
|
||||
typealias RecognizeCallback = (List<SearchGoodsInfo.Record>) -> Unit
|
||||
|
||||
@AndroidEntryPoint
|
||||
abstract class GoodsListActivity : ComponentActivity() {
|
||||
abstract class GoodsListActivity : BaseActivity() {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "GoodsListActivity"
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.sw.inbound.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.activity.viewModels
|
||||
import com.sw.inbound.base.BaseActivity
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.sw.inbound.databinding.ActivityHomeBinding
|
||||
import com.sw.inbound.model.response.User
|
||||
import com.sw.inbound.objbox.FoodModule
|
||||
import com.sw.inbound.sdk.SensorScaleUtils
|
||||
import com.sw.inbound.utils.DateTimeUtils
|
||||
import com.sw.inbound.utils.ThreadUtils
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.startActivity
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
import com.sw.inbound.viewmodel.UserViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* 首页 Activity(XML 版本)
|
||||
* 对应原 HomeScreen.kt Compose 版本,原文件保留不动
|
||||
* 功能:展示标题栏(含实时时间或用户信息)和两个功能入口(采购单入库、自采入库)
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class HomeActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityHomeBinding
|
||||
|
||||
/** 用于获取用户信息的 ViewModel */
|
||||
private val viewModel: UserViewModel by viewModels()
|
||||
|
||||
/** 每秒刷新当前时间的 Handler */
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
/** 时间刷新任务,每 1 秒更新一次标题栏右侧时间文字 */
|
||||
private val timeRunnable = object : Runnable {
|
||||
override fun run() {
|
||||
binding.tvTime.text = DateTimeUtils.getChineseDateString()
|
||||
handler.postDelayed(this, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityHomeBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
initViews()
|
||||
observeUser()
|
||||
SensorScaleUtils.startScale(autoScale = true)
|
||||
lifecycleScope.launch {
|
||||
FoodModule.init(this@HomeActivity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
SensorScaleUtils.closeScale()
|
||||
ThreadUtils.release()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化各控件的点击事件
|
||||
*/
|
||||
private fun initViews() {
|
||||
// 标题点击:跳转菜品采集页面
|
||||
binding.tvTitle.setOnClickListener {
|
||||
startActivity<FoodCollectionActivity>()
|
||||
}
|
||||
|
||||
// 采购单入库入口
|
||||
binding.ivOrderPurchase.setOnClickListener {
|
||||
startActivity<PurchaseOrderActivity>()
|
||||
}
|
||||
|
||||
// 自采入库入口,传入非采购单标志
|
||||
binding.ivOrderSelfProcurement.setOnClickListener {
|
||||
startActivity<SelfProcurementActivity> {
|
||||
putExtra(GoodsListActivity.IS_RECEIPT_PAGE, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 观察用户登录状态,动态切换标题栏右侧显示内容:
|
||||
* - 已登录:显示用户名 + 退出图标
|
||||
* - 未登录:显示实时时间
|
||||
*/
|
||||
private fun observeUser() {
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
viewModel.user.collect { user ->
|
||||
updateUserView(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据登录状态切换标题栏右侧 UI
|
||||
* @param user 当前用户信息,为 null 表示未登录
|
||||
*/
|
||||
private fun updateUserView(user: User?) {
|
||||
if (user != null) {
|
||||
// 已登录:显示用户名和退出图标,隐藏时间
|
||||
binding.tvTime.gone()
|
||||
binding.llUserInfo.visible()
|
||||
binding.tvUserName.text = user.name ?: "用户"
|
||||
} else {
|
||||
// 未登录:显示实时时间,隐藏用户信息
|
||||
binding.llUserInfo.gone()
|
||||
binding.tvTime.visible()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// 页面可见时启动时间刷新
|
||||
handler.post(timeRunnable)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
// 页面不可见时停止刷新,避免内存泄漏
|
||||
handler.removeCallbacks(timeRunnable)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.sw.inbound.base.BaseActivity
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import coil.load
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
@@ -15,7 +15,7 @@ import com.sw.inbound.dialog.Loading
|
||||
import com.sw.inbound.utils.ext.copyText
|
||||
import java.io.File
|
||||
|
||||
class LocalImagePreviewActivity : ComponentActivity() {
|
||||
class LocalImagePreviewActivity : BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityLocalImagePreviewBinding
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.sw.inbound.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.sw.inbound.base.BaseActivity
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@@ -24,7 +24,7 @@ import kotlinx.coroutines.launch
|
||||
* 采购单列表
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class PurchaseOrderActivity : ComponentActivity() {
|
||||
class PurchaseOrderActivity : BaseActivity() {
|
||||
|
||||
private var list = mutableListOf<SupplierInfo>()
|
||||
private val adapter by lazy {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.sw.inbound.base
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
|
||||
/**
|
||||
* 所有 Activity 的基类
|
||||
* - 继承 ComponentActivity,保持与项目其他 Activity 一致
|
||||
* - 自动隐藏状态栏和导航栏,实现全屏沉浸式体验
|
||||
* - 在屏幕底部上滑时可临时唤出导航栏,松手后自动收回
|
||||
*/
|
||||
abstract class BaseActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
hideSystemBars()
|
||||
}
|
||||
|
||||
/**
|
||||
* 窗口焦点变化时回调
|
||||
* 场景:弹出 Dialog 后焦点丢失,Dialog 消失后焦点恢复,此时需重新隐藏系统栏,
|
||||
* 避免系统栏在 Dialog 关闭后意外"复活"
|
||||
*/
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
if (hasFocus) {
|
||||
hideSystemBars()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏状态栏和导航栏
|
||||
* 使用 WindowInsetsControllerCompat(Androidx 推荐方式,向下兼容性好)
|
||||
* - 状态栏:完全隐藏
|
||||
* - 导航栏:完全隐藏,底部上滑时临时出现,松手后自动收回(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE)
|
||||
*/
|
||||
private fun hideSystemBars() {
|
||||
// 允许布局延伸到系统栏区域(edge-to-edge),避免内容被系统栏遮挡
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
WindowInsetsControllerCompat(window, window.decorView).apply {
|
||||
// 同时隐藏状态栏和导航栏
|
||||
hide(WindowInsetsCompat.Type.systemBars())
|
||||
// 底部上滑时临时显示导航栏,松手后自动隐藏(沉浸式 Sticky 模式)
|
||||
systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@mipmap/bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 标题栏区域,与 TopTitleBar Compose 组件对应 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="60dp"
|
||||
android:paddingEnd="60dp"
|
||||
android:paddingTop="22dp">
|
||||
|
||||
<!-- 标题文字,点击可跳转菜品采集页面 -->
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="出入库管理"
|
||||
android:textColor="@color/title"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<!-- 占位弹性空间 -->
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<!-- 当前时间文字(用户未登录时显示) -->
|
||||
<TextView
|
||||
android:id="@+id/tvTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="24sp"
|
||||
android:visibility="visible" />
|
||||
|
||||
<!-- 用户信息区(已登录时显示,未登录隐藏) -->
|
||||
<LinearLayout
|
||||
android:id="@+id/llUserInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUserName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<Space
|
||||
android:layout_width="21dp"
|
||||
android:layout_height="1dp" />
|
||||
|
||||
<!-- 退出登录图标 -->
|
||||
<ImageView
|
||||
android:id="@+id/ivLogout"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:contentDescription="退出"
|
||||
android:src="@mipmap/ic_logout" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 功能入口区域,水平居中排列两个入口图标 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- 采购单入库入口 -->
|
||||
<ImageView
|
||||
android:id="@+id/ivOrderPurchase"
|
||||
android:layout_width="595dp"
|
||||
android:layout_height="477dp"
|
||||
android:contentDescription="采购单入库"
|
||||
android:src="@mipmap/ic_order_purchase" />
|
||||
|
||||
<Space
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="1dp" />
|
||||
|
||||
<!-- 自采入库入口 -->
|
||||
<ImageView
|
||||
android:id="@+id/ivOrderSelfProcurement"
|
||||
android:layout_width="595dp"
|
||||
android:layout_height="477dp"
|
||||
android:contentDescription="自采入库"
|
||||
android:src="@mipmap/ic_order_self_procurement" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user