前言
本人Android小菜鸡一枚,开发该app的主要目的是为了巩固kotlin语法,学习使用JetPack进行一个完整App的开发,不得不说,Kotlin+JetPack开发起来真是无敌丝滑(末尾附上项目地址)
介绍
😄时刻是一个使用纯kotlin和Jetpack实现的具有简单增删改查功能的日记App
效果图
使用的相关技术
- DataBinding :省去了繁琐的findViewById工作,而且通过和ViewMode配合,可以直接把ViewModel的数据渲染到界面上
- Paging:分页加载库
郭神的博客 - Room:封装了sqlite,将表映射成Java或Kotlin对象,我觉得相比于之前使用的greendao,room最大的优势是支持了kotlin的flow,通过和paging配合,实现自动的刷新数据链接
- dataStore:用来代替SP的数据持久化方案,最大的优势是支持异步获取保存数据,通过一个PreferencesKey保存对应类型泛型的方法保证了类型安全
- ViewModel:用于保存actvity的数据中转
- Glide:图片加载,这个太牛皮了就不介绍了
- liveData:代替EventBus用于进行事件分发
部分代码展示
private fun setThemeBackGround(@ColorRes colorRes: Int) {
val color: Int = ContextCompat.getColor(this, colorRes)
mBinding.clEditDairy.setBackgroundResource(colorRes)
setStatusBarColor(color)
if (ColorUtils.calculateLuminance(color) > 0.6) {
setAndroidNativeLightStatusBar(this, true)
} else {
setAndroidNativeLightStatusBar(this, false)
}
val shape = GradientDrawable()
shape.color = ColorStateList.valueOf(addColorDepth(color))
shape.cornerRadius = dp2px(baseContext, 5f)
ripperDrawable =
RippleDrawable(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.DairyEditHintText)), shape, null)
}
private fun addColorDepth(color: Int): Int {
var red = color and 0xff0000 shr 16
var green = color and 0x00ff00 shr 8
var blue = color and 0x0000ff
red = if (red - 25 > 0) red - 25 else 0
green = if (green - 25 > 0) green - 25 else 0
blue = if (blue - 25 > 0) blue - 25 else 0
return Color.rgb(red, green, blue)
}
override fun onPause() {
super.onPause()
if (!TextUtils.isEmpty(viewModel.dairyContent.value) && isNeedToSaved) {
DataStoreUtils.saveSyncStringData(RECOVER_CONTENT, viewModel.dairyContent.value!!)
DataStoreUtils.saveSyncStringData(RECOVER_TITLE, mBinding.appBar.getTitle())
}
}
private fun tryToRecoverDairy() {
lifecycleScope.launch(Dispatchers.Main) {
DataStoreUtils.readStringFlow(RECOVER_CONTENT).first {
if (it.isNotEmpty()) {
recoveredContent = it
}
true
}
DataStoreUtils.readStringFlow(RECOVER_TITLE).first {
if (it.isNotEmpty()) {
recoveredTitle = it
}
true
}
}
private fun getDairyData() {
lifecycleScope.launch(Dispatchers.Main) {
viewModel.getAllDairy().collect {
dairyAdapter.submitData(it)
}
}
}
fun getAllDairy(): Flow<PagingData<DairyItem>> {
return repository.getAllDairyData().cachedIn(viewModelScope)
}
fun getAllDairyData(): Flow<PagingData<DairyItem>> {
return Pager(
config = PagingConfig(PAGE_SIZE, maxSize = 150),
pagingSourceFactory = dairyDao.getAllDairy().asPagingSourceFactory()
).flow
}
@Query("SELECT * FROM DairyEntity order by createTime desc")
fun getAllDairy(): DataSource.Factory<Int, DairyItem>
private val toAlbumLauncher =
registerForActivityResult(ToSystemAlbumResultContract()) {
if (it != null) {
viewModel.pictureList.add(it)
viewModel.isChanged.value = true
pictureSelectAdapter.notifyItemRangeChanged(viewModel.pictureList.size, 2)
}
}
private val toCameraLauncher =
registerForActivityResult(ActivityResultContracts.TakePicture()) {
if (it) {
viewModel.pictureList.add(currentUri)
viewModel.isChanged.value = true
pictureSelectAdapter.notifyItemRangeChanged(viewModel.pictureList.size, 2)
galleryAddPic()
}
}
inner class ToSystemAlbumResultContract : ActivityResultContract<Unit, Uri?>() {
override fun createIntent(context: Context, input: Unit?): Intent {
val intent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
intent.type = "image/*"
return intent
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return intent?.data
}
}
最后
源码中代码的注释非常详细,有兴趣的大佬可以进去看看呐 Kotlin的扩展函数用起来贼爽
github地址:LongerRelationShip
有兴趣的大佬可以下载提提建议 时刻下载地址 后期开发功能
- 记账功能
- 录音笔记功能
- App的图库功能
- 日记的收藏和设置私密
感谢
|