首页ui调了一点

This commit is contained in:
ddshi 2025-10-24 17:08:08 +08:00
parent 43056b245f
commit 874b83b5a2
84 changed files with 664 additions and 142 deletions

View File

@ -19,7 +19,12 @@
"Bash(git init:*)", "Bash(git init:*)",
"Bash(rd:*)", "Bash(rd:*)",
"Bash(git add:*)", "Bash(git add:*)",
"Bash(git commit:*)" "Bash(git commit:*)",
"Bash(mkdir:*)",
"Bash(magick:*)",
"Bash(convert:*)",
"Bash(python:*)",
"Bash(rm:*)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

View File

@ -0,0 +1,56 @@
package com.chick_mood.ui.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chick_mood.data.model.Emotion
import com.daodaoshi.chick_mood.databinding.ItemChickImageBinding
/**
* 小鸡形象适配器
* 用于展示不同情绪对应的小鸡图标
*/
class ChickImageAdapter : RecyclerView.Adapter<ChickImageAdapter.ChickImageViewHolder>() {
private var emotions: List<Emotion> = emptyList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChickImageViewHolder {
val binding = ItemChickImageBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return ChickImageViewHolder(binding)
}
override fun onBindViewHolder(holder: ChickImageViewHolder, position: Int) {
holder.bind(emotions[position])
}
override fun getItemCount(): Int = emotions.size
/**
* 更新数据
*/
fun updateData(newEmotions: List<Emotion>) {
emotions = newEmotions
notifyDataSetChanged()
}
inner class ChickImageViewHolder(
private val binding: ItemChickImageBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(emotion: Emotion) {
// 根据情绪类型设置对应的小鸡图标
val chickDrawable = when (emotion) {
Emotion.HAPPY -> com.daodaoshi.chick_mood.R.drawable.ic_placeholder_chick_happy
Emotion.SAD -> com.daodaoshi.chick_mood.R.drawable.ic_placeholder_chick_sad
Emotion.ANGRY -> com.daodaoshi.chick_mood.R.drawable.ic_placeholder_chick_angry
Emotion.WORRIED -> com.daodaoshi.chick_mood.R.drawable.ic_placeholder_chick_worried
Emotion.LONELY -> com.daodaoshi.chick_mood.R.drawable.ic_placeholder_chick_lonely
Emotion.SCARED -> com.daodaoshi.chick_mood.R.drawable.ic_placeholder_chick_scared
}
binding.ivChick.setImageResource(chickDrawable)
}
}
}

View File

@ -0,0 +1,133 @@
package com.chick_mood.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.chick_mood.data.model.MoodRecord
import com.chick_mood.utils.MoodDescriptionGenerator
import com.daodaoshi.chick_mood.databinding.ItemMoodCardBinding
/**
* 心情卡片适配器
* 用于展示心情记录的详细信息卡片
*/
class MoodCardAdapter(
private val onCardClick: (MoodRecord) -> Unit,
private val onDetailClick: (MoodRecord) -> Unit,
private val onFavoriteClick: (MoodRecord) -> Unit,
private val onShareClick: (MoodRecord) -> Unit
) : RecyclerView.Adapter<MoodCardAdapter.MoodCardViewHolder>() {
private var moodRecords: List<MoodRecord> = emptyList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MoodCardViewHolder {
val binding = ItemMoodCardBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
return MoodCardViewHolder(binding)
}
override fun onBindViewHolder(holder: MoodCardViewHolder, position: Int) {
holder.bind(moodRecords[position])
}
override fun getItemCount(): Int = moodRecords.size
/**
* 更新数据
*/
fun updateData(newRecords: List<MoodRecord>) {
moodRecords = newRecords
notifyDataSetChanged()
}
/**
* 获取当前数据
*/
fun getData(): List<MoodRecord> = moodRecords
inner class MoodCardViewHolder(
private val binding: ItemMoodCardBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(record: MoodRecord) {
// 设置心情文案
val moodDescription = MoodDescriptionGenerator.generateMoodDescription(
record.moodIntensity, record.emotion
)
binding.tvMoodDescription.text = moodDescription
// 设置收藏状态
updateFavoriteIcon(record.isFavorite)
// 处理文本和图片内容的显示逻辑
val hasText = !record.textContent.isNullOrEmpty()
val hasImage = !record.imagePath.isNullOrEmpty()
if (hasText && hasImage) {
// 有图有文:图片在左,文本在右
binding.ivImage.visibility = View.VISIBLE
binding.tvTextContent.visibility = View.VISIBLE
binding.llMainContent.orientation = LinearLayout.HORIZONTAL
binding.ivImage.layoutParams = LinearLayout.LayoutParams(80, 80).apply {
marginEnd = 12
}
binding.tvTextContent.text = record.textContent
// TODO: 加载真实图片
binding.ivImage.setImageResource(com.daodaoshi.chick_mood.R.drawable.placeholder_background)
} else if (hasImage && !hasText) {
// 有图无文:图片居中显示
binding.ivImage.visibility = View.VISIBLE
binding.tvTextContent.visibility = View.GONE
binding.llMainContent.orientation = LinearLayout.VERTICAL
binding.llMainContent.gravity = android.view.Gravity.CENTER
binding.ivImage.layoutParams = LinearLayout.LayoutParams(120, 120).apply {
marginEnd = 0
}
// TODO: 加载真实图片
binding.ivImage.setImageResource(com.daodaoshi.chick_mood.R.drawable.placeholder_background)
} else if (hasText && !hasImage) {
// 无图有文:文本占满整个内容区域
binding.ivImage.visibility = View.GONE
binding.tvTextContent.visibility = View.VISIBLE
binding.llMainContent.orientation = LinearLayout.VERTICAL
binding.tvTextContent.text = record.textContent
} else {
// 无图无文:隐藏内容区域
binding.ivImage.visibility = View.GONE
binding.tvTextContent.visibility = View.GONE
}
// 设置点击事件
binding.root.setOnClickListener {
onCardClick(record)
}
binding.btnDetail.setOnClickListener {
onDetailClick(record)
}
binding.btnFavorite.setOnClickListener {
onFavoriteClick(record)
// 更新收藏状态显示
updateFavoriteIcon(!record.isFavorite)
}
binding.btnShare.setOnClickListener {
onShareClick(record)
}
}
private fun updateFavoriteIcon(isFavorite: Boolean) {
val favoriteIcon = if (isFavorite) {
com.daodaoshi.chick_mood.R.drawable.ic_card_favorite_filled
} else {
com.daodaoshi.chick_mood.R.drawable.ic_card_favorite_border
}
binding.btnFavorite.setImageResource(favoriteIcon)
}
}
}

View File

@ -0,0 +1,54 @@
package com.chick_mood.utils
import com.chick_mood.data.model.Emotion
/**
* 心情文案生成器
* 根据心情值和情绪类型生成"程度+心情类型"的文案
*/
object MoodDescriptionGenerator {
/**
* 生成心情文案
* @param intensity 心情值 (0-100)
* @param emotion 情绪类型
* @return 心情文案格式程度+情绪类型
*/
fun generateMoodDescription(intensity: Int, emotion: Emotion): String {
val degree = getDegreeDescription(intensity)
val emotionName = getEmotionName(emotion)
return "$degree $emotionName"
}
/**
* 根据心情值获取程度描述
* @param intensity 心情值 (0-100)
* @return 程度描述
*/
private fun getDegreeDescription(intensity: Int): String {
return when (intensity) {
in 0..20 -> "有些"
in 21..40 -> "非常"
in 41..60 -> "超级"
in 61..80 -> "这也太"
in 81..100 -> "完全无法控制"
else -> "有些"
}
}
/**
* 获取情绪名称
* @param emotion 情绪类型
* @return 情绪中文名称
*/
private fun getEmotionName(emotion: Emotion): String {
return when (emotion) {
Emotion.HAPPY -> "开心"
Emotion.SAD -> "悲伤"
Emotion.ANGRY -> "生气"
Emotion.WORRIED -> "烦恼"
Emotion.LONELY -> "孤单"
Emotion.SCARED -> "害怕"
}
}
}

View File

@ -11,7 +11,8 @@ import com.daodaoshi.chick_mood.databinding.ActivityMainBinding
import com.chick_mood.data.database.DatabaseTestHelper import com.chick_mood.data.database.DatabaseTestHelper
import com.chick_mood.data.database.SimpleDatabaseManager import com.chick_mood.data.database.SimpleDatabaseManager
import com.chick_mood.ui.emotion.EmotionSelectorDialog import com.chick_mood.ui.emotion.EmotionSelectorDialog
import com.chick_mood.ui.adapter.MoodRecordAdapter import com.chick_mood.ui.adapter.MoodCardAdapter
import com.chick_mood.ui.adapter.ChickImageAdapter
import com.chick_mood.data.model.Emotion import com.chick_mood.data.model.Emotion
import com.chick_mood.data.model.MoodRecord import com.chick_mood.data.model.MoodRecord
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -20,6 +21,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import com.chick_mood.utils.MoodDescriptionGenerator
/** /**
* 简化的首页Activity - 主要用于展示历史心情记录和创建新记录的入口 * 简化的首页Activity - 主要用于展示历史心情记录和创建新记录的入口
@ -40,7 +42,8 @@ class MainActivitySimple : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private lateinit var timeFormatter: SimpleDateFormat private lateinit var timeFormatter: SimpleDateFormat
private lateinit var moodRecordAdapter: MoodRecordAdapter private lateinit var moodCardAdapter: MoodCardAdapter
private lateinit var chickImageAdapter: ChickImageAdapter
private var recordIdToLocate: Long = -1L private var recordIdToLocate: Long = -1L
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -57,14 +60,14 @@ class MainActivitySimple : AppCompatActivity() {
// 初始化UI组件 // 初始化UI组件
initViews() initViews()
// 初始化ViewPager2适配器 // 初始化适配器
initMoodRecordAdapter() initAdapters()
// 数据库测试已禁用,避免创建额外的测试记录 // 数据库测试已禁用,避免创建额外的测试记录
// runDatabaseTest() // runDatabaseTest()
// 创建测试数据(如果数据库为空) // 测试数据已移除,用户可以通过添加心情功能创建真实数据
createTestDataIfNeeded() // createTestDataIfNeeded()
// 加载历史记录数据 // 加载历史记录数据
loadMoodRecords() loadMoodRecords()
@ -209,12 +212,56 @@ class MainActivitySimple : AppCompatActivity() {
} }
/** /**
* 更新时间指示器 * 更新时间信息
*/ */
private fun updateTimeIndicator(timestamp: Long) { private fun updateTimeInfo(position: Int) {
// TODO: 实现时间更新功能 - 暂时注释掉 val records = moodCardAdapter.getData()
// val formattedTime = timeFormatter.format(Date(timestamp)) if (position < records.size) {
// binding.tvTimeIndicator.text = formattedTime val record = records[position]
// 获取当前日期(用于比较)
val now = Calendar.getInstance()
val recordDate = Calendar.getInstance().apply {
timeInMillis = record.timestamp
}
// 比较日期
val weekdayText = when {
isSameDay(now, recordDate) -> "今天"
isYesterday(now, recordDate) -> "昨天"
else -> {
val weekdays = arrayOf("", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六")
weekdays[recordDate.get(Calendar.DAY_OF_WEEK)]
}
}
// 获取时间
val time = String.format("%02d:%02d",
recordDate.get(Calendar.HOUR_OF_DAY),
recordDate.get(Calendar.MINUTE))
binding.tvWeekday.text = weekdayText
binding.tvTime.text = time
}
}
/**
* 判断是否为同一天
*/
private fun isSameDay(cal1: Calendar, cal2: Calendar): Boolean {
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR)
}
/**
* 判断是否为昨天
*/
private fun isYesterday(now: Calendar, recordDate: Calendar): Boolean {
val yesterday = Calendar.getInstance().apply {
timeInMillis = now.timeInMillis
add(Calendar.DAY_OF_YEAR, -1)
}
return isSameDay(yesterday, recordDate)
} }
/** /**
@ -222,9 +269,9 @@ class MainActivitySimple : AppCompatActivity() {
*/ */
private fun showEmptyStateUI() { private fun showEmptyStateUI() {
binding.llEmptyState.isVisible = true binding.llEmptyState.isVisible = true
// TODO: 其他视图状态设置 - 暂时注释掉 binding.llTimeInfo.isVisible = false
// binding.vpHistoryRecords.isVisible = false binding.flChickContainer.isVisible = false
// binding.tvTimeIndicator.isVisible = false binding.vpMoodCards.isVisible = false
} }
/** /**
@ -232,12 +279,9 @@ class MainActivitySimple : AppCompatActivity() {
*/ */
private fun showContentStateUI() { private fun showContentStateUI() {
binding.llEmptyState.isVisible = false binding.llEmptyState.isVisible = false
// TODO: 其他视图状态设置 - 暂时注释掉 binding.llTimeInfo.isVisible = true
// binding.vpHistoryRecords.isVisible = true binding.flChickContainer.isVisible = true
// binding.tvTimeIndicator.isVisible = true binding.vpMoodCards.isVisible = true
// TODO: 设置ViewPager2数据
// binding.vpHistoryRecords.adapter = null
} }
/** /**
@ -274,15 +318,20 @@ class MainActivitySimple : AppCompatActivity() {
} }
/** /**
* 初始化心情记录适配器 * 初始化适配器
*/ */
private fun initMoodRecordAdapter() { private fun initAdapters() {
moodRecordAdapter = MoodRecordAdapter( // 初始化心情卡片适配器
onItemClick = { record -> moodCardAdapter = MoodCardAdapter(
onCardClick = { record ->
// 点击记录卡片 - 跳转到详情页 // 点击记录卡片 - 跳转到详情页
Log.d(TAG, "点击了心情记录: ${record.emotion}") Log.d(TAG, "点击了心情记录: ${record.emotion}")
showMoodRecordDetail(record) showMoodRecordDetail(record)
}, },
onDetailClick = { record ->
// 查看详情
showMoodRecordDetail(record)
},
onFavoriteClick = { record -> onFavoriteClick = { record ->
// 收藏/取消收藏 // 收藏/取消收藏
toggleFavorite(record) toggleFavorite(record)
@ -290,24 +339,40 @@ class MainActivitySimple : AppCompatActivity() {
onShareClick = { record -> onShareClick = { record ->
// 分享记录 // 分享记录
shareMoodRecord(record) shareMoodRecord(record)
},
onDetailClick = { record ->
// 查看详情
showMoodRecordDetail(record)
} }
) )
binding.vpHistoryRecords.adapter = moodRecordAdapter binding.vpMoodCards.adapter = moodCardAdapter
binding.vpHistoryRecords.orientation = ViewPager2.ORIENTATION_HORIZONTAL binding.vpMoodCards.orientation = ViewPager2.ORIENTATION_HORIZONTAL
// 设置页面变化回调,用于更新时间指示器 // 初始化小鸡形象适配器
binding.vpHistoryRecords.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { chickImageAdapter = ChickImageAdapter()
binding.vpChickImages.adapter = chickImageAdapter
binding.vpChickImages.orientation = ViewPager2.ORIENTATION_HORIZONTAL
// 设置页面变化回调保持两个ViewPager2同步
binding.vpMoodCards.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
super.onPageSelected(position) super.onPageSelected(position)
if (position < moodRecordAdapter.itemCount) { // 同步小鸡形象位置
// 当有记录时,更新时间指示器显示当前选中记录的时间 if (position < chickImageAdapter.itemCount) {
// updateTimeIndicator(moodRecordAdapter.moodRecords[position].timestamp) binding.vpChickImages.setCurrentItem(position, false)
} }
// 更新时间信息
updateTimeInfo(position)
}
})
// 为小鸡形象ViewPager2也添加页面变化回调实现双向同步
binding.vpChickImages.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
// 同步心情卡片位置
if (position < moodCardAdapter.itemCount) {
binding.vpMoodCards.setCurrentItem(position, false)
}
// 更新时间信息
updateTimeInfo(position)
} }
}) })
} }
@ -319,14 +384,23 @@ class MainActivitySimple : AppCompatActivity() {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
try { try {
val dbManager = SimpleDatabaseManager.getInstance(this@MainActivitySimple) val dbManager = SimpleDatabaseManager.getInstance(this@MainActivitySimple)
val records = dbManager.getRecentMoodRecords(50) // 获取最近50条记录 val records = dbManager.getRecentMoodRecords(50) // 获取最近50条记录
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if (records.isEmpty()) { if (records.isEmpty()) {
showEmptyStateUI() showEmptyStateUI()
} else { } else {
showContentStateUI() showContentStateUI()
moodRecordAdapter.updateData(records)
// 更新心情卡片适配器
moodCardAdapter.updateData(records)
// 更新小鸡形象适配器
val emotions = records.map { it.emotion }
chickImageAdapter.updateData(emotions)
// 更新时间信息(显示第一条记录的时间)
updateTimeInfo(0)
// 检查是否需要定位记录 // 检查是否需要定位记录
checkAndLocateEditedRecord() checkAndLocateEditedRecord()
@ -350,16 +424,14 @@ class MainActivitySimple : AppCompatActivity() {
private fun toggleFavorite(record: MoodRecord) { private fun toggleFavorite(record: MoodRecord) {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
try { try {
// 创建更新后的记录(注意:这里需要修改数据模型支持更新) val dbManager = SimpleDatabaseManager.getInstance(this@MainActivitySimple)
val updatedRecord = record.copy(isFavorite = !record.isFavorite) val updatedRecord = record.copy(isFavorite = !record.isFavorite)
dbManager.updateMoodRecord(updatedRecord)
// TODO: 实现数据库更新功能
// SimpleDatabaseManager.updateMoodRecord(updatedRecord)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
// 重新加载数据 // 重新加载数据以更新UI状态
loadMoodRecords() loadMoodRecords()
val message = if (updatedRecord.isFavorite) "已收藏" else "已取消收藏" val message = if (!record.isFavorite) "已收藏" else "已取消收藏"
showTemporaryMessage(message) showTemporaryMessage(message)
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -610,26 +682,26 @@ class MainActivitySimple : AppCompatActivity() {
Log.d(TAG, "开始定位记录ID: $recordId") Log.d(TAG, "开始定位记录ID: $recordId")
// 确保ViewPager2已经准备好 // 确保ViewPager2已经准备好
binding.vpHistoryRecords.post { binding.vpMoodCards.post {
// 从适配器获取最新数据 // 从适配器获取最新数据
val records = moodRecordAdapter.getData() val records = moodCardAdapter.getData()
Log.d(TAG, "当前适配器数据量: ${records.size}") Log.d(TAG, "当前适配器数据量: ${records.size}")
val position = records.indexOfFirst { record -> record.id == recordId } val position = records.indexOfFirst { record -> record.id == recordId }
Log.d(TAG, "查找记录ID $recordId,找到位置: $position") Log.d(TAG, "查找记录ID $recordId,找到位置: $position")
if (position != -1 && position < moodRecordAdapter.itemCount) { if (position != -1 && position < moodCardAdapter.itemCount) {
// 使用setCurrentItem定位第二个参数为true表示平滑滚动 // 使用setCurrentItem定位第二个参数为true表示平滑滚动
binding.vpHistoryRecords.setCurrentItem(position, true) binding.vpMoodCards.setCurrentItem(position, true)
Log.d(TAG, "已定位到位置: $position") Log.d(TAG, "已定位到位置: $position")
// 延迟一点再次确认定位,确保定位成功 // 延迟一点再次确认定位,确保定位成功
binding.vpHistoryRecords.postDelayed({ binding.vpMoodCards.postDelayed({
val currentPosition = binding.vpHistoryRecords.currentItem val currentPosition = binding.vpMoodCards.currentItem
Log.d(TAG, "定位后当前位置: $currentPosition") Log.d(TAG, "定位后当前位置: $currentPosition")
if (currentPosition != position) { if (currentPosition != position) {
Log.w(TAG, "定位可能不准确,尝试重新定位") Log.w(TAG, "定位可能不准确,尝试重新定位")
binding.vpHistoryRecords.setCurrentItem(position, true) binding.vpMoodCards.setCurrentItem(position, true)
} }
}, 300) }, 300)
} else { } else {

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="90dp" />
<solid android:color="#FFAC46" />
</shape>
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<!-- 简单的圆形背景 -->
<path
android:fillColor="#FFF8E1"
android:pathData="M54,6c26.5,0 48,21.5 48,48c0,26.5 -21.5,48 -48,48c-26.5,0 -48,-21.5 -48,-48C6,27.5 27.5,6 54,6z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -24,29 +24,19 @@
android:id="@+id/btn_more" android:id="@+id/btn_more"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:src="@drawable/ic_more" android:src="@drawable/ic_home_more"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:layout_gravity="start" android:layout_gravity="start"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:contentDescription="更多功能" /> android:contentDescription="更多功能" />
<!-- 标题 -->
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="今日"
android:textSize="18sp"
android:textColor="@color/text_primary"
android:textStyle="bold"
android:layout_gravity="center" />
<!-- 统计按钮 --> <!-- 统计按钮 -->
<ImageView <ImageView
android:id="@+id/btn_statistics" android:id="@+id/btn_statistics"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:src="@drawable/ic_statistics" android:src="@drawable/ic_home_statistics"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
@ -54,86 +44,129 @@
</androidx.appcompat.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
<!-- 时间指示器 --> <!-- 时间信息区域 -->
<TextView <LinearLayout
android:id="@+id/tv_time_indicator" android:id="@+id/ll_time_info"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:textSize="16sp" android:orientation="vertical"
android:textColor="@color/text_secondary"
android:gravity="center" android:gravity="center"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/toolbar" app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:text="2024.07.15 星期一 12:30" />
<!-- 历史记录展示区域 -->
<FrameLayout
android:id="@+id/fl_history_container"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="80dp"
app:layout_constraintTop_toBottomOf="@id/tv_time_indicator"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"> app:layout_constraintEnd_toEndOf="parent">
<!-- ViewPager2 用于历史记录卡片 --> <!-- 星期数 -->
<TextView
android:id="@+id/tv_weekday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/text_primary"
tools:text="星期一" />
<!-- 具体时间 -->
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textSize="14sp"
android:textColor="@color/text_secondary"
tools:text="14:30" />
</LinearLayout>
<!-- 小鸡形象区域 -->
<FrameLayout
android:id="@+id/fl_chick_container"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_marginTop="40dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/ll_time_info"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- ViewPager2 用于小鸡形象切换 -->
<androidx.viewpager2.widget.ViewPager2 <androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_history_records" android:id="@+id/vp_chick_images"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="horizontal" /> android:orientation="horizontal" />
<!-- 空状态页面 (默认隐藏) -->
<LinearLayout
android:id="@+id/ll_empty_state"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:visibility="gone">
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:src="@drawable/ic_empty_chick"
android:layout_marginBottom="16dp"
android:contentDescription="空白状态小鸡" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="还没有心情记录"
android:textSize="16sp"
android:textColor="@color/text_secondary"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击下方按钮开始记录吧"
android:textSize="14sp"
android:textColor="@color/text_hint" />
</LinearLayout>
</FrameLayout> </FrameLayout>
<!-- 添加心情按钮 --> <!-- 心情卡片区域 -->
<com.google.android.material.floatingactionbutton.FloatingActionButton <androidx.viewpager2.widget.ViewPager2
android:id="@+id/fab_add_mood" android:id="@+id/vp_mood_cards"
android:layout_width="wrap_content" android:layout_width="360dp"
android:layout_height="wrap_content" android:layout_height="170dp"
android:layout_margin="24dp" android:layout_marginTop="32dp"
android:src="@drawable/ic_add" android:layout_marginBottom="80dp"
android:backgroundTint="@color/chick_yellow" android:visibility="gone"
app:tint="@color/white" android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/fl_chick_container"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<!-- 空状态页面 (默认隐藏) -->
<LinearLayout
android:id="@+id/ll_empty_state"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:gravity="center"
android:layout_marginBottom="80dp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:src="@drawable/ic_empty_chick"
android:layout_marginBottom="16dp"
android:contentDescription="空白状态小鸡" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="还没有心情记录"
android:textSize="16sp"
android:textColor="@color/text_secondary"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击下方按钮开始记录吧"
android:textSize="14sp"
android:textColor="@color/text_hint" />
</LinearLayout>
<!-- 添加心情按钮 -->
<Button
android:id="@+id/fab_add_mood"
android:layout_width="144dp"
android:layout_height="56dp"
android:text="添加心情"
android:textSize="16sp"
android:textColor="@color/white"
android:textStyle="bold"
android:background="@drawable/bg_add_mood_button"
android:layout_marginBottom="24dp"
android:elevation="4dp"
android:stateListAnimator="@null"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:rippleColor="@color/chick_yellow_dark"
android:contentDescription="添加心情记录" /> android:contentDescription="添加心情记录" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/iv_chick"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:contentDescription="心情小鸡" />

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="12dp"
app:cardElevation="2dp"
app:cardBackgroundColor="@color/white">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- 心情文案 - 左上角 -->
<TextView
android:id="@+id/tv_mood_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="@color/text_primary"
android:maxLines="2"
android:ellipsize="end"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_detail"
tools:text="完全无法控制 开心" />
<!-- 查看详情按钮 - 右上角 -->
<ImageView
android:id="@+id/btn_detail"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_more_info"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/text_secondary"
android:padding="2dp"
android:contentDescription="查看详情"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- 主要内容区域 -->
<LinearLayout
android:id="@+id/ll_main_content"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal"
android:gravity="top"
app:layout_constraintTop_toBottomOf="@id/tv_mood_description"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- 左侧图片区域 -->
<ImageView
android:id="@+id/iv_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginEnd="12dp"
android:scaleType="centerCrop"
android:visibility="gone"
android:background="@drawable/placeholder_background"
android:contentDescription="心情图片" />
<!-- 右侧文本区域 -->
<TextView
android:id="@+id/tv_text_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:textSize="14sp"
android:textColor="@color/text_secondary"
android:lineSpacingExtra="2dp"
android:maxLines="4"
android:ellipsize="end"
android:gravity="top"
android:visibility="gone"
tools:text="今天心情特别好,工作顺利完成,还和朋友们一起聚餐聊天,感觉很充实很快乐。" />
</LinearLayout>
<!-- 操作按钮区域 - 右下角 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- 收藏按钮 -->
<ImageView
android:id="@+id/btn_favorite"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_card_favorite_border"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="2dp"
android:contentDescription="收藏" />
<!-- 分享按钮 -->
<ImageView
android:id="@+id/btn_share"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="12dp"
android:src="@drawable/ic_card_share"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="2dp"
android:contentDescription="分享" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -3,7 +3,7 @@
<!-- 主题色彩 --> <!-- 主题色彩 -->
<color name="chick_yellow">#FFD954</color> <color name="chick_yellow">#FFD954</color>
<color name="chick_yellow_dark">#FFC107</color> <color name="chick_yellow_dark">#FFC107</color>
<color name="main_background">#FFF8E1</color> <color name="main_background">#FFFCEA</color>
<!-- Material Design色彩 --> <!-- Material Design色彩 -->
<color name="primary">#FFD954</color> <color name="primary">#FFD954</color>
@ -42,7 +42,7 @@
<color name="blue_300">#64B5F6</color> <color name="blue_300">#64B5F6</color>
<!-- 添加心情页面专用颜色 --> <!-- 添加心情页面专用颜色 -->
<color name="background_light">#FFF8E1</color> <color name="background_light">#FFFCEA</color>
<color name="primary_color">#FFD954</color> <color name="primary_color">#FFD954</color>
<color name="progress_background">#FFE0B2</color> <color name="progress_background">#FFE0B2</color>
<color name="overlay_background">#80000000</color> <color name="overlay_background">#80000000</color>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,19 @@
A. 在哪里可以下载阿里妈妈数黑体?
渠道一https://www.iconfont.cn/fonts/detail?cnid=a9fXc2HD9n7s
渠道二fonts.alibabagroup.com
B. 阿里阿里妈妈数黑体简介
基本信息阿里妈妈数黑体为中文简体字库收纳的中文字符包括但不限于GB2312共计6767个汉字英文大小写共52个常用标点符号共206个总计7025个字符。
设计说明:阿里妈妈数黑体字型饱满、体态中正,布白极具现代韵律,落笔厚实而简练;字里行间流露出先锋、前卫和时尚的视觉感受。适用于电商、广告、品牌形象、推广物料等场景。
C. 使用反馈、商业合作等问题请email
alimama-font@list.alibaba-inc.com
——
重要!安装前请先阅读此文档
请先按照下面流程安装文件夹里的字体包。
1. 打开字体文件夹根据不同系统需要选择OTF或TTF版本
2. 字体所包含只有一个字重(双击安装)。

View File

@ -0,0 +1,15 @@
阿里妈妈数黑体法律声明
1. 阿里妈妈数黑体字体及包含该字体的字库软件,合称“阿里妈妈数黑体”。
2. 阿里妈妈数黑体的知识产权和相关权益归属于淘宝(中国)软件有限公司(以下简称“阿里妈妈”),受《中华人民共和国著作权法》及其他适用法律法规、国际公约、条约的保护。
3. 阿里妈妈授权个人、企业等用户在遵守本声明相关条款的前提下可以下载、安装和使用上述阿里妈妈字体该授权是免费的普通许可用户可基于合法目的用于商业用途或非商业用途但不得以任何违反本声明第4条及法律法规、政策、规章或公序良俗的方式使用。
4. 除本法律声明中明确授权之外阿里妈妈未授予用户关于阿里妈妈数黑体的其他权利。未经阿里妈妈授权任何人不得1对阿里妈妈数黑体进行仿制、转换、翻译、反编译、反向工程、拆分、破解或以其他方式试图从该字库软件获取源代码2删除、覆盖或修改阿里妈妈数黑体法律声明的全部或部分内容3将阿里妈妈数黑体进行单独定价出售、出租、出借、转让、转授权、或采取其他未经阿里妈妈授权的行为4) 发布任何使外界误认其与阿里妈妈或其关联公司存在合作、赞助或背书等商业关联的不实信息。
5. 阿里妈妈授予用户的上述授权不附带任何明示或暗示的保证,不对任何人因从非阿里妈妈官方渠道或指定渠道下载、安装或使用阿里妈妈数黑体而引发的任何直接或间接损失承担责任。
6. 本声明的解释、履行与争议解决适用中华人民共和国的法律。用户与阿里妈妈就阿里妈妈数黑体的使用若发生争议,双方应友好协商,若协商不成,任一方有权向浙江省杭州市有管辖权的人民法院提起诉讼。
反馈与咨询联系方alimama-font@list.alibaba-inc.com

BIN
image/appicon/appicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
image/心情卡片@1x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB