Skip to content

Learn about development projects with jetpack compose

Notifications You must be signed in to change notification settings

wzj042/SmartCity-Compose

Repository files navigation

智慧城市模块分析

尝试使用compose重构,则部分代码无法复用框架以及考虑使用替代

  • 引导页
    • viewpager左右滑动 with指示符
    • preference读写 ip port, init status -> Preferences DataStore
  • 主页
    • 轮播图 auto viewpager
    • 搜索
    • RecyclerView -> LazyRows
    • bottom tab view pager
  • 个人中心
    • 图片上传
    • [修改已保存ip port]

基础要求

应用名 | 主页toolbar title:智慧城市

打包为release包发布

关键路径

  • 任务周期: 2023.9.24 -9.28
  • 交付物:智慧城市应用apk及源码
  • 模块划分
    • 架构
      • Android 应用的应用图表模型
      • UI层
      • ViewModel层
      • Repository层
        • [数据持久库Room]
        • 网络请求Retrofit
        • 架构组件LiveData
        • 协程构建和启动, Kotlin Flow
        • 数据绑定适配器
      • 本地数据存储
        • Preferences DataStore
    • 引导页
      • 滑动引导页
      • 本地存储
    • 主页面
      • 网络请求
        • get -> json -> plan object
        • post : with form
      • RecyclerView -> LazyColumn
      • BottomAppBar
      • AppBar
      • EditText -> TextFieId
    • 个人中心
    • 全部服务
      • custom list: with checked status
    • 自选模块
  • 任务安排:
    1. DAY1
      • 规划剩下四天的任务安排
      • 初步了解jetpack compose
      • 学习简易kotlin语法
        • 了解网络库retrofit
      • 了解待学习内容
    2. DAY2
      • 完成引导页界面
        • 滑动引导页(Pager)
      • [主页使用技术研究
        • SearchBar
        • BottomNavigation
        • Scaffold
    3. DAY3
      • 学习
        • 了解kt flow 协程
        • Preferences DataStore实现本地存储功能
        • viewModel & liveData
      • 实现
        • 主页
          • banner -> HorizontalPager
          • tablayout -> TabRow
          • 协程加载数据 -> 考虑引入Net网络请求框架
        • 个人中心
      • 可选
        • 学习依赖注入
        • 重构抽象考虑搭建基本结构
    4. DAY4
      • 实现全部服务
      • 挑选自选模块尝试重构代码实现
      • 打包应用测试
    5. DAY5
      • 完善应用
      • 提交交付物

学习笔记

DAY1

使用Kotlin网络通信

  • Retrofit—— 网络请求库

  • Gson —— 将 json 与 对象 互转的库

  • Retrofit converter-Gson —— Retrofit插件,提供GsonConverterFactory帮助Gson与Retrofit交互

  • 依赖部分变动为kotlin dsl —— 简化使用只了解为更改为

  • dependencies {
        implementation ("library url")
    }

    此处三个组件库的实现我直接借助chatgpt生成相应示例代码,我补充细节的形式来直接先敲一次例子了解有哪些基本功能

    相关kt语法

    • data class

      • 类名后直接声明主构造函数,在其中定义一些类属性,使它们称为类成员属性
      • 会将主构造函数中的成员自动生成 getter, setter 以及 生成equals, hashCode, toString
    • @SerializedName 注解

      • 指定json字段与kt属性名间的映射
    • suspend —— kotlin协程概念之一

      • 定义挂起函数,表示函数可被挂起和恢复执行
      • 使其能与协程一同工作
    • 双冒号::引用对象语法

      • 例如ApiService::class 表示对 ApiService 类的引用,而 .java 则表示获取该类的 Java Class 对象。

        在 Retrofit 中,我们需要传递一个 Java Class 对象给 retrofit.create() 方法来创建相应的 API 接口实例。因此,我们使用 ApiService::class.java 来获取 ApiService 的 Java Class 对象,然后在 retrofit.create() 方法中使用它。

    • object对象表达式语法

      • 可用于创建匿名对象,还可将泛型作为类型参数

        val callback = object : Callback<List<String>> {
            // 实现 Callback 接口的方法
            override fun onResponse() {
            }
        }

    retrofit相关语法

    • 通过接口定义 api接口
    • 通过构造实例使用方法
    • 通过注解定义请求类型,请求头,参数
      • @Query(String)注解 拼接参数到URL中
      • @Header(String) 添加请求头
      • @Body 将参数添加到body中

    gson相关语法

    • setLenient() —— 设置Gson解析器为宽松模式
      • 使解析器尝试解析不符合json规范的内容,避免遇到错误立刻抛出异常

实现了完整的一个retrofit get post的流程,封装方法相关的语法知识太多,明天补上

DAY2

学习Compose基本布局

尝试实现引导页时发现对新布局如何定位不够了解,决定开一个codelab

花了两个单位时跟着敲完一个codelab

收获很多,大部分页面组件都包括了相应实例

修改本地项目kt版本保证兼容

but don't say I didn't warn you

This version (1.4.8) of the Compose Compiler requires Kotlin version 1.8.22 but you appear to be using Kotlin version 1.9.10 which is not known to be compatible.  Please consult the Compose-Kotlin compatibility map located at https://developer.android.com/jetpack/androidx/releases/compose-kotlin to choose a compatible version pair (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).

打开codelab项目出现以上警告,选择打开项目根目录下的build.gradle文件并修改plugins快kotlin插件版本

plugins {
    ...
    id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
    ...
}

通过Pager实现引导页

...

class IntroActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun IntroView() {

    val context = LocalContext.current

    val imageList = listOf(
        ...
    )

    val pagerState = rememberPagerState { imageList.size }

    HorizontalPager(
        state = pagerState,
        modifier = Modifier.fillMaxSize()
    ) { pageIndex ->
        val imageId = imageList[pageIndex]

        Image(
            painter = painterResource(id = imageId),
            contentDescription = "intro",
            modifier = Modifier.fillMaxSize(),
            contentScale = ContentScale.FillBounds
        )



    }

    // 指示器
    Box(Modifier.fillMaxSize()) {
        Row(
            Modifier
                .align(Alignment.BottomCenter)
                .padding(bottom = 50.dp)
        ) {
            imageList.forEachIndexed { index, _ ->
                val color = if (index == pagerState.currentPage) Color.White else Color.Gray
                Box(
                    Modifier
                        .size(16.dp)
                        .clip(CircleShape)
                        .background(color)
                )
                Spacer(modifier = Modifier.width(8.dp))
            }
        }
    }

    if (pagerState.currentPage == imageList.lastIndex) {

        Box(
            Modifier
                .fillMaxSize()
        ) {
            Text(
                text = "网络设置",
                color = Color.White,
                modifier = Modifier
                    .align(Alignment.TopEnd)
                    .padding(top = 25.dp, end = 25.dp)
                    .clickable {

                    },
            )
            Button(
                onClick = {
//                        check if net config setup yet

                    context.startActivity(Intent(context, MainActivity::class.java))
                },
                modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .padding(bottom = 100.dp, start = 50.dp, end = 50.dp)
            ) {
                Text(
                    text = "进入主页"
                )

            }


        }
    }
}

搭建主页

搭UI,配合chatgpt用了一堆像状态保存数据对槽位匹配之类的方法,只求先搭好主页和个人中心

BottomNavigationTopAppBar联动(修改appBarText)以及设置相应Fragment都有了大量的改动,查文档查了一晚上

然后发现不用NavHost直接在Content处匹配appBarText不就完了,虽然可能会有隐患(与BottomNavigation联调方面)

分好了Fragment和弄好SearchBar

DAY3

继续搭页面

折腾依赖库

要下载一个库应为仓库配置半天没弄下来最后直接剪裁代码了,结果搞另一个库依赖的时候解决了

// settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven { url = uri("https://www.jitpack.io" ) }
    }
}

引入import androidx.compose.ui.util.lerp时才发现少了个util库

dependencies {
    implementation("androidx.compose.ui:ui-util:1.5.1")
}
Pager搭Banner

花了一个上午看一坨文档,连加个依赖都卡住,直接从一个Banner库里扒代码才搞定

DAY4

根据官方示例重构代码

Note: As Compose cannot render HTML code in Text yet. The AndroidViewBinding API is used to embed a TextView in Compose. See the PlantDescription composable in the PlantDetailView file.
  • 注意compose Text暂不支持html code, 官方示例也提到了用binding 获取TextView去组合使用

Splash

往前适配splash-screen

  • 添加依赖
implementation("androidx.core:core-splashscreen:1.0.0")
  • 新建theme配置参数
<style name="Theme.Intro" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@color/tertiary</item>
        <item name="windowSplashScreenAnimatedIcon">@mipmap/app_logo</item>
        <item name="windowSplashScreenIconBackgroundColor">@color/secondary</item>
        <item name="windowSplashScreenAnimationDuration">1000</item>
    </style>
  • 给启动页Act设置主题

IntroBanner

添加依赖
// settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        maven { url = uri("https://jitpack.io") }
    }
}

// build.gradle.kts(:app)
dependencies {
//    banner
    implementation("com.github.zhujiang521:Banner:2.6.5")
}

参考引用

继续搭页面

  • chatgpt | copilot

About

Learn about development projects with jetpack compose

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages