添加了界面及逻辑

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
@@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.flow
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.math.abs
/**
* 时间格式化工具类
@@ -47,4 +48,66 @@ object DateTimeUtils {
delay(intervalMillis)
}
}
/**
* 解析日期时间字符串
* @param timeString 格式为 "yyyy-MM-dd HH:mm:ss" 的字符串
* @return Date 对象,解析失败返回 null
*/
fun parseDateTime(timeString: String?): Date? {
return try {
if (timeString == null) return null
val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
format.parse(timeString)
} catch (e: Exception) {
e.printStackTrace()
null
}
}
/**
* 判断给定时间是否距离当前时间超过36小时
* @param timeInMillis 时间戳(毫秒)
* @return true 表示超过36小时,false 表示未超过
*/
fun isMoreThan36HoursFromNow(timeInMillis: Long): Boolean {
val currentTime = System.currentTimeMillis()
val timeDifference = currentTime - timeInMillis
val hoursDifference = timeDifference / (1000 * 60 * 60) // 毫秒转小时
return hoursDifference >= 36
}
/**
* 获取时间间隔描述
*/
fun getTimeAgo(date: Date?): String {
if (date == null) return "未知时间"
val now = Date()
val diffMillis = now.time - date.time
// 如果是未来时间
if (diffMillis < 0) {
val futureHours = abs(diffMillis) / (1000 * 60 * 60)
return if (futureHours < 24) {
"未来 $futureHours 小时"
} else {
val days = futureHours / 24
"未来 $days"
}
}
// 过去时间
val hours = diffMillis / (1000 * 60 * 60)
return when {
hours < 1 -> "刚刚"
hours < 24 -> "${hours}小时前"
// hours < 48 -> "昨天"
// hours < 72 -> "前天"
else -> {
val days = hours / 24
"${days}天前"
}
}
}
}
@@ -0,0 +1,141 @@
package com.sw.platecabinet.utils
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
class FragmentHelper(
private val fragmentManager: FragmentManager,
private val containerId: Int
) {
/**
* 添加Fragment到容器中
* @param fragment 要添加的Fragment
* @param addToBackStack 是否添加到返回栈
* @param tag Fragment的标签
*/
fun addFragment(fragment: Fragment, addToBackStack: Boolean = false, tag: String? = null) {
fragmentManager.beginTransaction().apply {
add(containerId, fragment, tag)
if (addToBackStack) {
addToBackStack(tag)
}
commit()
}
}
/**
* 替换容器中的Fragment
* @param fragment 要替换的Fragment
* @param addToBackStack 是否添加到返回栈
* @param tag Fragment的标签
* @param animEnter 进入动画
* @param animExit 退出动画
* @param animPopEnter 弹出进入动画
* @param animPopExit 弹出退出动画
*/
fun replaceFragment(
fragment: Fragment,
addToBackStack: Boolean = true,
tag: String? = null,
animEnter: Int = 0,
animExit: Int = 0,
animPopEnter: Int = 0,
animPopExit: Int = 0
) {
fragmentManager.beginTransaction().apply {
if (animEnter != 0 || animExit != 0 || animPopEnter != 0 || animPopExit != 0) {
setCustomAnimations(animEnter, animExit, animPopEnter, animPopExit)
}
replace(containerId, fragment, tag)
if (addToBackStack) {
addToBackStack(tag)
}
commit()
}
}
/**
* 显示Fragment
* @param fragment 要显示的Fragment
*/
fun showFragment(fragment: Fragment) {
fragmentManager.beginTransaction()
.show(fragment)
.commit()
}
/**
* 隐藏Fragment
* @param fragment 要隐藏的Fragment
*/
fun hideFragment(fragment: Fragment) {
fragmentManager.beginTransaction()
.hide(fragment)
.commit()
}
/**
* 移除Fragment
* @param fragment 要移除的Fragment
*/
fun removeFragment(fragment: Fragment) {
fragmentManager.beginTransaction()
.remove(fragment)
.commit()
}
/**
* 返回上一个Fragment
* @return 是否成功返回
*/
fun popBackStack(): Boolean {
return fragmentManager.popBackStackImmediate()
}
/**
* 返回到指定的Fragment
* @param tag Fragment的标签
* @param inclusive 是否包含指定的Fragment
*/
fun popBackStackTo(tag: String, inclusive: Boolean = false): Boolean {
return fragmentManager.popBackStackImmediate(
tag,
if (inclusive) FragmentManager.POP_BACK_STACK_INCLUSIVE else 0
)
}
/**
* 获取当前显示的Fragment
*/
fun getCurrentFragment(): Fragment? {
return fragmentManager.findFragmentById(containerId)
}
/**
* 通过tag查找Fragment
*/
fun findFragmentByTag(tag: String): Fragment? {
return fragmentManager.findFragmentByTag(tag)
}
/**
* 清除所有Fragment
*/
fun clearAllFragments() {
// 清除所有回退栈中的Fragment
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
// 清除所有已添加的Fragment
fragmentManager.fragments.forEach { fragment ->
removeFragment(fragment)
}
}
/**
* 检查返回栈是否为空
*/
fun isBackStackEmpty(): Boolean {
return fragmentManager.backStackEntryCount == 0
}
}
@@ -0,0 +1,156 @@
package com.sw.platecabinet.utils
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
class PermissionHelper private constructor(
private val context: Context,
private val permissions: Array<String>,
private val requestCode: Int,
private val rationale: String? = null
) {
private var onGranted: (() -> Unit)? = null
companion object {
/**
* 创建权限请求构建器
* @param context 上下文(Activity或Fragment
* @param permissions 需要请求的权限数组
* @param requestCode 请求码
*/
fun with(context: Context, permissions: Array<String>, requestCode: Int): Builder {
return Builder(context, permissions, requestCode)
}
/**
* 检查是否已授予所有权限
*/
fun areAllPermissionsGranted(context: Context, permissions: Array<String>): Boolean {
return permissions.all { permission ->
ContextCompat.checkSelfPermission(
context,
permission
) == PackageManager.PERMISSION_GRANTED
}
}
/**
* 处理权限请求结果(供BaseActivity/BaseFragment调用)
*/
fun handlePermissionResult(
context: Context,
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray,
onPermissionPermanentlyDenied: (List<String>) -> Unit
): Boolean {
if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
return true
}
val permanentlyDeniedPermissions = mutableListOf<String>()
permissions.forEachIndexed { index, permission ->
if (grantResults[index] != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(
context as Activity,
permission
)
) {
permanentlyDeniedPermissions.add(permission)
}
}
}
if (permanentlyDeniedPermissions.isNotEmpty()) {
onPermissionPermanentlyDenied(permanentlyDeniedPermissions)
}
return false
}
/**
* 跳转到应用设置页面
*/
fun openAppSettings(context: Context) {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", context.packageName, null)
}
if (context is Activity) {
context.startActivity(intent)
} else if (context is Fragment) {
context.startActivity(intent)
}
}
}
class Builder(
private val context: Context,
private val permissions: Array<String>,
private val requestCode: Int
) {
private var rationale: String? = null
/**
* 设置权限说明(当需要向用户解释权限用途时显示)
*/
fun setRationale(rationale: String): Builder {
this.rationale = rationale
return this
}
/**
* 设置权限授予回调
*/
fun onGranted(callback: () -> Unit): PermissionHelper {
val helper = PermissionHelper(context, permissions, requestCode, rationale)
helper.onGranted = callback
return helper
}
}
/**
* 检查并请求权限
*/
fun checkAndRequest() {
if (areAllPermissionsGranted(context, permissions)) {
onGranted?.invoke()
} else {
requestPermissions()
}
}
private fun requestPermissions() {
val activity = context as? Activity ?: return
// 检查是否需要显示权限说明
val shouldShowRationale = permissions.any { permission ->
ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
}
if (shouldShowRationale && rationale != null) {
// 显示解释对话框
AlertDialog.Builder(activity)
.setTitle("权限说明")
.setMessage(rationale)
.setPositiveButton("确定") { _, _ ->
doRequestPermissions(activity)
}
.setNegativeButton("取消", null)
.show()
} else {
// 直接请求权限
doRequestPermissions(activity)
}
}
private fun doRequestPermissions(activity: Activity) {
ActivityCompat.requestPermissions(activity, permissions, requestCode)
}
}