添加了界面及逻辑

This commit is contained in:
zxj
2025-07-18 17:16:00 +08:00
parent b68c967d82
commit f97ef151c3
74 changed files with 3108 additions and 34 deletions
@@ -1,36 +1,39 @@
package com.sw.platecabinet.activity
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.WindowManager
import android.text.TextUtils
import android.view.View
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.sw.inbound.utils.DateTimeUtils
import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.ext.setClickListeners
import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.view.CustomDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import timber.log.Timber
/**
* activity 基类
*/
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
protected lateinit var binding: VB
private set
private var headerBinding: ItemTitleTimeBinding? = null
protected lateinit var context: Context
private var timeJob: Job? = null
private var mDialogWaiting: CustomDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
context = this
binding = inflateViewBinding()
headerBinding = inflateTitleBinding()
@@ -41,6 +44,11 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
fun updateTime() {
headerBinding?.let {
headerBinding!!.tvRightTime.setClickListeners(
onDoubleClick = {
MainActivity.start(context, pageType = PageType.SETTING_LIST)
}
)
val scope = CoroutineScope(Dispatchers.Main)
timeJob = scope.launch {
DateTimeUtils.realTimeChineseDateFlow()
@@ -52,6 +60,45 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
// 统一处理权限拒绝情况
val allGranted = PermissionHelper.handlePermissionResult(
this,
requestCode,
permissions,
grantResults
) { permanentlyDeniedPermissions ->
// 权限被永久拒绝的统一处理
Timber.e("用户永久拒绝权限 $permanentlyDeniedPermissions")
}
}
/**
* 显示等待提示框
*/
fun showWaitingDialog(tip: String?): Dialog? {
hideWaitingDialog()
val view = View.inflate(this, R.layout.dialog_waiting, null)
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).setText(tip)
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog)
mDialogWaiting!!.show()
mDialogWaiting!!.setCancelable(true)
return mDialogWaiting
}
/**
* 隐藏等待提示框
*/
fun hideWaitingDialog() {
mDialogWaiting?.dismiss()
mDialogWaiting = null
}
protected abstract fun inflateViewBinding(): VB
protected abstract fun inflateTitleBinding(): ItemTitleTimeBinding?
@@ -1,9 +1,11 @@
package com.sw.platecabinet.activity
import android.Manifest
import android.content.Intent
import android.graphics.Outline
import android.view.View
import android.view.ViewOutlineProvider
import androidx.activity.viewModels
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
@@ -11,6 +13,8 @@ import androidx.core.content.ContextCompat
import com.google.common.util.concurrent.ListenableFuture
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.viewmodel.UserViewModel
import timber.log.Timber
/**
@@ -18,6 +22,10 @@ import timber.log.Timber
*/
class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>() {
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
private val viewModel by viewModels<UserViewModel>()
private val CAMERA_PERMISSION_REQUEST_CODE = 100
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
override fun inflateViewBinding(): ActivityLoginFaceBinding {
return ActivityLoginFaceBinding.inflate(layoutInflater)
@@ -28,14 +36,25 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>() {
}
override fun initialize() {
// 请求权限
checkCameraPermission()
initView()
startCamera()
viewModel.generateToken()
binding.llToPwd.setOnClickListener {
val intent = Intent(this, LoginByPwdActivity::class.java)
startActivity(intent)
}
}
private fun checkCameraPermission() {
PermissionHelper.with(this, REQUIRED_PERMISSIONS, CAMERA_PERMISSION_REQUEST_CODE)
.onGranted {
// 权限已授予
startCamera()
}
.checkAndRequest()
}
private fun initView() {
binding.previewView.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
@@ -14,6 +14,9 @@ class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
}
override fun initialize() {
binding.btnLogin.setOnClickListener {
MainActivity.start(context, pageType = PageType.PLATE_CABINET_FULL)
}
binding.tvFaceRec.setOnClickListener {
val intent = Intent(this, LoginByFaceActivity::class.java)
startActivity(intent)
@@ -1,9 +1,20 @@
package com.sw.platecabinet.activity
import android.content.Context
import android.content.Intent
import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ActivityMainBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.fragment.BindPlateFragment
import com.sw.platecabinet.fragment.PlateCabinetFullFragment
import com.sw.platecabinet.fragment.PlateOpenFragment
import com.sw.platecabinet.fragment.SettingListFragment
import com.sw.platecabinet.fragment.UnBindPlateFragment
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.FragmentHelper
class MainActivity : BaseActivity<ActivityMainBinding>() {
private lateinit var fragmentHelper: FragmentHelper
override fun inflateViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater)
@@ -13,7 +24,65 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
return binding.includeHeader
}
override fun initialize() {
// 静态启动方法
companion object {
private const val PARAM_PAGE_TYPE = "pageType"
private const val PARAM_EQUIPMENT_INFO = "equipmentUserInfo"
fun start(
context: Context,
pageType: PageType,
equipmentUserInfo: EquipmentUserInfo? = null
) {
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(PARAM_PAGE_TYPE, pageType.name)
intent.putExtra(PARAM_EQUIPMENT_INFO, equipmentUserInfo)
context.startActivity(intent)
}
}
}
override fun initialize() {
val param = intent.getStringExtra(PARAM_PAGE_TYPE)
val equipmentUserInfo = intent.getParcelableExtra<EquipmentUserInfo>(PARAM_EQUIPMENT_INFO)
val pageType = param?.let { PageType.valueOf(param) } ?: PageType.SETTING_LIST
fragmentHelper = FragmentHelper(supportFragmentManager, R.id.fragment_container)
val page = when (pageType) {
PageType.SETTING_LIST -> SettingListFragment()
PageType.BIND_PLATE -> BindPlateFragment.newInstance(equipmentUserInfo)
PageType.PLATE_OPEN -> PlateOpenFragment()
PageType.UNBIND_PLATE -> UnBindPlateFragment.newInstance(equipmentUserInfo)
PageType.PLATE_CABINET_FULL -> PlateCabinetFullFragment()
}
fragmentHelper.addFragment(page)
}
}
/**
* 界面类型
*/
enum class PageType {
/**
* 餐盘柜打开
*/
PLATE_OPEN,
/**
* 设置列表
*/
SETTING_LIST,
/**
* 绑定餐盘
*/
BIND_PLATE,
/**
* 解绑餐盘
*/
UNBIND_PLATE,
/**
* 餐盘柜已满
*/
PLATE_CABINET_FULL
}
@@ -0,0 +1,97 @@
package com.sw.platecabinet.activity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.sw.platecabinet.R
import kotlin.math.ceil
class TestActivity : AppCompatActivity() {
private lateinit var parentRecyclerView: RecyclerView
private lateinit var pageAdapter: PageAdapter
private val itemsPerPage = 22 // 每行2个,每列11个,共22个
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)
parentRecyclerView = findViewById(R.id.parentRecyclerView)
parentRecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
// 假设有100个数据项
val allItems = (1..30).map { "Item $it" }
val pages = allItems.chunked(itemsPerPage)
pageAdapter = PageAdapter(pages)
parentRecyclerView.adapter = pageAdapter
}
private fun convertToColumnFirst(original: List<String>, cols: Int): List<String> {
val rows = ceil(original.size.toDouble() / cols).toInt()
return List(original.size) { pos ->
val row = pos % rows
val col = pos / rows
val originalPos = col + row * cols
original.getOrElse(originalPos) { "" }
}
}
inner class PageAdapter(private val pages: List<List<String>>) :
RecyclerView.Adapter<PageAdapter.PageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.page_item_layout, parent, false)
return PageViewHolder(view)
}
override fun onBindViewHolder(holder: PageViewHolder, position: Int) {
holder.bind(pages[position])
}
override fun getItemCount(): Int = pages.size
inner class PageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val childRecyclerView: RecyclerView =
itemView.findViewById(R.id.childRecyclerView)
fun bind(items: List<String>) {
childRecyclerView.layoutManager = GridLayoutManager(itemView.context, 2)
childRecyclerView.adapter = ChildAdapter(items)
}
}
}
inner class ChildAdapter(private val items: List<String>) :
RecyclerView.Adapter<ChildAdapter.ItemViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_bind_view, parent, false)
return ItemViewHolder(view)
}
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.bind(position, items[position])
}
override fun getItemCount(): Int = items.size
inner class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val llRoot: LinearLayout = itemView.findViewById(R.id.ll_root)
private val tvNum: TextView = itemView.findViewById(R.id.tv_num)
fun bind(position: Int, item: String) {
tvNum.text = item
llRoot.setBackgroundResource(if (position % 3 == 0) R.drawable.grid_item_bind else R.drawable.grid_item_unbind)
}
}
}
}