刚开始学习 Kotlin
其实挺痛苦的,相关的书籍或视频偏向于知识点的讲解。
开源项目为了满足业务需求,代码层层封装,用来上手实在不合适,于是便有了 fragmject
项目。
在此感谢 玩Android 及其 开放API 。
fragmject
是一个为初学者准备的上手项目。
通过对 Kotlin
和 Jetpack
的系统运用,实现的一个功能完备符合主流市场标准应用。
fragmject
没有复杂的业务和多余的封装, 完全依照 Android Developer 官方的写法。
代码简单,内容全面,快速上手,对理解其他项目设计思想和封装技巧也很有帮助。
学习本项目你将有如下收获:
- Kotlin(函数进阶,泛型,反射,协程...)
- MVVM(ViewModel,LiveData...)
- 单 Activity 应用架构(Navigation...)
- 常用控件封装(图片选择器、图片编辑器、日期控件、全面屏沉浸、屏幕录制...)
- 字节码插桩(ASM...)
- Compose
为了您在运行本项目时获得最佳体验,请使用最新版本 Android Studio
。
Download Android Studio | Android Developer
在学习前希望您能了解以下知识,这将帮助您更快的上手本项目。
- Kotlin 语言学习 | Android Developer
- Kotlin 代码示例 | Android Developer
- ViewBinding 使用入门 | Android Developer
- LiveData 使用入门 | Android Developer
- ViewModel 使用入门 | Android Developer
- Coroutines 使用入门 | Android Developer
- Navigation 使用入门 | Android Developer
- Room 使用入门 | Android Developer
- Compose 使用入门 | Android Developer
- 一文看懂MVVM | 掘金
├── app app
| └── src
| └── main
| | └── java 源码目录
| | | ├── activity Activity目录
| | | | └── MainActivity 项目唯一Activity
| | | ├── adapter Adapter目录
| | | ├── compose Compose目录
| | | ├── ui ui目录
| | | | └── main mian目录
| | | | └── home home目录
| | | | | ├── HomeScreen
| | | | | └── HomeViewModel
| | | | └── MainScreen
| | | ├── utils 工具类目录
| | | ├── WanActivity 唯一Activity
| | | ├── WanApplication Application
| | | └── WanNavGraph 导航图
| | |
| | └── res 资源目录
| | |
| | └── AndroidManifest.xml 配置文件
| |
| └── build.gradle 模块构建配置
| └── channel 渠道配置文件
| └── dictionary 自定义混淆字典
| └── proguard-rules.pro 代码混淆配置文件
|
├── library-base 基础library(library开头为公共库,任何项目都可使用)
| └── src
| └── main
| | ├── assets 原生文件目录
| | └── java 源码目录
| | ├── activity Activity目录
| | ├── adapter Adapter目录
| | ├── bus 消息总线目录
| | ├── db Database目录
| | ├── dialog Dialog目录
| | ├── http 网络请求目录
| | ├── provider ContentProvider目录
| | ├── utils 工具类目录
| | └── view 自定义view目录
| |
| └── build.gradle 模块构建配置
|
├── library-picture 图片模块(目录同app,不再展开)
|
├── library-plugin 插件模块
| └── src
| └── main
| └── groovy 源码目录
| |
| └── resources 配置目录
| └── statistic.properties 插件配置
|
├── repos 插件生成目录
|
├── build.gradle 项目构建配置
├── config.gradle gradle编译文件 gradle依赖配置
├── config.properties 项目配置
├── gradle.properties gradle配置
└── settings.gradle 项目依赖配置
目前 master
处在增量迁移中(Compose 和 View 在代码库中共存),直到应用完全迁移至 Compose 为止。
如果你暂时不需要 Compose ,可以切换到 Tags v1.3.0 。
与使用 Android View 系统相比,Compose 可让我们用更少的代码实现更多的功能,这样需要测试和调试的代码会更少,出现 bug 的可能性也更小。对于审核人员或维护人员,需要阅读、理解、审核和维护的代码就更少。
Compose 的布局系统在概念上更简单,所有代码都使用同一种语言编写并且位于同一文件中,而不必在 Kotlin 和 XML 二者之间来回切换。
Compose 使用声明性 API,这意味着您只需描述界面,Compose 会负责完成其余工作。
利用 Compose,您可以构建不与特定 activity 或 fragment 相关联的小型无状态组件。
在 Compose 中,状态是显式的,并且会传递给相应的可组合项。这样一来,状态便具有单一可信来源,因而是封装和分离的。然后,应用状态变化时,界面会自动更新。
Compose 与您所有的现有代码兼容:您可以从 View 调用 Compose 代码,也可以从 Compose 调用 View。大多数常用库(如 Navigation、ViewModel 和 Kotlin 协程)都适用于 Compose,因此您可以随时随地开始采用。
Jetpack Compose : 一学就会的自定义下拉刷新&加载更多
Jetpack Compose : WebView的使用与优化
通过对 RoomDatabase
进行封装,从而更方便的实现数据持久化。
// 存储数据
KVDatabase.set(key: String, value: String)
// 获取数据
KVDatabase.get(key: String)
SharedFlowBus:30行代码实现消息总线你确定不看吗
// 发送消息
SharedFlowBus.with(objectKey: Class<T>).tryEmit(value: T)
// 发送粘性消息
SharedFlowBus.withSticky(objectKey: Class<T>).tryEmit(value: T)
// 订阅消息
SharedFlowBus.on(objectKey: Class<T>).observe(owner){ it ->
println(it)
}
// 订阅粘性消息
SharedFlowBus.onSticky(objectKey: Class<T>).observe(owner){ it ->
println(it)
}
在 MiaowPlugin
添加 ScanBean
并配置目标字段或方法以及对应的替换字段或方法
ScanBean(
owner = "android/os/Build",
name = "BRAND",
desc = "Ljava/lang/String;",
replaceOpcode = Opcodes.INVOKESTATIC,
replaceOwner = "com/example/fragment/library/common/utils/BuildUtils",
replaceName = "getBrand",
"()Ljava/lang/String;"
)
在 MiaowPlugin
添加 TimeBean
并配置打印目标或范围
TimeBean( //以包名和执行时间为条件
"com/example/fragment/library/base",
time = 50L
)
在 MiaowPlugin
添加 TraceBean
并配置埋点目标以及对应埋点方法
TraceBean(
owner = "Landroid/view/View\$OnClickListener;",
name = "onClick",
desc = "(Landroid/view/View;)V",
traceOwner = "com/example/fragment/library/common/utils/StatisticHelper",
traceName = "viewOnClick",
traceDesc = "(Landroid/view/View;)V" //参数应在desc范围之内
)
配置完成后 gradle
执行 publish
任务生成插件
在根目录 setting.gradle
添加本地插件源
pluginManagement {
repositories {
maven {
url uri('repo')
}
}
}
在根目录 build.gradle
添加插件依赖
buildscript {
dependencies {
classpath 'com.example.miaow:plugin:1.0.0'
}
}
在app目录 build.gradle
apply插件
plugins {
id 'miaow'
}
PictureEditorDialog.newInstance()
.setBitmapPath(path)
.setEditorFinishCallback(object : EditorFinishCallback {
override fun onFinish(path: String) {
val bitmap = BitmapFactory.decodeFile(path, BitmapFactory.Options())
}
})
.show(childFragmentManager)
如上所示:
- 通过
PictureEditorDialog
调用图片编辑器 - 通过
setBitmapPath(path)
传入图片路径 - 通过
setEditorFinishCallback(callback)
获取编辑后的图片地址
如果觉得 PictureEditorDialog
不能满足需求,还可以通过 PictureEditorView
来自定义样式
<com.example.miaow.picture.editor.PictureEditorView
android:id="@+id/pic_editor"
android:layout_width="match_parent"
android:layout_height="match_parent" />
picEditor.setBitmapPath(path)
picEditor.setMode(PictureEditorView.Mode.STICKER)
picEditor.setGraffitiColor(Color.parseColor("#ffffff"))
picEditor.setSticker(StickerAttrs(bitmap))
picEditor.graffitiUndo()
picEditor.mosaicUndo()
picEditor.saveBitmap()
如上所示:
- 通过
setBitmapPath(path)
传入图片路径 - 通过
setMode(mode)
设置编辑模式,分别有:涂鸦,橡皮擦,马赛克,贴纸 - 通过
setGraffitiColor(color)
设置涂鸦画笔颜色 - 通过
setSticker(StickerAttrs(bitmap))
设置贴纸 - 通过
graffitiUndo()
涂鸦撤销 - 通过
mosaicUndo()
马赛克撤销 - 通过
saveBitmap()
保存编辑图片
PictureEditorView
就介绍到这里,具体使用请查看 PictureEditorDialog
<com.example.miaow.picture.editor.PictureClipView
android:id="@+id/clip"
android:layout_width="match_parent"
android:layout_height="match_parent" />
clip.setBitmapResource(bitmap)
clip.rotate()
clip.reset()
clip.saveBitmap()
如上所示:
- 通过
setBitmapResource(bitmap)
传入裁剪图片 - 通过
clip.rotate()
图片旋转 - 通过
clip.reset()
图片重置 - 通过
clip.saveBitmap()
保存裁剪框内图片
PictureClipView
就介绍到这里,具体使用请查看 PictureClipDialog
if (context is AppCompatActivity) {
PictureSelectorDialog.newInstance()
...省略部分代码
.show(context.supportFragmentManager)
}
满满的 WebView 优化干货,让你的 H5 实现秒开体验
- QQ : 237934622
- QQ群 : 389499839
- WeChat : zst_1116
- Email : zst_1116@icloud.com
- JueJin:miaowmiaow
感谢所有优秀的开源项目 ^^
如果喜欢的话希望给个 Star 或 Fork ^^
谢谢~~