Skip to content

fragmject 是一个为初学者准备的上手项目。 通过对 Kotlin 和 Jetpack 的系统运用,实现的一个功能完备符合主流市场标准 App。 fragmject 没有复杂的业务和多余的封装, 完全依照 Android Developer 官方的写法。 代码简单,内容全面,快速上手,对理解其他项目设计思想和封装技巧也很有帮助。

License

Notifications You must be signed in to change notification settings

SkyOfStars/fragmject

 
 

Repository files navigation

前言

刚开始学习 Kotlin 其实挺痛苦的,相关的书籍或视频偏向于知识点的讲解。
开源项目为了满足业务需求,代码层层封装,用来上手实在不合适,于是便有了 fragmject 项目。
在此感谢 玩Android 及其 开放API

简介

fragmject 是一个为初学者准备的上手项目。
通过对 KotlinJetpack 的系统运用,实现的一个功能完备符合主流市场标准应用。
fragmject 没有复杂的业务和多余的封装, 完全依照 Android Developer 官方的写法。
代码简单,内容全面,快速上手,对理解其他项目设计思想和封装技巧也很有帮助。

学习本项目你将有如下收获:

  • Kotlin(函数进阶,泛型,反射,协程...)
  • MVVM(ViewModel,LiveData...)
  • 单 Activity 应用架构(Navigation...)
  • 常用控件封装(图片选择器、图片编辑器、日期控件、全面屏沉浸、屏幕录制...)
  • 字节码插桩(ASM...)
  • Compose

开发环境

为了您在运行本项目时获得最佳体验,请使用 Android Studio Chipmunk (2021.2.1) 🐿️Android Gradle 7.2.2 或者以上版本。
Download Android Studio | Android Developer

前置知识

在学习前希望您能了解以下知识,这将帮助您更快的上手本项目。

截图展示

1.jpg 2.jpg 3.jpg

项目目录结构

├── 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                             项目依赖配置

Jetpack Compose(持续更新)

目前 master 处在增量迁移中(Compose 和 View 在代码库中共存),直到应用完全迁移至 Compose 为止。
如果你暂时不需要 Compose ,可以切换到 Tags v1.3.0

Jetpack Compose : 从改造你的登录页面开始

Jetpack Compose : 一学就会的自定义下拉刷新&加载更多

Jetpack Compose : WebView的使用与优化

KVDatabase

通过对 RoomDatabase 进行封装,从而更方便的实现数据持久化。

快速使用

// 存储数据
KVDatabase.set(key: String, value: String)

// 获取数据
KVDatabase.get(key: String)

SharedFlowBus

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)
}

字节码插桩

最通俗易懂的字节码插桩实战 —— 优雅的打印方法执行时间

最通俗易懂的字节码插桩实战 —— 自动埋点

隐私合规 ———— 替换目标字段或方法(library-plugin)

一文学会字节码替换,再也不用担心隐私合规审核

快速使用

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'
}

图片编辑器(library-picture)

自己动手撸一个图片编辑器(支持长图)

截图展示

5.gif 6.gif 7.gif

快速使用

PictureEditorDialog.newInstance()
    .setBitmapPath(path)
    .setEditorFinishCallback(object : EditorFinishCallback {
        override fun onFinish(path: String) {
            val bitmap = BitmapFactory.decodeFile(path, BitmapFactory.Options())
        }
    })
    .show(childFragmentManager)

如上所示:

  1. 通过 PictureEditorDialog 调用图片编辑器
  2. 通过 setBitmapPath(path) 传入图片路径
  3. 通过 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()

如上所示:

  1. 通过 setBitmapPath(path) 传入图片路径
  2. 通过 setMode(mode) 设置编辑模式,分别有:涂鸦,橡皮擦,马赛克,贴纸
  3. 通过 setGraffitiColor(color) 设置涂鸦画笔颜色
  4. 通过 setSticker(StickerAttrs(bitmap)) 设置贴纸
  5. 通过 graffitiUndo() 涂鸦撤销
  6. 通过 mosaicUndo() 马赛克撤销
  7. 通过 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()

如上所示:

  1. 通过 setBitmapResource(bitmap) 传入裁剪图片
  2. 通过 clip.rotate() 图片旋转
  3. 通过 clip.reset() 图片重置
  4. 通过 clip.saveBitmap() 保存裁剪框内图片

PictureClipView 就介绍到这里,具体使用请查看 PictureClipDialog

WebView 优化及 H5 秒开实践

满满的 WebView 优化干货,让你的 H5 实现秒开体验

主要开源框架

Gitee镜像

About me

Thanks

感谢所有优秀的开源项目 ^^
如果喜欢的话希望给个 Star 或 Fork ^
^
谢谢~~

About

fragmject 是一个为初学者准备的上手项目。 通过对 Kotlin 和 Jetpack 的系统运用,实现的一个功能完备符合主流市场标准 App。 fragmject 没有复杂的业务和多余的封装, 完全依照 Android Developer 官方的写法。 代码简单,内容全面,快速上手,对理解其他项目设计思想和封装技巧也很有帮助。

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Kotlin 93.2%
  • Java 4.7%
  • JavaScript 2.1%