cloudroam
2025-04-11 cb99bd7dad1b305a434c5c6c99ca65e782eb0f34
add: 消息提醒
已修改13个文件
已添加7个文件
581 ■■■■ 文件已修改
app/src/main/AndroidManifest.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/App.kt 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/adapter/ReminderRecordAdapter.kt 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/service/ApiService.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/service/ReminderWorker.kt 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/ReminderRecordViewModel.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder_delete.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder_express.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder_finance.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder_flight.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder_income.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/reminder_train.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_reminder_list.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_home.xml 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_reminder_record.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/dimens.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml
@@ -145,6 +145,16 @@
            android:name=".ui.invitation.InvitationActivity"
            android:exported="false"/>
        <activity
            android:name=".activity.ReminderListActivity"
            android:exported="false"
            android:label="提醒列表" />
        <activity
            android:name=".activity.ReminderSettingsActivity"
            android:exported="false"
            android:label="设置提醒" />
    </application>
</manifest>
app/src/main/java/com/example/firstapp/App.kt
@@ -37,6 +37,7 @@
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
@Suppress("DEPRECATION")
class App : Application(), CactusCallback, Configuration.Provider {
@@ -455,6 +456,7 @@
    private fun setupReminderWorker() {
        Log.d(TAG, "设置定时提醒Worker")
        
        // 方式1:使用周期性执行
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
@@ -474,6 +476,18 @@
            ExistingPeriodicWorkPolicy.REPLACE,
            reminderWorkRequest
        )
        // 方式2:设置在特定时间执行(例如每天上午9点和下午18点)
        // 可根据需要设置多个不同时间点的提醒
        ReminderWorker.setupScheduledWorker(this, 9, 0)  // 上午9:00
        ReminderWorker.setupScheduledWorker(this, 13, 50) // 下午18:00
        // 注意:不再立即执行一次提醒检查,避免重复提醒
        // 如果需要立即检查,可以设置一个延迟,例如5分钟后执行
        val delayedWorkRequest = OneTimeWorkRequestBuilder<ReminderWorker>()
            .setInitialDelay(5, TimeUnit.MINUTES)  // 延迟5分钟执行
            .build()
        WorkManager.getInstance(this).enqueue(delayedWorkRequest)
    }
}
app/src/main/java/com/example/firstapp/activity/ReminderListActivity.kt
@@ -11,11 +11,19 @@
import com.example.firstapp.databinding.ActivityReminderListBinding
import com.example.firstapp.ui.dashboard.ReminderRecordViewModel
import kotlinx.coroutines.launch
import android.widget.Toast
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import android.graphics.Color
import android.view.Gravity
import android.util.TypedValue
class ReminderListActivity : AppCompatActivity() {
    private lateinit var binding: ActivityReminderListBinding
    private lateinit var viewModel: ReminderRecordViewModel
    private lateinit var adapter: ReminderRecordAdapter
    private var unreadBadge: TextView? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
@@ -26,7 +34,40 @@
        setupRecyclerView()
        setupClickListeners()
//        setupUnreadBadge()  消息列表页面不使用小红点
        observeRecords()
        // 检查未读消息数量
        checkUnreadMessages()
    }
    private fun setupUnreadBadge() {
        // 创建未读消息数量的小红点
        unreadBadge = TextView(this).apply {
            setBackgroundResource(android.R.color.holo_red_light)
            setTextColor(Color.WHITE)
            gravity = Gravity.CENTER
            textSize = 10f
            setPadding(8, 2, 8, 2)
            // 设置圆角背景
            val outValue = TypedValue()
            context.theme.resolveAttribute(
                android.R.attr.selectableItemBackgroundBorderless, outValue, true
            )
            setBackgroundResource(outValue.resourceId)
            setBackgroundColor(Color.RED)
        }
        // 添加到布局中
        (binding.clearReadMessagesButton.parent as ViewGroup).addView(unreadBadge)
        // 调整位置到已读按钮右上角
        (unreadBadge?.layoutParams as? FrameLayout.LayoutParams)?.apply {
            gravity = Gravity.TOP or Gravity.END
            topMargin = 8
            rightMargin = 8
        }
    }
    private fun setupRecyclerView() {
@@ -34,6 +75,7 @@
            // 点击提醒记录时,标记为已读
            lifecycleScope.launch {
                viewModel.updateRecordStatus(record.id, ReminderRecord.STATUS_READ)
                checkUnreadMessages()
            }
        }
        binding.reminderRecyclerView.apply {
@@ -46,11 +88,56 @@
        binding.addReminderButton.setOnClickListener {
            startActivity(Intent(this, ReminderSettingsActivity::class.java))
        }
    }
        // 添加已读按钮点击事件
        binding.clearReadMessagesButton.setOnClickListener {
            lifecycleScope.launch {
                // 将所有未读消息标记为已读
                adapter.currentList.forEach { record ->
                    if (record.status == ReminderRecord.STATUS_UNREAD) {
                        viewModel.updateRecordStatus(record.id, ReminderRecord.STATUS_READ)
                    }
                }
                Toast.makeText(
                    this@ReminderListActivity, "所有消息已标记为已读", Toast.LENGTH_SHORT
                ).show()
                checkUnreadMessages()
            }
        }
    }
    // 观察提醒记录列表
    private fun observeRecords() {
        viewModel.reminderRecords.observe(this) { records ->
            adapter.submitList(records)
            checkUnreadMessages()
        }
    }
    private fun checkUnreadMessages() {
        lifecycleScope.launch {
            val unreadCount = viewModel.getUnreadCount()
            // 更新未读消息数量徽章
            if (unreadCount > 0) {
                unreadBadge?.apply {
                    text = if (unreadCount > 99) "99+" else unreadCount.toString()
                    visibility = android.view.View.VISIBLE
                }
            } else {
                unreadBadge?.visibility = android.view.View.GONE
            }
        }
    }
    override fun onResume() {
        super.onResume()
        // 每次恢复活动时检查未读消息
        checkUnreadMessages()
    }
    override fun onPause() {
        super.onPause()
        // 发送广播通知HomeFragment更新未读提醒数量
        sendBroadcast(Intent("com.example.firstapp.REMINDER_UPDATED"))
    }
app/src/main/java/com/example/firstapp/adapter/ReminderRecordAdapter.kt
@@ -45,17 +45,23 @@
        fun bind(record: ReminderRecord) {
            binding.apply {
                categoryNameText.text = record.categoryName
                // 设置图标
                // 根据提醒类别设置不同图标
                val iconResource = when (record.categoryId) {
                    1 -> R.drawable.reminder_express  // 快递
                    2 -> R.drawable.reminder_finance  // 还款
                    3 -> R.drawable.reminder_income   // 收入
                    4 -> R.drawable.reminder_flight   // 航班
                    5 -> R.drawable.reminder_train    // 火车票
                    else -> R.drawable.reminder_express  // 默认使用快递图标
                }
                categoryIcon.setImageResource(iconResource)
                contentText.text = record.content
                timeText.text = dateFormat.format(Date(record.createdAt))
                
                // 设置状态图标
                statusIcon.setImageResource(
                    if (record.status == ReminderRecord.STATUS_UNREAD)
                        R.drawable.ic_reminder
                    else
                        R.drawable.ic_add
                )
                // 保留已读/未读状态的视觉区分,现在仅通过整体项目透明度区分
                val alpha = if (record.status == ReminderRecord.STATUS_UNREAD) 1.0f else 0.7f
                root.alpha = alpha
            }
        }
    }
app/src/main/java/com/example/firstapp/database/service/ApiService.kt
@@ -78,7 +78,7 @@
// 创建Retrofit实例(单例)
object RetrofitClient{
//    private const val BASE_URL ="http://192.168.1.198:8080/flower/"
 //   private const val BASE_URL ="http://192.168.1.213:8080/flower/"
    private const val BASE_URL ="http://14.103.144.28:8080/flower/"
app/src/main/java/com/example/firstapp/service/ReminderWorker.kt
@@ -7,6 +7,7 @@
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.work.*
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.example.firstapp.MainActivity
@@ -21,6 +22,7 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import java.util.Calendar
import java.util.concurrent.TimeUnit
/**
@@ -38,23 +40,23 @@
    override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
        android.util.Log.d("ReminderWorker", "doWork 开始执行")
        try {
            // 强制发送一条测试通知(确认Worker是否执行)
            // sendTestNotification()
            android.util.Log.d("ReminderWorker", "发送测试通知确认Worker已执行")
            // 获取所有提醒设置
            val reminderList = reminderRepository.getAllReminders().first()
            android.util.Log.d("ReminderWorker", "获取到 ${reminderList.size} 条提醒设置")
            
            if (reminderList.isEmpty()) {
                // 测试用:如果没有数据,也发送一条测试通知
                sendTestNotification()
                android.util.Log.d("ReminderWorker", "数据为空,发送了测试通知")
            }
            for (reminder in reminderList) {
                try {
                    android.util.Log.d("ReminderWorker", "处理提醒: ${reminder.categoryName}")
                    checkCategoryContent(reminder.categoryId, reminder.categoryName, reminder.notificationMethod)
                } catch (e: Exception) {
                    e.printStackTrace()
                    android.util.Log.e("ReminderWorker", "处理提醒失败: ${e.message}")
            if (reminderList.isNotEmpty()) {
                for (reminder in reminderList) {
                    try {
                        android.util.Log.d("ReminderWorker", "处理提醒: ${reminder.categoryName}")
                        checkCategoryContent(reminder.categoryId, reminder.categoryName, reminder.notificationMethod)
                    } catch (e: Exception) {
                        e.printStackTrace()
                        android.util.Log.e("ReminderWorker", "处理提醒失败: ${e.message}")
                    }
                }
            }
            
@@ -232,12 +234,40 @@
    companion object {
        private const val CHANNEL_ID = "reminder_channel"
        
        // 定时任务执行频率 - 设置为每天运行一次
        val REPEAT_INTERVAL = 24L   // 每24小时运行一次
        val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.HOURS
        // 测试用的频率配置,已注释掉
        // val REPEAT_INTERVAL = 2L
        // val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.MINUTES
        // 定时任务执行频率 - 可选不同配置
        val REPEAT_INTERVAL = 15L  // 设置为每15分钟运行一次
        val REPEAT_INTERVAL_TIME_UNIT = TimeUnit.MINUTES
        // 创建在指定时间运行的定时任务
        fun setupScheduledWorker(context: Context, hour: Int, minute: Int) {
            val calendar = Calendar.getInstance()
            val now = Calendar.getInstance()
            calendar.set(Calendar.HOUR_OF_DAY, hour)
            calendar.set(Calendar.MINUTE, minute)
            calendar.set(Calendar.SECOND, 0)
            // 如果设定时间已经过了,则设置为明天这个时间
            if (calendar.timeInMillis < now.timeInMillis) {
                calendar.add(Calendar.DAY_OF_MONTH, 1)
            }
            // 计算初始延迟
            val initialDelay = calendar.timeInMillis - now.timeInMillis
            // 创建周期性工作请求(每天同一时间)
            val dailyWorkRequest = PeriodicWorkRequestBuilder<ReminderWorker>(
                24, TimeUnit.HOURS
            )
                .setInitialDelay(initialDelay, TimeUnit.MILLISECONDS)
                .build()
            // 使用 REPLACE 策略确保新配置生效
            WorkManager.getInstance(context).enqueueUniquePeriodicWork(
                "daily_reminder_${hour}_${minute}",
                ExistingPeriodicWorkPolicy.REPLACE,
                dailyWorkRequest
            )
        }
    }
app/src/main/java/com/example/firstapp/ui/dashboard/ReminderRecordViewModel.kt
@@ -5,13 +5,17 @@
import androidx.lifecycle.LiveData
import androidx.lifecycle.asLiveData
import com.example.firstapp.database.entity.ReminderRecord
import com.example.firstapp.database.entity.ReminderRecord.Companion.STATUS_UNREAD
import com.example.firstapp.database.repository.ReminderRecordRepository
import com.example.firstapp.database.service.RetrofitClient
class ReminderRecordViewModel(application: Application) : AndroidViewModel(application) {
    private val reminderRecordRepository: ReminderRecordRepository = ReminderRecordRepository(application)
    val reminderRecords: LiveData<List<ReminderRecord>> = reminderRecordRepository.getAllRecords().asLiveData()
    val reminderRecords: LiveData<List<ReminderRecord>> =
        reminderRecordRepository.getRecordsByStatus(
            STATUS_UNREAD
        ).asLiveData()
    suspend fun getUserInfo(phone: String) = RetrofitClient.apiService.getUserInfo(phone)
app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt
@@ -15,9 +15,7 @@
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide
import com.example.firstapp.R
import com.example.firstapp.activity.ContentDetailActivity
import com.example.firstapp.activity.PickupActivity
import com.example.firstapp.activity.VipActivity
import com.example.firstapp.adapter.ExpressAdapter
@@ -28,13 +26,14 @@
import com.example.firstapp.databinding.FragmentHomeBinding
import com.example.firstapp.databinding.DialogCategorySelectorBinding
import com.example.firstapp.model.CategoryConfig
import com.example.firstapp.model.IncomeGroup
import com.example.firstapp.model.IncomePackage
import com.example.firstapp.utils.PreferencesManager
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.launch
import com.example.firstapp.view.UnderlineTextView
import com.example.firstapp.activity.ReminderListActivity
import android.graphics.Color
import android.view.Gravity
import android.widget.FrameLayout
class HomeFragment : Fragment() {
@@ -49,6 +48,8 @@
    private lateinit var flightAdapter: FinanceAdapter
    private lateinit var trainAdapter: FinanceAdapter
    private lateinit var dataUpdateReceiver: BroadcastReceiver
    private lateinit var reminderUpdateReceiver: BroadcastReceiver
    private var reminderBadge: TextView? = null
    //onCreateView这个方法创建后被调用,通常是初始化视图组件和观察者
    override fun onCreateView(
@@ -94,6 +95,7 @@
        setupTabSwitching()
        setupObservers()
        setupCategorySelector()
        setupUnreadBadge()
    }
    override fun onCreate(savedInstanceState: Bundle?) {
@@ -105,6 +107,16 @@
                if (intent.action == "com.example.firstapp.DATA_UPDATED") {
                    // 收到数据更新广播时重新加载数据
                    homeViewModel.loadExpressData()
                }
            }
        }
        // 创建提醒更新广播接收器
        reminderUpdateReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                if (intent.action == "com.example.firstapp.REMINDER_UPDATED") {
                    // 收到提醒更新广播时重新检查未读提醒数量
                    homeViewModel.checkUnreadReminders()
                }
            }
        }
@@ -207,7 +219,7 @@
                updateTabStyles(tabFinance)
                homeViewModel.loadFinanceData()
            }
            // 其他标签点击事件需要检查会员状态
            val memberOnlyTabs = mapOf(
                tabIncome to { homeViewModel.loadIncomeData() },
@@ -279,7 +291,7 @@
            val tabs = listOf(tabExpress, tabFinance, tabIncome, tabFlight, tabTrain)
            tabs.forEach { tab ->
                // 设置文字颜色为黑色或灰色
                tab.setTextColor(ContextCompat.getColor(requireContext(),
                tab.setTextColor(ContextCompat.getColor(requireContext(),
                    if (tab == selectedTab) android.R.color.black else R.color.gray))
                // 设置文字大小
                tab.textSize = if (tab == selectedTab) 16f else 14f
@@ -311,6 +323,11 @@
        homeViewModel.trainItems.observe(viewLifecycleOwner) { items ->
            trainAdapter.submitList(items)
        }
        // 观察未读提醒数量变化
        homeViewModel.unreadReminderCount.observe(viewLifecycleOwner) { unreadCount ->
            updateReminderBadge(unreadCount)
        }
        // 观察可见分类的变化
@@ -387,8 +404,19 @@
            IntentFilter("com.example.firstapp.DATA_UPDATED"),
            ContextCompat.RECEIVER_NOT_EXPORTED
        )
        // 注册提醒更新广播接收器
        ContextCompat.registerReceiver(
            requireContext(),
            reminderUpdateReceiver,
            IntentFilter("com.example.firstapp.REMINDER_UPDATED"),
            ContextCompat.RECEIVER_NOT_EXPORTED
        )
        // 加载数据
        homeViewModel.loadExpressData()
        // 检查未读提醒数量
        homeViewModel.checkUnreadReminders()
    }
    override fun onPause() {
@@ -396,6 +424,7 @@
        try {
            // 取消注册广播接收器
            requireContext().unregisterReceiver(dataUpdateReceiver)
            requireContext().unregisterReceiver(reminderUpdateReceiver)
        } catch (e: Exception) {
            // 处理可能的异常
            e.printStackTrace()
@@ -451,9 +480,12 @@
        }
        // 添加提醒按钮点击事件
//        binding.reminderButton.setOnClickListener {
//            startActivity(Intent(requireContext(), ReminderListActivity::class.java))
//        }
        binding.reminderButton.setOnClickListener {
            // 跳转到提醒列表页面
            startActivity(Intent(requireContext(), ReminderListActivity::class.java))
            // 重新检查未读提醒数量
            homeViewModel.checkUnreadReminders()
        }
    }
    private fun showCategorySelectorDialog() {
@@ -481,15 +513,15 @@
                        adapter.setCategories(categories)
                    } else {
                        // 非会员只能看到快递和还款
                        val limitedCategories = categories.filter {
                            it.name == "快递" || it.name == "还款"
                        val limitedCategories = categories.filter {
                            it.name == "快递" || it.name == "还款"
                        }
                        adapter.setCategories(limitedCategories)
                    }
                } catch (e: Exception) {
                    // 发生错误时只显示基础分类
                    val limitedCategories = categories.filter {
                        it.name == "快递" || it.name == "还款"
                    val limitedCategories = categories.filter {
                        it.name == "快递" || it.name == "还款"
                    }
                    adapter.setCategories(limitedCategories)
                }
@@ -503,4 +535,43 @@
        dialog.show()
    }
    // 添加设置未读提醒徽章的方法
    private fun setupUnreadBadge() {
        // 创建未读消息数量的小红点
        reminderBadge = TextView(requireContext()).apply {
            setBackgroundResource(R.drawable.circle_badge_background)
            setTextColor(Color.WHITE)
            gravity = Gravity.CENTER
            textSize = 10f
            minWidth = resources.getDimensionPixelSize(R.dimen.badge_min_width)
            minHeight = resources.getDimensionPixelSize(R.dimen.badge_min_height)
            setPadding(4, 0, 4, 0)
        }
        // 添加到布局中
        val parentView = binding.reminderButton.parent as? ViewGroup
        parentView?.addView(reminderBadge)
        // 调整位置到提醒按钮右上角
        (reminderBadge?.layoutParams as? FrameLayout.LayoutParams)?.apply {
            gravity = Gravity.TOP or Gravity.END
            width = 48  // 使用固定像素值
            height = 48 // 使用固定像素值
            // 设置位置偏移,使小红点位于图标右上角
            setMargins(0, 0, 0, 0)
        }
    }
    // 更新未读提醒徽章
    private fun updateReminderBadge(unreadCount: Int) {
        reminderBadge?.apply {
            if (unreadCount > 0) {
                text = if (unreadCount > 99) "99+" else unreadCount.toString()
                visibility = View.VISIBLE
            } else {
                visibility = View.GONE
            }
        }
    }
}
app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt
@@ -19,6 +19,8 @@
import com.example.firstapp.util.SecureStorage
import com.example.firstapp.utils.PreferencesManager
import kotlinx.coroutines.launch
import com.example.firstapp.database.repository.ReminderRecordRepository
import com.example.firstapp.database.entity.ReminderRecord
class HomeViewModel : ViewModel() {
@@ -40,8 +42,12 @@
    private val _visibleCategories = MutableLiveData<List<CategoryConfig>>()
    val visibleCategories: LiveData<List<CategoryConfig>> = _visibleCategories
    private val _unreadReminderCount = MutableLiveData<Int>()
    val unreadReminderCount: LiveData<Int> = _unreadReminderCount
    private lateinit var secureStorage: SecureStorage
    private lateinit var currentUserId: String
    private lateinit var reminderRecordRepository: ReminderRecordRepository
    init {
        // 初始化时加载包裹列表数据
@@ -53,9 +59,12 @@
    fun initialize(context: Context, userId: String) {
        secureStorage = SecureStorage(context)
        currentUserId = userId
        reminderRecordRepository = ReminderRecordRepository(context)
        loadCategories()
        // 初始化时更新可见分类
        _categories.value?.let { updateVisibleCategories(it) }
        // 加载未读提醒数量
        checkUnreadReminders()
    }
    private fun loadDataByType(type: String) {
@@ -234,6 +243,18 @@
        _visibleCategories.value = categories.filter { it.isEnabled }
    }
    // 添加检查未读提醒数量的方法
    fun checkUnreadReminders() {
        viewModelScope.launch {
            try {
                val unreadCount = reminderRecordRepository.getUnreadCount(ReminderRecord.STATUS_UNREAD)
                _unreadReminderCount.postValue(unreadCount)
            } catch (e: Exception) {
                Log.e("HomeViewModel", "Failed to get unread reminder count: ${e.message}")
            }
        }
    }
    // 登出时不再清除本地数据
    fun logout() {
        // 只清除内存中的数据
app/src/main/res/drawable/reminder.xml
对比新文件
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M935.7,753.1c-38.7,-55.1 -113.4,-130.2 -113.3,-267.7 -1.5,-221 -96.3,-338.6 -245.8,-372.2 -0.2,-8 -0.3,-16 -0.5,-23.9C574.9,42.1 545,2.1 510,2.1 475,2.1 445.2,42.1 444,89.4c-0.2,8.6 -0.4,17.1 -0.5,25.7 -144,37.5 -235.2,152.9 -236.5,370.4 -0.1,137.5 -60.8,225.1 -113.6,268.8 -54.5,61.4 70.8,69.5 70.5,69 233.8,30 467.5,29.6 701.3,-1.1 -0.3,0.2 102.2,-23.1 70.6,-69zM510,1019.7c75.3,0.1 142.9,-54.5 178,-125.6a2268.8,2268.8 0,0 1,-355.9 0c35.1,71.1 102.6,125.7 178,125.6z"
      android:fillColor="#333333"/>
</vector>
app/src/main/res/drawable/reminder_delete.xml
对比新文件
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M380,455a8,8 0,0 1,8 -8h64a8,8 0,0 1,8 8v240a8,8 0,0 1,-8 8h-64a8,8 0,0 1,-8 -8V455zM644,455a8,8 0,0 0,-8 -8h-64a8,8 0,0 0,-8 8v240a8,8 0,0 0,8 8h64a8,8 0,0 0,8 -8V455z"
      android:fillColor="#323338"/>
  <path
      android:pathData="M321,212L321,96c0,-17.7 14.3,-32 32,-32h320c17.7,0 32,14.3 32,32v116h183a8,8 0,0 1,8 8v64a8,8 0,0 1,-8 8h-55v635c0,17.7 -14.3,32 -32,32L225,959c-17.7,0 -32,-14.3 -32,-32L193,292h-58a8,8 0,0 1,-8 -8v-64a8,8 0,0 1,8 -8h186zM401,144v68h224v-68L401,144zM273,292v587h480L753,292L273,292z"
      android:fillColor="#323338"/>
</vector>
app/src/main/res/drawable/reminder_express.xml
对比新文件
@@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M589.7,672 L587.8,672C544.5,672 500.6,705.7 491.3,745.1L691.6,745.1C681.4,706.3 634,672 589.7,672"
      android:fillColor="#0587FF"/>
  <path
      android:pathData="M528.6,421C528.6,401 558.7,401 558.7,421 558.7,442.2 576,459.4 597.4,459.4 618.7,459.4 636,442.2 636,421L636,373.8 534.7,278.9 339.7,278.9 279.9,334 584.2,334C592.5,334 599.3,340.7 599.3,349.1 599.3,357.4 592.5,364.1 584.2,364.1L247.2,364.1 236.6,373.9 236.6,421C236.6,442.2 253.9,459.4 275.2,459.4 296.6,459.4 313.8,442.2 313.8,421 313.8,401 344,401 344,421 344,442.2 361.2,459.4 382.6,459.4 403.9,459.4 421.2,442.2 421.2,421 421.2,401 451.3,401 451.3,421 451.3,442.2 468.6,459.4 490,459.4 511.3,459.4 528.6,442.2 528.6,421"
      android:fillColor="#0587FF"/>
  <path
      android:pathData="M585.3,633.9C610.6,633.9 631.4,612.5 631.4,585.7 631.4,559 610.6,537.5 585.3,537.5 559.9,537.5 539.2,559 539.2,585.7 539.2,612.5 559.9,633.9 585.3,633.9"
      android:fillColor="#0587FF"/>
  <path
      android:pathData="M708.7,775.2C708.2,775.2 707.8,775.1 707.3,775.1 706.8,775.1 706.4,775.2 705.9,775.2L479.2,775.2C478.4,775.2 477.6,775.1 476.8,775 476,775.1 475.2,775.2 474.4,775.2 466.1,775.2 459.3,768.5 459.3,760.2 459.3,712.1 496.5,668.7 542.7,650.7 522.4,636.6 509.1,612.7 509.1,585.7 509.1,542.6 543.1,507.4 585.3,507.4 627.5,507.4 661.5,542.6 661.5,585.7 661.5,611.6 649.2,634.5 630.4,648.8 680.7,665.5 723.8,710.6 723.8,760.2 723.8,768.5 717,775.2 708.7,775.2M436.3,463.7C423.7,479.4 404.3,489.5 382.6,489.5 360.9,489.5 341.5,479.4 328.9,463.7 316.3,479.4 296.9,489.5 275.2,489.5 272.7,489.5 270.2,489.4 267.7,489.1L267.7,624.9C267.7,645.1 272.8,648.1 298.8,648.1 300.4,648.1 300.4,648.1 301.9,648.1L411.3,648.1C419.6,648.1 426.4,654.9 426.4,663.2 426.4,671.5 419.6,678.3 411.3,678.3L301.9,678.3C300.4,678.3 300.4,678.3 298.8,678.2 258.3,678.1 237.6,666.2 237.6,624.9L237.6,478.3C218.9,466.1 206.5,445 206.5,421L206.5,367.3C206.5,363.1 208.2,359.1 211.3,356.2L211.6,356C210.5,353.9 209.8,351.6 209.8,349.1 209.8,340.7 216.5,334 224.9,334L235.4,334 323.6,252.7C326.3,250.2 330,248.8 333.8,248.8L540.6,248.8C544.4,248.8 548.1,250.2 550.9,252.8L661.4,356.3C664.4,359.2 666.1,363.1 666.1,367.3L666.1,421C666.1,458.9 635.3,489.5 597.4,489.5 575.6,489.5 556.3,479.4 543.7,463.7 531.1,479.4 511.7,489.5 490,489.5 468.2,489.5 448.9,479.4 436.3,463.7M512,10C234.8,10 10,234.8 10,512 10,789.2 234.8,1014 512,1014 789.2,1014 1014,789.2 1014,512 1014,234.8 789.2,10 512,10"
      android:fillColor="#0587FF"/>
</vector>
app/src/main/res/drawable/reminder_finance.xml
对比新文件
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="32dp"
    android:height="32dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M230.8,576.6c-12.6,9.6 -25.2,23.7 -28.9,42.3 -5.2,24.5 -0.7,55.7 22.3,80.1 28.9,28.9 72.7,37.1 92,38.6 51.2,3.7 106.1,-22.3 147.7,-50.5 16.3,-11.1 43.8,-34.1 70.5,-69.8 -59.4,-30.4 -133.6,-64.6 -212.2,-61.6 -41.6,1.5 -70.5,9.6 -91.3,20.8zM983.2,712.3c26,-61.6 40.8,-129.1 40.8,-200.3 0,-282 -230,-512 -512,-512S0,230 0,512s230,512 512,512c170.7,0 321.3,-83.8 414.8,-212.2C838.5,768.7 693.8,696 604,653c-42.3,49 -105.4,97.2 -176.6,118 -44.5,13.4 -85.3,18.6 -126.9,9.6 -42.3,-8.9 -72.7,-28.2 -90.5,-47.5 -8.9,-10.4 -19.3,-22.3 -27.5,-37.8 0.7,0.7 0.7,2.2 0.7,3 0,0 -4.5,-7.4 -7.4,-19.3 -1.5,-5.9 -3,-11.9 -3.7,-17.8 -0.7,-4.5 -0.7,-8.9 0,-12.6 -0.7,-7.4 0,-15.6 1.5,-23.7 4.5,-20.8 12.6,-43.8 35.6,-65.3 49,-48.2 115,-50.5 149.1,-50.5 50.5,0.7 138,22.3 212.2,49 20.8,-43.8 34.1,-89.8 42.3,-121.7L305,436.3v-33.4h158.1v-66.8L272.3,336.1v-34.1h190.7v-66.8c0,-8.9 2.2,-16.3 16.3,-16.3h74.9v83.1h207v33.4L554.3,335.4v66.8L719.8,402.2S702.7,494.9 651.5,586.2c115,40.8 277.5,104.6 331.7,126.1zM983.2,712.3"
      android:fillColor="#1296db"/>
</vector>
app/src/main/res/drawable/reminder_flight.xml
对比新文件
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M924.8,337.6c-22.6,-53.3 -54.9,-101.3 -96,-142.4 -41.1,-41.1 -89.1,-73.5 -142.4,-96C631.2,75.8 572.5,64 512,64S392.8,75.8 337.6,99.2c-53.3,22.6 -101.3,54.9 -142.4,96 -41.1,41.1 -73.5,89.1 -96,142.4C75.8,392.8 64,451.5 64,512s11.8,119.2 35.2,174.4c22.6,53.3 54.9,101.3 96,142.4 41.1,41.1 89.1,73.5 142.4,96C392.8,948.2 451.5,960 512,960s119.2,-11.8 174.4,-35.2c53.3,-22.6 101.3,-54.9 142.4,-96 41.1,-41.1 73.5,-89.1 96,-142.4C948.2,631.2 960,572.5 960,512s-11.8,-119.2 -35.2,-174.4zM838.3,417s-298.4,165.4 -458,249.4c-10.8,5.6 -22.7,9.1 -34.8,10.2 -21.1,1.8 -34.2,2.4 -55.8,3.4 -11.5,2.1 -23.3,-0.7 -32.7,-7.6l-86.5,-80c-4.9,-4.9 -7.3,-11.7 -6.8,-18.6 0.8,-6.9 3.7,-13.4 8.4,-18.6 10.1,-10.7 25.7,-14.4 39.5,-9.3 25.9,9.3 66.9,19.7 98.3,34.5 2.2,0.9 4.6,0.9 6.8,0l76.5,-36.2c3.8,-2.8 9.7,-11.2 0,-16.9l-143.6,-72.4c-5.3,-1.7 -9.1,-6.3 -9.6,-11.8 -0.5,-5.5 2.3,-10.8 7.2,-13.5 8.6,-6.7 17.3,-13.8 26.1,-20.2 8.5,-9 20.3,-13.8 32.7,-13.5 90.1,10.9 180.4,22.5 270.6,33.7 1.5,0.1 2.9,-0.2 4.2,-0.9 4.1,-1.8 70.5,-31.5 144.5,-70.8 18.8,-9.3 39.5,-14.2 60.5,-14.4v-0.1c26.1,-1 51.4,9.2 69.4,28 10.2,12.1 6.1,31.3 -16.9,45.6z"
      android:fillColor="#3772f8"/>
</vector>
app/src/main/res/drawable/reminder_income.xml
对比新文件
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="128dp"
    android:height="128dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M1023.4,511.7c-2,436.4 -73,511.9 -511.7,511.7C73.1,1023.2 -0.7,950 0,511.7 0.7,73.4 72.8,-1.1 511.7,0c438.8,1.1 513.6,75.3 511.7,511.7z"
      android:fillColor="#E60012"/>
  <path
      android:pathData="M1023.4,511.7c-2,436.4 -73,511.9 -511.7,511.7C73.1,1023.2 -0.7,950 0,511.7 0.7,73.4 72.8,-1.1 511.7,0c438.8,1.1 513.6,75.3 511.7,511.7z"
      android:fillColor="#FB5B42"/>
  <path
      android:pathData="M1023.4,511.7c-2,436.4 -73,511.9 -511.7,511.7C73.1,1023.2 -0.7,950 0,511.7 0.7,73.4 72.8,-1.1 511.7,0c438.8,1.1 513.6,75.3 511.7,511.7z"
      android:fillColor="#FB5B42"/>
  <path
      android:pathData="M1023.4,511.7c-2,436.4 -73,511.9 -511.7,511.7C73.1,1023.2 -0.7,950 0,511.7 0.7,73.4 72.8,-1.1 511.7,0c438.8,1.1 513.6,75.3 511.7,511.7z"
      android:fillColor="#FB5B42"/>
  <path
      android:pathData="M1023.4,511.7c-2,436.4 -73,511.9 -511.7,511.7C73.1,1023.2 -0.7,950 0,511.7 0.7,73.4 72.8,-1.1 511.7,0c438.8,1.1 513.6,75.3 511.7,511.7z"
      android:fillColor="#FB5B42"/>
  <path
      android:pathData="M784.8,19.8l-3.5,2c-26.8,17 -49.1,43.9 -58.7,73.4l-1.2,4.5 -20,85.9 -83.4,374.6 -56.9,260.9 -22.2,105.6 -2.7,14.9c-1.6,41.9 20.6,72.5 57.4,80.9l-37.9,0.6a3594,3594 0,0 1,-40.1 0.2l-42.9,-0.3 -40.6,-0.9c-85.4,-2.5 -154.2,-9.4 -209.7,-23.7 -10.8,-12.7 -17.1,-29.5 -17.7,-49.1l0.1,-8.5 5,-26.4 65.3,-302.8L366.6,200l22.3,-96.3 2.3,-8.8C406,49.3 451.2,9.8 496.4,3.8l6.7,-0.4 32.7,-0.6L588.9,2.6h41.7c59.7,2.8 110.7,8.1 154.2,17.3z"
      android:fillColor="#00508E"/>
  <path
      android:pathData="M1023.4,479.1v33.5l-0.5,45.8 -0.6,29 -1,27.8 -1.3,26.7 -1.7,25.5 -2,24.4 -2.4,23.3 -2.9,22.2 -1.6,10.7 -3.5,20.7c-29,154.5 -101.1,219.5 -266.7,243.4l-22.1,2.9 -23.2,2.4 -24.3,2 -12.6,0.9 -26,1.4 -27.2,1.1 -14.1,0.4c-34.5,-7.8 -56.2,-35.1 -57.4,-72.7l0.1,-8.4 6.1,-31.7 30.4,-142.6 84.6,-385.1 51.5,-229.2 12.3,-52.2 1.5,-5.5c10,-30.7 33.8,-58.7 62.1,-75.5 149.5,31.3 211.2,107 232.7,274.7l2.8,24.6c0.4,4.2 0.9,8.5 1.2,12.8l2,26.5 1.6,27.9 1.2,29.2 0.7,30.6 0.4,32.1z"
      android:fillColor="#00908C"/>
  <path
      android:pathData="M332.6,520.8h100.6a35.9,35.9 0,0 0,23.2 -8c10.4,-7.6 17.8,-18.8 20.9,-31.8l27.2,-123h-87c-19.6,2.6 -38.2,10.4 -53.9,23l5.1,-23L320.3,357.9L259.7,631.9a26.4,26.4 0,0 0,2.9 24.6,32.7 32.7,0 0,0 23.7,8.8h56l7.9,-35.4h-31.6a9.3,9.3 0,0 1,-2.7 -0.4,8.7 8.7,0 0,1 -5,-10.8l21.7,-97.9zM653.4,649.9l-3.4,15.4L601.7,665.2l3.4,-15.4h-111.9l7.8,-35.3h17.3l56.7,-256.7h48.1l-5,22.9a115,115 0,0 1,52.6 -22.9h61.4l-7.9,35.4h-14.3l-49,221.4h14.2l-7.8,35.1h-13.9zM144.2,405.2h15.1s22,-1.7 35.7,-47.2h50.8a205.7,205.7 0,0 1,-11 23.5h63.4l-7.9,35.4L209.4,417a75.7,75.7 0,0 1,-50.7 24.5h-22.4l7.9,-36.2zM737.8,358.1h52.5c-0.9,6.7 -0.9,13.5 0,20.2 0,0 1.9,11.1 19.9,11.3l-7.9,35.6h-29.2a34.4,34.4 0,0 1,-31.7 -19.8,80.2 80.2,0 0,1 -3.7,-47.3zM882.4,405.4a55.1,55.1 0,0 1,-40.5 19.7h-29.2l7.9,-35.6a28.9,28.9 0,0 0,24.9 -11.3c3.8,-6.3 6.8,-13.1 9,-20.2h52.6a115.3,115.3 0,0 1,-24.7 47.3zM599.4,466.4l16,-72.9v-0.1h46.5l-11.2,50.4a100.5,100.5 0,0 0,-51.3 22.6zM401.7,421.8a108.5,108.5 0,0 0,-52 22.5l11.3,-50.5h87.5l-6.2,28.1h-40.5zM880.2,479.1L819.6,479.1l-7.4,33.7h60.6l-7.8,35L799.6,547.8l-10.4,18.1h29l8.4,50.5c0.5,5.6 3.7,10.7 8.4,13.6h11.8l-7.9,35.4h-25.7a35.1,35.1 0,0 1,-26.1 -11.8,46.6 46.6,0 0,1 -6.1,-19.6l-7,-42.1 -24.6,42.6a74.9,74.9 0,0 1,-15.9 21.1,41.6 41.6,0 0,1 -28.8,9.8L669.5,665.5l7.8,-35.4h17.8a18.6,18.6 0,0 0,14.2 -10.4l41.8,-71.9h-55.5l7.8,-35h60.6l7.4,-33.7h-60.6l7.8,-35.1h169.4l-7.7,35.1zM243.2,630L195.9,630a5.9,5.9 0,0 1,-2.8 -0.6,8.7 8.7,0 0,1 -5,-11l10.7,-48.2L256.3,570.3l7.9,-35.5L206.8,534.8l11,-49.6h57.3l7.8,-35.4L143,449.8l-7.9,35.4h34.5l-11,49.6h-34.5l-7.9,35.6h34.5l-13.9,62.8a25.5,25.5 0,0 0,7.7 27,30.3 30.3,0 0,0 17.4,5.1h73.3l7.8,-35.3zM340.6,485.3h87.5l6.3,-28.2L346.8,457.1l-6.2,28.2zM631.8,529.6a98.9,98.9 0,0 0,-51.5 22.3l16.2,-72.8h46.5l-11.2,50.5zM453.5,579.7a30.4,30.4 0,0 0,11 -18l5.8,-26.6h-36.9l-4.2,18.8a8.3,8.3 0,0 1,-7.8 5.6h-17.4l-0.5,-24.6L355.3,534.9l1.7,102.9a41.2,41.2 0,0 0,2.8 16.7c4.9,11.9 28.1,10.7 28.1,10.7h53.6l7.8,-35.3h-35.5c-4.3,0.6 -8.3,-2.8 -8.8,-7.3l-0.5,-35.8h22.6a40.9,40.9 0,0 0,26.4 -7.1zM566.5,614.5h46.4l11.1,-50.1h-46.4l-11.1,50.1z"
      android:fillColor="#FFFFFF"/>
</vector>
app/src/main/res/drawable/reminder_train.xml
对比新文件
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="128dp"
    android:height="128dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M196.1,282.1v171l174.6,63.5 -41,-252.9z"
      android:fillColor="#3378FE"/>
  <path
      android:pathData="M827.9,244.7v297.5c-20.5,-17.4 -45.6,-35.3 -76.3,-51.2 12.3,-2.6 22,-13.3 22,-26.6V299c0,-14.8 -12.3,-27.1 -27.1,-27.1h-192c-14.8,0 -27.1,12.3 -27.1,27.1v129c-5.6,-0.5 -10.8,-1 -16.4,-1.5 -4.6,-0.5 -8.7,-0.5 -13.3,-1V299c0,-14.8 -12.3,-27.1 -27.1,-27.1H277.5c-14.8,0 -27.1,12.3 -27.1,27.1v49.7c-21.5,-14.3 -39.4,-29.2 -54.3,-43.5V205.3c0,-7.7 1,-15.9 3.6,-23 54.8,17.4 147.5,33.3 293.4,21 174.1,-14.3 280.1,16.9 334.8,41.5z"
      android:fillColor="#FFB634"/>
  <path
      android:pathData="M827.9,205.3v38.9c-54.8,-24.6 -160.8,-55.3 -334.8,-41 -145.9,12.3 -238.6,-3.6 -293.4,-21 9.2,-29.7 34.8,-56.3 65,-62.5 163.3,-34.3 331.8,-34.3 494.6,0 37.9,7.7 68.6,47.6 68.6,85.5z"
      android:fillColor="#BB32FF"/>
  <path
      android:pathData="M751.6,490.5c-1.5,0.5 -3.6,0.5 -5.6,0.5h-192c-14.8,0 -27.1,-12.3 -27.1,-27.1v-35.8c-5.6,-0.5 -10.8,-1 -16.4,-1.5 -4.6,-0.5 -8.7,-0.5 -13.3,-1v37.9c0,14.8 -12.3,27.1 -27.1,27.1L322.6,490.5c41,35.3 82.9,81.9 120.3,141.3 5.1,7.7 9.7,15.9 14.8,24.6 23.6,41 45.1,88.1 63,141.8h238.1c38.4,0 69.6,-31.2 69.6,-69.6v-187.4c-21,-16.9 -46.1,-34.3 -76.8,-50.7zM706,720.9c-6.1,0 -11.8,-1 -16.9,-3.6 -15.4,-6.7 -26.1,-22 -26.1,-39.4 0,-2.6 0.5,-5.6 1,-8.2 3.6,-20 21.5,-34.8 42.5,-34.8 23.6,0 43,19.5 43,43 -0.5,23.6 -20,43 -43.5,43z"
      android:fillColor="#3378FE"/>
  <path
      android:pathData="M457.7,656.9c-4.6,-8.2 -9.7,-16.4 -14.8,-24.6 -37.4,-59.9 -79.9,-106 -120.3,-141.3h-45.1c-14.8,0 -27.1,-12.3 -27.1,-27.1v-26.6C230.4,425 212.5,414.7 196.1,407v322.6c0,38.4 31.2,69.1 69.6,69.6L520.2,799.2c-17.4,-54.3 -38.9,-101.4 -62.5,-142.3zM334.8,717.3c-5.1,2.6 -11.3,3.6 -16.9,3.6 -23.6,0 -43,-19.5 -43,-43 0,-23.6 19.5,-43 43,-43 21,0 38.4,14.8 42.5,34.8 0.5,2.6 1,5.1 1,8.2 -1,17.4 -11.3,32.8 -26.6,39.4z"
      android:fillColor="#5F4DFE"/>
  <path
      android:pathData="M732.2,798.7h-91.1l21,38.9H362l20.5,-38.9H291.8l-64.5,121.3h91.1l21.5,-41h343.6l22,41h90.6zM827.9,545.8h-200.2c-4.6,0 -9.2,2 -12.3,5.1L512,653.8l-103.4,-103.4c-3.1,-3.1 -7.7,-5.1 -12.3,-5.1H196.1v34.8H389.1l110.6,110.6c3.6,3.6 7.7,5.1 12.3,5.1 4.6,0 8.7,-1.5 12.3,-5.1l110.6,-110.6h193v-34.3z"
      android:fillColor="#2F2960"/>
  <path
      android:pathData="M746,271.4h-192c-14.8,0 -27.1,12.3 -27.1,27.1v164.9c0,14.8 12.3,27.1 27.1,27.1h192c2,0 3.6,0 5.6,-0.5 12.3,-2.6 22,-13.3 22,-26.6V299c0,-15.4 -12.3,-27.6 -27.6,-27.6zM469.5,271.4H277.5c-14.8,0 -27.1,12.3 -27.1,27.1v164.9c0,14.8 12.3,27.1 27.1,27.1h192.5c14.8,0 27.1,-12.3 27.1,-27.1V299c0,-15.4 -12.3,-27.6 -27.6,-27.6z"
      android:fillColor="#F3F3F3"/>
  <path
      android:pathData="M706,634.9c-21,0 -38.4,14.8 -42.5,34.8 -0.5,2.6 -1,5.1 -1,8.2 0,17.9 10.8,32.8 26.1,39.4 5.1,2.6 11.3,3.6 16.9,3.6 23.6,0 43,-19.5 43,-43 0.5,-24.1 -18.9,-43 -42.5,-43zM359.9,669.7c-3.6,-20 -21,-34.8 -42.5,-34.8 -23.6,0 -43,19.5 -43,43 0,23.6 19.5,43 43,43 6.1,0 11.8,-1 16.9,-3.6 15.4,-6.7 26.1,-22 26.1,-39.4 0,-3.1 0,-5.6 -0.5,-8.2z"
      android:fillColor="#2F2960"/>
</vector>
app/src/main/res/layout/activity_reminder_list.xml
@@ -4,6 +4,29 @@
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!-- 顶部标题栏   android:background="@android:color/white"-->
    <RelativeLayout
        android:id="@+id/titleBarLayout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:elevation="4dp"
        android:padding="8dp">
        <!-- 将已读按钮改为图标 -->
        <ImageButton
            android:id="@+id/clearReadMessagesButton"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="16dp"
            android:background="?attr/selectableItemBackgroundBorderless"
            android:contentDescription="标记所有消息为已读"
            android:padding="8dp"
            android:src="@drawable/reminder_delete" />
    </RelativeLayout>
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/reminderRecyclerView"
        android:layout_width="match_parent"
app/src/main/res/layout/fragment_home.xml
@@ -21,24 +21,26 @@
            android:orientation="vertical">
            <!-- 快递/财务切换区域 -->
            <FrameLayout
            <!-- 优化后的快递/财务切换区域 -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:orientation="horizontal"
                android:layout_marginTop="8dp"
                android:layout_marginBottom="8dp"
                android:layout_marginHorizontal="8dp">
                <!-- 分类标签区域 -->
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="70dp"
                    android:layout_weight="1"
                    android:orientation="horizontal">
                    <com.example.firstapp.view.UnderlineTextView
                        android:id="@+id/tabExpress"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:padding="6dp"
@@ -49,7 +51,7 @@
                    <com.example.firstapp.view.UnderlineTextView
                        android:id="@+id/tabFinance"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:padding="6dp"
@@ -59,7 +61,7 @@
                    <com.example.firstapp.view.UnderlineTextView
                        android:id="@+id/tabIncome"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:padding="6dp"
@@ -69,7 +71,7 @@
                    <com.example.firstapp.view.UnderlineTextView
                        android:id="@+id/tabFlight"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:padding="6dp"
@@ -79,46 +81,43 @@
                    <com.example.firstapp.view.UnderlineTextView
                        android:id="@+id/tabTrain"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:gravity="center"
                        android:padding="6dp"
                        android:text="火车票"
                        android:textSize="14sp" />
                        android:textSize="13sp" />
                </LinearLayout>
                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="32dp">
                <!-- 右侧图标区域 -->
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:orientation="horizontal"
                    android:gravity="center_vertical">
                    <ImageButton
                        android:id="@+id/categoryButton"
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:layout_gravity="center_vertical|end"
                        android:layout_marginEnd="32dp"
                        android:layout_marginEnd="8dp"
                        android:background="?attr/selectableItemBackgroundBorderless"
                        android:contentDescription="分类设置"
                        android:padding="4dp"
                        android:scaleType="fitCenter"
                        android:src="@drawable/home_add" />
                </FrameLayout>
                <ImageButton
                    android:id="@+id/reminderButton"
                    android:layout_width="28dp"
                    android:layout_height="28dp"
                    android:layout_gravity="center_vertical|end"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:contentDescription="提醒设置"
                    android:padding="4dp"
                    android:scaleType="fitCenter"
                    android:src="@drawable/home_add" />
            </FrameLayout>
                    <ImageButton
                        android:id="@+id/reminderButton"
                        android:layout_width="28dp"
                        android:layout_height="28dp"
                        android:background="?attr/selectableItemBackgroundBorderless"
                        android:contentDescription="提醒设置"
                        android:padding="4dp"
                        android:scaleType="fitCenter"
                        android:src="@drawable/reminder" />
                </LinearLayout>
            </LinearLayout>
            <!-- 内容区域 -->
            <FrameLayout
app/src/main/res/layout/item_reminder_record.xml
@@ -3,16 +3,26 @@
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="8dp"
    android:layout_marginVertical="4dp"
    app:cardCornerRadius="8dp"
    app:cardElevation="2dp">
    android:layout_marginHorizontal="0dp"
    android:layout_marginVertical="1dp"
    app:cardCornerRadius="0dp"
    app:cardElevation="0dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="16dp">
        android:padding="16dp"
        android:background="@android:color/white">
        <ImageView
            android:id="@+id/categoryIcon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_vertical"
            android:layout_marginEnd="16dp"
            android:src="@drawable/ic_add"
             />
        <LinearLayout
            android:layout_width="0dp"
@@ -21,18 +31,11 @@
            android:orientation="vertical">
            <TextView
                android:id="@+id/categoryNameText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="16sp"
                android:textStyle="bold" />
            <TextView
                android:id="@+id/contentText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:textColor="@android:color/darker_gray"
                android:textColor="@android:color/black"
                android:textSize="14sp" />
            <TextView
@@ -40,18 +43,10 @@
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:textColor="@android:color/darker_gray"
                android:textColor="@android:color/black"
                android:textSize="12sp" />
        </LinearLayout>
        <ImageView
            android:id="@+id/statusIcon"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_gravity="center_vertical"
            android:src="@drawable/ic_add"
            />
    </LinearLayout>
app/src/main/res/values/dimens.xml
@@ -6,4 +6,12 @@
    <dimen name="list_item_spacing_half">8dp</dimen>
    <dimen name="heatmap_cell_size">12dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
    <!-- 徽章尺寸 -->
    <dimen name="badge_min_width">16dp</dimen>
    <dimen name="badge_min_height">16dp</dimen>
    <dimen name="badge_margin_top">4dp</dimen>
    <dimen name="badge_margin_end">4dp</dimen>
    <dimen name="badge_size">16dp</dimen>
</resources>