diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e6b0c77..57e8f14 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -2,6 +2,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/daodaoshi/chick_mood/AddActivity.kt b/app/src/main/java/com/daodaoshi/chick_mood/AddActivity.kt
new file mode 100644
index 0000000..23234d9
--- /dev/null
+++ b/app/src/main/java/com/daodaoshi/chick_mood/AddActivity.kt
@@ -0,0 +1,416 @@
+package com.daodaoshi.chick_mood
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.hardware.Sensor
+import android.hardware.SensorEvent
+import android.hardware.SensorEventListener
+import android.hardware.SensorManager
+import android.util.Log
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.View
+import android.view.animation.AlphaAnimation
+import android.view.animation.Animation
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.ProgressBar
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import android.os.Vibrator
+import android.os.VibrationEffect
+import com.chick_mood.data.model.Emotion
+import java.text.DecimalFormat
+
+/**
+ * 添加心情页面
+ * 通过摇晃手机来记录心情强度的核心功能页面
+ */
+class AddActivity : AppCompatActivity(), SensorEventListener {
+
+ // UI组件
+ private lateinit var btnBack: ImageView
+ private lateinit var tvTitle: TextView
+ private lateinit var tvMoodText: TextView
+ private lateinit var tvMoodValue: TextView
+ private lateinit var progressBar: ProgressBar
+ private lateinit var ivChick: ImageView
+ private lateinit var btnEnd: Button
+ private lateinit var viewOverlay: View
+ private lateinit var tvOverlayText: TextView
+
+ // 传感器相关
+ private lateinit var sensorManager: SensorManager
+ private var accelerometer: Sensor? = null
+ private var isSensorRegistered = false
+
+ // 震动反馈
+ private lateinit var vibrator: Vibrator
+
+ // 心情数据
+ private var selectedEmotion: Emotion? = null
+ private var currentMoodValue = 0
+ private val maxMoodValue = 100
+
+ // 遮罩引导系统
+ private val handler = Handler(Looper.getMainLooper())
+ private var overlayState = OVERLAY_STATE_INITIAL
+
+ // 摇晃检测相关
+ private var lastShakeTime = 0L
+ private var shakeThreshold = 15f // 摇晃强度阈值
+ private val moodValueFormatter = DecimalFormat("#")
+
+ companion object {
+ private const val TAG = "AddActivity"
+ private const val EXTRA_EMOTION_TYPE = "emotion_type"
+
+ // 遮罩状态
+ private const val OVERLAY_STATE_INITIAL = 0
+ private const val OVERLAY_STATE_READY = 1
+ private const val OVERLAY_STATE_HIDDEN = 2
+
+ // 遮罩显示时间(毫秒)
+ private const val OVERLAY_INITIAL_DURATION = 2000L
+ private const val OVERLAY_READY_DURATION = 2000L
+
+ // 心情值累计参数
+ private const val SHAKE_COOLDOWN = 100L // 摇晃冷却时间(毫秒)
+ private const val MOOD_INCREMENT_BASE = 2 // 基础心情值增量
+
+ /**
+ * 启动AddActivity
+ * @param context 上下文
+ * @param emotion 选择的心情类型
+ */
+ fun start(context: Context, emotion: Emotion) {
+ val intent = Intent(context, AddActivity::class.java).apply {
+ putExtra(EXTRA_EMOTION_TYPE, emotion.name)
+ }
+ context.startActivity(intent)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_add)
+
+ // 获取传递的心情类型
+ selectedEmotion = intent.getStringExtra(EXTRA_EMOTION_TYPE)?.let {
+ Emotion.valueOf(it)
+ } ?: Emotion.HAPPY
+
+ initViews()
+ initSensor()
+ startOverlaySequence()
+ }
+
+ /**
+ * 初始化视图组件
+ */
+ private fun initViews() {
+ btnBack = findViewById(R.id.btn_back)
+ tvTitle = findViewById(R.id.tv_title)
+ tvMoodText = findViewById(R.id.tv_mood_text)
+ tvMoodValue = findViewById(R.id.tv_mood_value)
+ progressBar = findViewById(R.id.progress_bar)
+ ivChick = findViewById(R.id.iv_chick)
+ btnEnd = findViewById(R.id.btn_end)
+ viewOverlay = findViewById(R.id.view_overlay)
+ tvOverlayText = findViewById(R.id.tv_overlay_text)
+
+ // 设置标题
+ tvTitle.text = "添加心情"
+
+ // 根据心情类型设置小鸡图标
+ selectedEmotion?.let { emotion ->
+ val chickIcon = getEmotionIconRes(emotion)
+ ivChick.setImageResource(chickIcon)
+ }
+
+ // 初始化UI状态
+ resetUI()
+
+ // 设置点击监听器
+ btnBack.setOnClickListener {
+ finish()
+ }
+
+ btnEnd.setOnClickListener {
+ onEndButtonClicked()
+ }
+
+ // 遮罩点击事件(可选:允许用户手动关闭遮罩)
+ viewOverlay.setOnClickListener {
+ // 可以选择是否允许用户手动关闭遮罩
+ // hideOverlay()
+ }
+ }
+
+ /**
+ * 初始化传感器和震动器
+ */
+ private fun initSensor() {
+ sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
+ accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
+
+ // 初始化震动器
+ vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+
+ if (accelerometer == null) {
+ Toast.makeText(this, "无传感器", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ /**
+ * 开始遮罩引导序列
+ */
+ private fun startOverlaySequence() {
+ overlayState = OVERLAY_STATE_INITIAL
+ viewOverlay.visibility = View.VISIBLE
+ tvOverlayText.visibility = View.VISIBLE
+ tvOverlayText.text = "握紧手机"
+
+ // 添加淡入动画
+ val fadeIn = AlphaAnimation(0f, 1f)
+ fadeIn.duration = 300
+ viewOverlay.startAnimation(fadeIn)
+ tvOverlayText.startAnimation(fadeIn)
+
+ // 2秒后切换到准备状态
+ handler.postDelayed({
+ if (overlayState == OVERLAY_STATE_INITIAL) {
+ overlayState = OVERLAY_STATE_READY
+ tvOverlayText.text = "开始摇晃,记录心情"
+
+ // 再过2秒后隐藏遮罩
+ handler.postDelayed({
+ hideOverlay()
+ }, OVERLAY_READY_DURATION)
+ }
+ }, OVERLAY_INITIAL_DURATION)
+ }
+
+ /**
+ * 隐藏遮罩
+ */
+ private fun hideOverlay() {
+ if (overlayState != OVERLAY_STATE_HIDDEN) {
+ overlayState = OVERLAY_STATE_HIDDEN
+
+ // 添加淡出动画
+ val fadeOut = AlphaAnimation(1f, 0f)
+ fadeOut.duration = 300
+ fadeOut.setAnimationListener(object : Animation.AnimationListener {
+ override fun onAnimationStart(animation: Animation) {}
+ override fun onAnimationEnd(animation: Animation) {
+ viewOverlay.visibility = View.GONE
+ tvOverlayText.visibility = View.GONE
+ // 开始监听摇晃
+ startShakeDetection()
+ }
+ override fun onAnimationRepeat(animation: Animation) {}
+ })
+ viewOverlay.startAnimation(fadeOut)
+ tvOverlayText.startAnimation(fadeOut)
+ }
+ }
+
+ /**
+ * 开始摇晃检测
+ */
+ private fun startShakeDetection() {
+ if (!isSensorRegistered && accelerometer != null) {
+ sensorManager.registerListener(
+ this,
+ accelerometer,
+ SensorManager.SENSOR_DELAY_NORMAL
+ )
+ isSensorRegistered = true
+ }
+ }
+
+ /**
+ * 停止摇晃检测
+ */
+ private fun stopShakeDetection() {
+ if (isSensorRegistered) {
+ sensorManager.unregisterListener(this)
+ isSensorRegistered = false
+ }
+ }
+
+ /**
+ * 重置UI状态
+ */
+ private fun resetUI() {
+ currentMoodValue = 0
+ tvMoodText.text = "开始!"
+ tvMoodValue.text = moodValueFormatter.format(currentMoodValue)
+ progressBar.progress = 0
+ }
+
+ /**
+ * 结束按钮点击处理
+ */
+ private fun onEndButtonClicked() {
+ stopShakeDetection()
+
+ // 创建心情记录数据
+ val currentTime = System.currentTimeMillis()
+
+ // 跳转到编辑页面
+ EditActivity.startForAdd(
+ context = this,
+ emotion = selectedEmotion!!,
+ moodValue = currentMoodValue,
+ timestamp = currentTime
+ )
+
+ finish()
+ }
+
+ /**
+ * 更新心情值和UI
+ */
+ private fun updateMoodValue(increment: Int) {
+ currentMoodValue = (currentMoodValue + increment).coerceAtMost(maxMoodValue)
+
+ // 更新UI
+ tvMoodValue.text = moodValueFormatter.format(currentMoodValue)
+ progressBar.progress = currentMoodValue
+
+ // 更新心情文案
+ updateMoodText()
+ }
+
+ /**
+ * 更新心情文案
+ */
+ private fun updateMoodText() {
+ val moodText = generateMoodText(currentMoodValue, selectedEmotion!!)
+ tvMoodText.text = moodText
+ }
+
+ /**
+ * 生成心情文案
+ */
+ private fun generateMoodText(value: Int, emotion: Emotion): String {
+ val degree = when {
+ value <= 20 -> "有些"
+ value <= 40 -> "非常"
+ value <= 60 -> "超级"
+ value <= 80 -> "这也太"
+ else -> "完全无法控制"
+ }
+ return "$degree ${emotion.displayName}"
+ }
+
+ /**
+ * 获取情绪对应的图标资源
+ */
+ private fun getEmotionIconRes(emotion: Emotion): Int {
+ return when (emotion) {
+ Emotion.HAPPY -> R.drawable.ic_placeholder_chick_happy
+ Emotion.ANGRY -> R.drawable.ic_placeholder_chick_angry
+ Emotion.SAD -> R.drawable.ic_placeholder_chick_sad
+ Emotion.WORRIED -> R.drawable.ic_placeholder_chick_worried
+ Emotion.LONELY -> R.drawable.ic_placeholder_chick_lonely
+ Emotion.SCARED -> R.drawable.ic_placeholder_chick_scared
+ }
+ }
+
+ // SensorEventListener 回调方法
+ override fun onSensorChanged(event: SensorEvent?) {
+ event?.let {
+ if (it.sensor.type == Sensor.TYPE_ACCELEROMETER) {
+ val currentTime = System.currentTimeMillis()
+
+ // 防止过于频繁的检测
+ if (currentTime - lastShakeTime < SHAKE_COOLDOWN) {
+ return
+ }
+
+ val x = it.values[0]
+ val y = it.values[1]
+ val z = it.values[2]
+
+ // 计算加速度的平方和
+ val accelerationSquare = x * x + y * y + z * z
+
+ // 计算总的加速度强度
+ val acceleration = Math.sqrt(accelerationSquare.toDouble()).toFloat()
+
+ // 检测是否达到摇晃阈值
+ if (acceleration > shakeThreshold) {
+ lastShakeTime = currentTime
+
+ // 提供震动反馈
+ provideVibrationFeedback()
+
+ // 根据摇晃强度计算心情值增量
+ val increment = calculateMoodIncrement(acceleration)
+ updateMoodValue(increment)
+ }
+ }
+ }
+ }
+
+ /**
+ * 提供震动反馈
+ */
+ private fun provideVibrationFeedback() {
+ try {
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+ // Android 8.0及以上使用VibrationEffect
+ val vibrationEffect = VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE)
+ vibrator.vibrate(vibrationEffect)
+ } else {
+ // 旧版本使用传统方法
+ @Suppress("DEPRECATION")
+ vibrator.vibrate(100)
+ }
+ } catch (e: Exception) {
+ // 震动功能失败不影响核心功能
+ Log.d(TAG, "震动反馈失败", e)
+ }
+ }
+
+ /**
+ * 根据摇晃强度计算心情值增量
+ */
+ private fun calculateMoodIncrement(acceleration: Float): Int {
+ // 基础增量 + 根据摇晃强度的额外增量
+ val baseIncrement = MOOD_INCREMENT_BASE
+ val bonusIncrement = ((acceleration - shakeThreshold) / 10).toInt().coerceAtLeast(0)
+ return baseIncrement + bonusIncrement
+ }
+
+ override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
+ // 不需要处理
+ }
+
+ override fun onResume() {
+ super.onResume()
+ // 如果遮罩已经隐藏,重新开始传感器监听
+ if (overlayState == OVERLAY_STATE_HIDDEN) {
+ startShakeDetection()
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ stopShakeDetection()
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ stopShakeDetection()
+ handler.removeCallbacksAndMessages(null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/daodaoshi/chick_mood/EditActivity.kt b/app/src/main/java/com/daodaoshi/chick_mood/EditActivity.kt
index d0316e3..5f07b35 100644
--- a/app/src/main/java/com/daodaoshi/chick_mood/EditActivity.kt
+++ b/app/src/main/java/com/daodaoshi/chick_mood/EditActivity.kt
@@ -1,6 +1,7 @@
package com.daodaoshi.chick_mood
import android.app.Activity
+import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.Editable
@@ -49,6 +50,12 @@ class EditActivity : AppCompatActivity() {
private var currentImagePath: String? = null
private val databaseManager = SimpleDatabaseManager.getInstance(this)
+ // 新增记录模式相关变量
+ private var isAddMode = false
+ private var addModeEmotion: Emotion? = null
+ private var addModeMoodValue: Int = 0
+ private var addModeTimestamp: Long = 0
+
// 图片选择器
private val imagePickerLauncher = registerForActivityResult(
androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult()
@@ -64,6 +71,43 @@ class EditActivity : AppCompatActivity() {
companion object {
private const val MAX_TEXT_LENGTH = 500
private const val TAG = "EditActivity"
+
+ // Intent extra keys
+ private const val EXTRA_RECORD_ID = "record_id"
+ private const val EXTRA_IS_ADD_MODE = "is_add_mode"
+ private const val EXTRA_EMOTION_TYPE = "emotion_type"
+ private const val EXTRA_MOOD_VALUE = "mood_value"
+ private const val EXTRA_TIMESTAMP = "timestamp"
+
+ /**
+ * 启动编辑页面(编辑模式)
+ * @param context 上下文
+ * @param recordId 要编辑的记录ID
+ */
+ fun start(context: Context, recordId: Long) {
+ val intent = Intent(context, EditActivity::class.java).apply {
+ putExtra(EXTRA_RECORD_ID, recordId)
+ putExtra(EXTRA_IS_ADD_MODE, false)
+ }
+ context.startActivity(intent)
+ }
+
+ /**
+ * 启动编辑页面(新增模式)
+ * @param context 上下文
+ * @param emotion 心情类型
+ * @param moodValue 心情值
+ * @param timestamp 时间戳
+ */
+ fun startForAdd(context: Context, emotion: Emotion, moodValue: Int, timestamp: Long) {
+ val intent = Intent(context, EditActivity::class.java).apply {
+ putExtra(EXTRA_IS_ADD_MODE, true)
+ putExtra(EXTRA_EMOTION_TYPE, emotion.name)
+ putExtra(EXTRA_MOOD_VALUE, moodValue)
+ putExtra(EXTRA_TIMESTAMP, timestamp)
+ }
+ context.startActivity(intent)
+ }
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -119,13 +163,53 @@ class EditActivity : AppCompatActivity() {
* 加载心情记录数据
*/
private fun loadData() {
- val recordId = intent.getLongExtra("record_id", -1L)
- if (recordId == -1L) {
- finish()
- return
- }
+ // 检查是否为新增模式
+ isAddMode = intent.getBooleanExtra(EXTRA_IS_ADD_MODE, false)
- loadRecordFromDatabase(recordId)
+ if (isAddMode) {
+ // 新增模式
+ loadAddModeData()
+ } else {
+ // 编辑模式
+ val recordId = intent.getLongExtra("record_id", -1L)
+ if (recordId == -1L) {
+ finish()
+ return
+ }
+ loadRecordFromDatabase(recordId)
+ }
+ }
+
+ /**
+ * 加载新增模式的数据
+ */
+ private fun loadAddModeData() {
+ try {
+ addModeEmotion = intent.getStringExtra(EXTRA_EMOTION_TYPE)?.let {
+ Emotion.valueOf(it)
+ } ?: Emotion.HAPPY
+ addModeMoodValue = intent.getIntExtra(EXTRA_MOOD_VALUE, 0)
+ addModeTimestamp = intent.getLongExtra(EXTRA_TIMESTAMP, System.currentTimeMillis())
+
+ // 创建临时记录用于显示
+ currentRecord = MoodRecord(
+ id = 0, // 临时ID,保存时会重新分配
+ emotion = addModeEmotion!!,
+ moodIntensity = addModeMoodValue,
+ timestamp = addModeTimestamp,
+ textContent = null,
+ imagePath = null,
+ isFavorite = false
+ )
+
+ // 更新UI
+ displayRecord(currentRecord!!)
+ Log.d(TAG, "Add mode data loaded successfully")
+ } catch (e: Exception) {
+ Log.e(TAG, "Error loading add mode data", e)
+ showToast("加载新增模式数据失败")
+ finish()
+ }
}
/**
@@ -354,26 +438,60 @@ class EditActivity : AppCompatActivity() {
CoroutineScope(Dispatchers.IO).launch {
try {
- val updatedRecord = record.copy(
- textContent = if (updatedText.isEmpty()) null else updatedText,
- imagePath = currentImagePath,
- timestamp = record.timestamp // 保持原始时间戳不变
- )
+ if (isAddMode) {
+ // 新增模式:创建新记录
+ val newRecord = MoodRecord(
+ id = 0, // 数据库自动生成ID
+ emotion = record.emotion,
+ moodIntensity = record.moodIntensity,
+ timestamp = record.timestamp,
+ textContent = if (updatedText.isEmpty()) null else updatedText,
+ imagePath = currentImagePath,
+ isFavorite = false
+ )
- databaseManager.updateMoodRecord(updatedRecord)
+ val newId = databaseManager.createMoodRecord(
+ emotion = newRecord.emotion,
+ intensity = newRecord.moodIntensity,
+ noteText = newRecord.textContent ?: "",
+ imagePaths = if (newRecord.imagePath != null) listOf(newRecord.imagePath) else emptyList()
+ )
- withContext(Dispatchers.Main) {
- showToast("保存成功")
+ withContext(Dispatchers.Main) {
+ showToast("保存成功")
- // 直接跳转到首页并传递编辑的记录ID用于定位
- val homeIntent = Intent(this@EditActivity, MainActivitySimple::class.java).apply {
- putExtra("edited_record_id", record.id)
- flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
+ // 跳转到首页并传递新增记录ID用于定位
+ val homeIntent = Intent(this@EditActivity, MainActivitySimple::class.java).apply {
+ putExtra("new_record_id", newId)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ startActivity(homeIntent)
+ finish()
+ }
+ } else {
+ // 编辑模式:更新现有记录
+ val updatedRecord = record.copy(
+ textContent = if (updatedText.isEmpty()) null else updatedText,
+ imagePath = currentImagePath,
+ timestamp = record.timestamp // 保持原始时间戳不变
+ )
+
+ databaseManager.updateMoodRecord(updatedRecord)
+
+ withContext(Dispatchers.Main) {
+ showToast("保存成功")
+
+ // 跳转到首页并传递编辑的记录ID用于定位
+ val homeIntent = Intent(this@EditActivity, MainActivitySimple::class.java).apply {
+ putExtra("edited_record_id", record.id)
+ flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
+ }
+ startActivity(homeIntent)
+ finish()
}
- startActivity(homeIntent)
- finish()
}
} catch (e: Exception) {
+ Log.e(TAG, "Error saving record", e)
withContext(Dispatchers.Main) {
showToast("保存失败")
}
diff --git a/app/src/main/java/com/daodaoshi/chick_mood/MainActivitySimple.kt b/app/src/main/java/com/daodaoshi/chick_mood/MainActivitySimple.kt
index a922f7e..a1b2536 100644
--- a/app/src/main/java/com/daodaoshi/chick_mood/MainActivitySimple.kt
+++ b/app/src/main/java/com/daodaoshi/chick_mood/MainActivitySimple.kt
@@ -154,12 +154,10 @@ class MainActivitySimple : AppCompatActivity() {
Emotion.SCARED -> "害怕"
}
- showTemporaryMessage("你选择了:$emotionName")
-
- // 创建一条测试记录来验证功能
- createMoodRecordWithEmotion(emotion)
-
Log.d(TAG, "用户选择了情绪:$emotionName")
+
+ // 跳转到添加心情页面
+ AddActivity.start(this, emotion)
}
/**
@@ -652,6 +650,12 @@ class MainActivitySimple : AppCompatActivity() {
Log.d(TAG, "检测到编辑完成的记录ID: $editedRecordId")
recordIdToLocate = editedRecordId
}
+
+ val newRecordId = intent.getLongExtra("new_record_id", -1L)
+ if (newRecordId != -1L) {
+ Log.d(TAG, "检测到新增完成的记录ID: $newRecordId")
+ recordIdToLocate = newRecordId
+ }
}
/**
diff --git a/app/src/main/res/drawable/button_primary.xml b/app/src/main/res/drawable/button_primary.xml
new file mode 100644
index 0000000..3823f0c
--- /dev/null
+++ b/app/src/main/res/drawable/button_primary.xml
@@ -0,0 +1,21 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/progress_bar_mood.xml b/app/src/main/res/drawable/progress_bar_mood.xml
new file mode 100644
index 0000000..6a18abf
--- /dev/null
+++ b/app/src/main/res/drawable/progress_bar_mood.xml
@@ -0,0 +1,20 @@
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_add.xml b/app/src/main/res/layout/activity_add.xml
new file mode 100644
index 0000000..a4cc8e5
--- /dev/null
+++ b/app/src/main/res/layout/activity_add.xml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index b0adb93..eb79680 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -40,4 +40,10 @@
#FF5252
#64B5F6
+
+
+ #FFF8E1
+ #FFD954
+ #FFE0B2
+ #80000000
\ No newline at end of file
diff --git a/claude.md b/claude.md
index 220248a..5cc7081 100644
--- a/claude.md
+++ b/claude.md
@@ -6,9 +6,9 @@
**项目名称:** 别摇小鸡心情记录App
**开发平台:** Android原生(Kotlin)
-**当前版本:** V1.3.0
+**当前版本:** V1.4.0
**更新日期:** 2025-10-24
-**开发状态:** ✅ 编辑页功能完成,图片显示系统完善
+**开发状态:** ✅ 添加心情功能完成,摇晃检测和震动反馈集成
---
@@ -20,6 +20,7 @@
- **数据存储:** SQLite Room + SharedPreferences
- **架构模式:** MVVM + Repository
- **动画引擎:** Lottie (准备中) + Property Animation
+- **传感器支持:** 加速度传感器 (摇晃检测)
### 功能模块
**V1.1.0 核心功能:**
@@ -57,8 +58,19 @@
- ✅ 图片选择、保存、加载、删除完整流程
- ✅ 定位机制优化(编辑和新增记录自动定位)
- ✅ 数据一致性修复(禁用额外测试记录)
-- 📋 摇晃检测与心情值计算(待开发)
-- 📋 小鸡动画响应系统(待开发)
+
+**V1.4.0 添加心情功能:**
+- ✅ 添加心情页面基础布局和UI组件(AddActivity + activity_add.xml)
+- ✅ 遮罩引导系统(握紧手机→开始摇晃→自动消失,300ms动画)
+- ✅ 加速度传感器集成和摇晃检测(15f阈值+100ms冷却)
+- ✅ 心情值计算和实时进度更新(2-100分增量算法)
+- ✅ 心情文案生成逻辑(5级程度描述+6种心情类型)
+- ✅ 小鸡形象显示(根据心情类型显示对应图标)
+- ✅ 结束按钮和编辑页跳转逻辑(EditActivity新增模式)
+- ✅ 首页添加按钮与心情选择弹窗集成(完整跳转逻辑)
+- ✅ 完整数据流传递(首页→添加页→编辑页→首页自动定位)
+- ✅ 震动反馈功能(100ms震动,支持新旧Android版本)
+- ✅ 遮罩显示优化(全屏覆盖+文字阴影+28sp字体)
---
@@ -132,14 +144,27 @@
- **模块6.8** ✅ 定位机制优化(编辑和新增记录自动定位)
- **模块6.9** ✅ 数据一致性修复(禁用额外测试记录)
-### 🔄 开发中模块
+### ✅ 已完成模块
-**阶段7:核心功能完善(下一步重点)**
-- **模块7.1** 📋 摇晃检测功能实现
-- **模块7.2** 📋 心情值计算逻辑
-- **模块7.3** 📋 小鸡动画响应系统
-- **模块7.4** 📋 侧边抽屉功能(更多按钮)
-- **模块7.5** 📋 统计页面实现(统计按钮)
+**阶段7:添加心情功能实现(已完成)**
+- **模块7.1** ✅ 添加心情页面基础布局和UI组件
+- **模块7.2** ✅ 遮罩引导系统实现(握紧手机→开始摇晃→自动消失)
+- **模块7.3** ✅ 加速度传感器集成和摇晃检测逻辑
+- **模块7.4** ✅ 心情值计算和实时进度更新系统
+- **模块7.5** ✅ 心情文案生成逻辑(基于心情值+心情类型)
+- **模块7.6** ✅ 小鸡形象显示(根据心情类型)
+- **模块7.7** ✅ 结束按钮和编辑页跳转逻辑
+- **模块7.8** ✅ 首页添加按钮与心情选择弹窗集成
+- **模块7.9** ✅ 完整数据流传递(首页→添加页→编辑页→首页)
+
+### 🔄 后续开发计划
+
+**阶段8:功能完善和优化(下一阶段)**
+- **模块8.1** 📋 小鸡动画响应系统
+- **模块8.2** 📋 侧边抽屉功能(更多按钮)
+- **模块8.3** 📋 统计页面实现(统计按钮)
+- **模块8.4** 📋 摇晃检测参数调优和设备适配
+- **模块8.5** 📋 用户体验细节优化和错误处理完善
---
@@ -170,68 +195,95 @@
## 🎯 下一步开发计划
-### 优先级1:详情页功能实现(当前重点)
-**模块5.1:详情页基础布局和UI组件**
-- 创建DetailActivity和对应布局文件
-- 实现顶部导航栏(返回、时间、更多操作)
-- 实现内容区域布局(小鸡形象、心情值、文案、配图、文本)
-- 支持四种内容状态(有图有文、有图无文、无图有文、无图无文)
+### 优先级1:添加心情页面实现(当前重点)
-**模块5.2:心情文案生成逻辑**
-- 实现心情值到程度描述的映射逻辑
-- 动态生成"程度+心情类型"组合文案
-- 心情值范围:0-20(有些) → 20-40(非常) → 40-60(超级) → 60-80(这也太) → 80-100(完全无法控制)
+**模块7.1:添加心情页面基础布局和UI组件**
+- 创建AddActivity和对应布局文件activity_add.xml
+- 实现顶部导航栏(返回按钮、标题"添加心情")
+- 实现内容区域布局(心情文案、心情值、进度条、小鸡形象)
+- 实现底部结束按钮和遮罩引导层
-**模块5.3:更多操作弹窗功能**
-- 实现底部弹窗布局(编辑、收藏、分享、删除)
-- 弹窗动画效果和交互逻辑
-- 各操作按钮的状态管理和点击响应
+**模块7.2:遮罩引导系统实现**
+- 创建遮罩布局引导用户操作流程
+- 实现定时器控制:握紧手机(2s) → 开始摇晃(2s) → 自动消失
+- 添加遮罩动画效果(淡入淡出)
+- 处理用户点击遮罩的交互逻辑
-**模块5.4:删除功能和二次确认弹窗**
-- 实现删除确认弹窗布局和交互
-- 数据库记录删除操作
-- 删除成功提示和页面跳转逻辑
+**模块7.3:加速度传感器集成和摇晃检测**
+- 集成Android加速度传感器(SensorManager)
+- 实现传感器事件监听和数据采集
+- 开发摇晃检测算法(强度计算、阈值过滤)
+- 添加传感器权限检查和错误处理
-**模块5.5:收藏功能和状态持久化**
-- 数据库添加收藏字段支持
-- 收藏状态切换和UI反馈
-- 收藏状态持久化存储
+**模块7.4:心情值计算和实时进度更新系统**
+- 开发心情值累计算法(基于摇晃强度和时长)
+- 实现进度条实时更新UI组件
+- 添加心情值上限控制(最高100)
+- 优化更新频率,平衡性能和用户体验
-**模块5.6:图片放大查看功能**
-- 实现图片点击放大预览
-- 支持手势缩放和拖拽
-- 1:1比例显示,图片自适应
+**模块7.5:心情文案生成逻辑**
+- 复用详情页的心情文案生成逻辑
+- 根据实时心情值更新程度描述
+- 实现文案动态切换动画效果
+- 确保文案与心情值同步更新
-**模块5.7:分享功能集成**
-- 集成Android系统分享功能
-- 生成分享文本内容
-- 跳转系统分享选择器
+**模块7.6:小鸡形象显示**
+- 根据传入的心情类型显示对应小鸡图标
+- 复用现有的心情类型图标资源
+- 添加小鸡形象的显示动画(可选)
-### 优先级2:核心交互功能(摇晃检测)
-**模块6.1:摇晃检测功能实现**
-- 实现手机摇晃传感器监听
-- 摇晃强度和持续时间计算
-- 摇晃阈值设置和优化
+**模块7.7:结束按钮和编辑页跳转逻辑**
+- 实现结束按钮点击事件处理
+- 准备跳转数据(心情类型、心情值、时间戳)
+- 修改EditActivity支持新增记录模式
+- 实现AddActivity到EditActivity的数据传递
-**模块6.2:心情值计算逻辑**
-- 根据摇晃参数计算心情强度值
-- 心情强度映射到情绪等级
-- 心情值与情绪选择的关联
+**模块7.8:首页添加按钮与心情选择弹窗集成**
+- 修改MainActivity的添加按钮逻辑
+- 修改心情选择弹窗的确认逻辑
+- 实现MainActivity到AddActivity的跳转
+- 传递心情类型数据到AddActivity
-### 优先级3:动画系统完善
-**模块6.3:小鸡动画响应系统**
+**模块7.9:完整数据流传递优化**
+- 测试完整流程:首页→添加页→编辑页→首页
+- 优化EditActivity的新增记录模式
+- 确保首页自动定位到新增记录
+- 修复数据传递中的边界情况
+
+### 优先级2:功能完善和优化(后续开发)
+
+**模块8.1:摇晃检测优化**
+- 调整摇晃检测灵敏度参数
+- 添加不同设备的适配逻辑
+- 优化传感器数据处理的性能
+- 添加摇晃检测的用户反馈优化
+
+**模块8.2:用户体验优化**
+- 添加页面切换动画效果
+- 优化遮罩引导的视觉体验
+- 添加摇晃过程的音效反馈(可选)
+- 完善错误状态的提示信息
+
+**模块8.3:测试和稳定性**
+- 编写摇晃检测的单元测试
+- 测试不同设备上的传感器兼容性
+- 添加异常情况的处理逻辑
+- 进行完整的集成测试
+
+### 优先级3:扩展功能(未来开发)
+
+**模块9.1:小鸡动画响应系统**
- 小鸡待机动画(Lottie集成)
- 摇晃时的小鸡反应动画
- 不同情绪对应的小鸡状态动画
- 点击小鸡的交互反馈动画
-### 优先级4:页面功能扩展
-**模块6.4:侧边抽屉功能(更多按钮)**
+**模块9.2:侧边抽屉功能(更多按钮)**
- 实现侧边抽屉UI布局
- 设置、关于、帮助等页面入口
- 用户个人资料管理
-**模块6.5:统计页面实现(统计按钮)**
+**模块9.3:统计页面实现(统计按钮)**
- 心情数据统计分析
- 情绪趋势图表展示
- 记录统计和可视化
@@ -325,6 +377,20 @@ Chick_Mood/
## 🔄 更新记录
+**2025-10-24 (V1.4.0 添加心情功能完成)**
+- ✅ **AddActivity完整实现**:包含完整的摇晃检测和心情记录功能
+- ✅ **遮罩引导系统**:2秒"握紧手机" → 2秒"开始摇晃,记录心情" → 自动消失,300ms流畅动画
+- ✅ **加速度传感器集成**:摇晃检测算法(15f阈值+100ms冷却+强度过滤)
+- ✅ **心情值计算系统**:基础增量2分+强度加成,0-100范围实时累计更新
+- ✅ **心情文案生成**:5级程度描述(有些/非常/超级/这也太/完全无法控制)+6种心情类型
+- ✅ **实时UI更新**:进度条、数值、文案同步更新,提供即时反馈
+- ✅ **震动反馈功能**:每次有效摇晃提供100ms震动反馈,支持新旧Android版本
+- ✅ **EditActivity新增模式**:支持新增记录的数据处理和保存逻辑
+- ✅ **完整数据流集成**:首页→添加页→编辑页→首页的完整循环和自动定位
+- ✅ **遮罩显示优化**:全屏覆盖+文字阴影+28sp字体,确保清晰可读
+- ✅ **权限管理**:添加震动权限,完善传感器权限检查
+- ✅ **错误处理完善**:无传感器Toast提示,震动失败不影响核心功能
+
**2025-10-24 (V1.3.0 编辑页功能完成)**
- ✅ **编辑页完整实现**:包含基础布局、UI组件和退出确认机制
- ✅ **返回键退出确认逻辑**:检测编辑行为,弹出二次确认弹窗
@@ -465,4 +531,103 @@ Chick_Mood/
---
+## 📄 添加心情页面功能详细说明
+
+### 🎯 功能概述
+添加心情页面是通过摇晃手机来记录心情强度的核心功能页面,用户通过摇晃动作来量化心情程度,然后跳转到编辑页完成最终记录。
+
+### 🔄 完整交互流程
+```
+首页 → 点击添加按钮 → 心情选择弹窗 → 选择心情类型 → 添加心情页面 → 握紧提示(2s) → 摇晃提示(2s) → 遮罩消失 → 用户摇晃 → 实时显示进度 → 点击结束按钮 → 编辑页面 → 编辑文本/图片 → 保存 → 首页(自动定位到新记录)
+```
+
+### 📱 页面结构与状态
+
+#### 1. 顶部区域
+- **返回按钮:** 左上角,点击返回上一页(首页)
+- **标题显示:** 添加心情(页面标题)
+
+#### 2. 信息显示区域
+- **心情文案区域:**
+ - 默认状态:显示"开始!"
+ - 摇晃状态:显示"程度+心情类型"组合文案
+ - 程度映射:0-20(有些) → 20-40(非常) → 40-60(超级) → 60-80(这也太) → 80-100(完全无法控制)
+ - 示例:心情值88 + 开心 = "完全无法控制 开心"
+
+- **心情值显示:**
+ - 数值范围:0-100
+ - 根据摇晃强度和时长从0开始累计
+ - 实时更新显示
+
+- **进度条:**
+ - 根据心情值实时更新进度
+ - 视觉反馈摇晃强度
+
+- **小鸡形象:**
+ - 根据心情类型显示对应图标
+ - 暂不根据心情值变化(与详情页保持一致)
+
+#### 3. 结束按钮
+- **位置:** 页面底部
+- **功能:** 点击跳转到编辑页面
+- **数据传递:** 携带心情类型、心情值、时间等信息
+
+#### 4. 遮罩引导系统
+- **第一阶段(0-2秒):** 显示"握紧手机"
+- **第二阶段(2-4秒):** 显示"开始摇晃,记录心情"
+- **第三阶段(4秒后):** 遮罩自动消失
+
+### 🔧 技术实现要点
+
+#### 传感器监听
+- **加速度传感器:** 监听手机摇晃动作
+- **摇晃强度计算:** 根据传感器数据计算摇晃强度
+- **阈值过滤:** 只有达到一定强度的摇晃才累计心情值
+- **错误处理:** 无传感器时Toast提示"无传感器"
+
+#### 心情值计算
+- **累计逻辑:** 根据摇晃强度和持续时间累计心情值
+- **上限控制:** 最高累计到100,不再增加
+- **实时更新:** 心情值和进度条实时反馈
+
+#### 数据流传递
+- **首页→添加页:** 心情类型数据通过Intent传递
+- **添加页→编辑页:** 心情类型、心情值、时间数据传递
+- **编辑页→首页:** 保存后返回首页并自动定位到新记录
+
+### 📝 页面状态管理
+
+#### 初始状态
+- 遮罩显示"握紧手机"
+- 心情值显示0
+- 进度条为空
+- 小鸡形象根据传入的心情类型显示
+
+#### 准备状态
+- 遮罩显示"开始摇晃,记录心情"
+- 其他UI元素保持初始状态
+
+#### 摇晃检测状态
+- 遮罩消失
+- 文案显示"开始!"
+- 等待用户摇晃动作
+
+#### 摇晃进行状态
+- 实时更新心情文案(程度+心情类型)
+- 心情值实时累计
+- 进度条实时更新
+- 小鸡形象保持不变
+
+#### 完成状态
+- 用户点击结束按钮
+- 携带所有数据跳转到编辑页面
+
+### 🚨 注意事项
+1. **传感器权限:** 需要确保应用有传感器使用权限
+2. **性能优化:** 传感器数据更新频率需要合理控制,避免过度消耗电量
+3. **用户体验:** 摇晃检测灵敏度需要平衡,既不能太敏感也不能太迟钝
+4. **数据一致性:** 确保整个流程中数据传递的准确性和完整性
+
+---
+
*此文档将随着开发进展持续更新,记录重要的技术决策和进度变化。*
\ No newline at end of file
diff --git a/project_img/添加心情.png b/project_img/添加心情.png
deleted file mode 100644
index af7c87e..0000000
Binary files a/project_img/添加心情.png and /dev/null differ
diff --git a/project_img/添加心情/开始摇晃@1x.png b/project_img/添加心情/开始摇晃@1x.png
new file mode 100644
index 0000000..991239d
Binary files /dev/null and b/project_img/添加心情/开始摇晃@1x.png differ
diff --git a/project_img/添加心情/握紧手机提示@1x.png b/project_img/添加心情/握紧手机提示@1x.png
new file mode 100644
index 0000000..ea10560
Binary files /dev/null and b/project_img/添加心情/握紧手机提示@1x.png differ
diff --git a/project_img/添加心情/摇晃手机提示@1x.png b/project_img/添加心情/摇晃手机提示@1x.png
new file mode 100644
index 0000000..59f56b2
Binary files /dev/null and b/project_img/添加心情/摇晃手机提示@1x.png differ
diff --git a/project_img/添加心情/摇晃进度@1x.png b/project_img/添加心情/摇晃进度@1x.png
new file mode 100644
index 0000000..badebb2
Binary files /dev/null and b/project_img/添加心情/摇晃进度@1x.png differ