首先是还没想好的app名字

1.先放一个演示视频吧

此处偷偷吐槽一下垃圾微信视频号,视频比例都没适配好,把我的演示视频直接裁剪了。

2.介绍(尬吹)

  1. 适配了深色模式,2022年了还有不适配的app吗(不会吧不会吧不会吧
  2. 目前做的部分有精美的UI和流畅的动画(存疑
  3. 目前只有日记功能

UI部分参考了iOS上的天天豆,强推

3.todo(画大饼)

  • 已完成功能

    • 精美UI(bushi
    • 流畅动画
    • 日记基本功能
    • 基本框架
    • 深色模式
  • 加入todo功能

    • tablayout切换完成以及未完成列表
    • 有截止日期,提醒功能
    • 有分类功能
  • 加入统计功能

    • 对每月以及每年进行心情趋势分布统计
    • 对每月完成的todo进行统计
  • 加入设置功能

    • 加入定时提醒写日记功能

    • 自由切换深色模式

    • 加入自定义主题

    • 适配material3动态颜色

    • 账号功能

    • 云存档

  • 完善日记功能

    • 设置每日只能同时存在一份日记
    • 添加每月分类
    • 优化滑动卡顿
    • 修改为每日与每月查看模式

4.初步骚操作记录

1.bottomnavigationview取消item选择
1
2
3
4
5
<item
android:id="@+id/uncheckedItem"
android:title=""
android:visible="false"
/>

只要添加一个空的隐藏的item,就可以使没选中的item变成初始状态,因为我采用了两个bottomnavigationview,将四个item平均分了,为了fab的效果,用了这种方式,然后再监听目前的fragmnet来控制效果,然后再设置相关的边距

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//控制BottomNavigationView和fab的效果
navController.addOnDestinationChangedListener { _, destination, _ ->
when(destination.id) {
R.id.navigation_home -> {
binding.navView.updatePadding(right = DensityUtil.dip2px(context,50f))
binding.navView2.updatePadding(left = DensityUtil.dip2px(context,50f))
binding.bottomAppBar.fabAlignmentMode = FAB_ALIGNMENT_MODE_CENTER
binding.navView2.menu.findItem(R.id.uncheckedItem).isChecked = true
binding.fab.setImageDrawable(getDrawable(R.drawable.ic_baseline_done_all_24))
binding.fab.show()
}
R.id.navigation_dashboard -> {
binding.fab.setImageDrawable(getDrawable(R.drawable.ic_baseline_add_24))
binding.navView.updatePadding(right = DensityUtil.dip2px(context,50f))
binding.navView2.updatePadding(left = DensityUtil.dip2px(context,50f))
binding.navView2.menu.findItem(R.id.uncheckedItem).isChecked = true
binding.bottomAppBar.fabAlignmentMode = FAB_ALIGNMENT_MODE_CENTER
binding.fab.show()
}
R.id.navigation_charts -> {
binding.navView.setPadding(0)
binding.navView2.setPadding(0)
binding.navView.menu.findItem(R.id.uncheckedItem).isChecked = true
binding.fab.hide()
}

R.id.navigation_settings -> {
binding.navView.setPadding(0)
binding.navView2.setPadding(0)
binding.navView.menu.findItem(R.id.uncheckedItem).isChecked = true
binding.fab.hide()
}
}
}

}
2.监听添加与修改日记
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//作为接收recyclerview添加以及修改结果的中转站
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
1 -> if (resultCode == RESULT_OK) {
diaryViewModel.addDiaryItem = data?.getParcelableExtra("addDiary")!!
diaryViewModel.addPosition.value = 1
}
2 -> {
if (data?.getStringExtra("position").toString() != "null"){
diaryViewModel.reviseDiaryItem = data?.getParcelableExtra("reviseDiary")!!
diaryViewModel.setPosition(position = data.getStringExtra("position")?.toInt() ?: -1)
}

}
}
}

在viewmodel里设置两个值,通过observe这两个值来通知fragment,话说应该有很多其他方法来做这件事,比如广播,handler之类的,不过我这种应该也不算很烂吧

3.在adapter外部获取点击事件
1
2
3
4
5
6
7
8
9
10
11
12
//点击事件接口
interface ItemListenter {
fun deleteItemClick(position: Int)
fun reviseItemClick(position: Int)
}

private var itemListenter: ItemListenter? = null
fun setOnItemClickListener(itemListenter: ItemListenter?) {
this.itemListenter = itemListenter
}
//在onCreateViewHolder里调用
itemListenter?.deleteItemClick(position)
1
2
3
4
5
6
7
8
9
10
11
12
13
//recyclerview点击接口回调
adapter.setOnItemClickListener(object : DiaryAdapter.ItemListenter {
override fun deleteItemClick(position: Int) {
diaryViewModel.deleteDiary(position)
adapter.notifyItemRemoved(position)
}

override fun reviseItemClick(position: Int) {

}


})

这样就可以拿到recyclerview里对应的position了,其实感觉弄个下拉刷新更方便,不过实时刷新肯定更好啦

4.在adapter里获取actvity
1
class DiaryAdapter(val diaryList: List<Diary>,val activity: Activity) : RecyclerView.Adapter<DiaryAdapter.ViewHolder>(){

在构造函数里加入activity参数,调用的时候传进来就好了

5.imageview图片展示效果
1
2
android:adjustViewBounds="true"
android:scaleType="fitXY"

在xml里设置这两个就能按原比例完整的展示图片了,为了这个弄了好久,最后发现原生的就行。。。我恨网上鱼龙混杂的垃圾教程

6.关于ConstraintLayout的黑科技

这个布局真的是功能强大,在lnm被小程序折磨以后如是说道,熟悉用法以后真的很强大

1.首先就是这个barrier功能
1
2
3
4
5
6
<androidx.constraintlayout.widget.Barrier
android:layout_width="1dp"
android:layout_height="0dp"
app:barrierDirection="end"
android:id="@+id/barrier1"
app:constraint_referenced_ids="delete_image,diarycard_mood,materialCardView"/>

可以把所需的控件包在里面,然后其他的就只能被挡在另一个方向了,对于复杂布局还是很有用的

2.其次便是Guideline功能
1
2
3
4
5
6
7
8
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

就是一个辅助线的功能,目前我用来定位水平中心,直接0.5就能到中心,舒舒服服


应该差不多就是这些了,后面就是慢慢加新功能了。。。。