Jetpack Compose 实战 宝可梦图鉴

news2024/9/22 7:26:02

文章目录

  • 前言
  • 实现效果
  • 一、架构介绍
  • 二、一些的功能点的介绍
    • 加载图片并获取主色,再讲主色设置为背景
    • 一个进度缓慢增加的圆形进度条
    • 单Activity使用navigation跳转Compose可组合项返回时页面重组的问题
    • hiltViewModel()
  • 主要参考项目
  • 总结


前言

阅读本文需要一定compose基础,如果没有请移步Jetpack Compose入门详解(实时更新)
学Compose学了有小半年的时间了,一直都是看官方的一些基础的教程并总结学习。最近终于实战了一个宝可梦图鉴的小项目,麻雀虽小五脏俱全。除了Compose外,还使用了一下一些Jetpack组件

  • accompanist-pager

  • coil

  • hilt

  • paging3

  • navigation-compose

  • accompanist-systemuicontroller

  • Retrofit

  • Kotlin Flow

接口数据来源于pokeapi

项目源代码
如果你觉得不错,请给我一个star,THKS


实现效果

闲话不多说,让我们来看看实现效果
在这里插入图片描述
可以看到我们实现了一个非常简洁的宝可梦图鉴,展示了所有世代的宝可梦,并提供了搜索,点击进入详情查看他们的属性

一、架构介绍

如图,展示了主要的一些文件:
在这里插入图片描述

  • api - 接口
  • nav - navigation导航
  • utils -工具类
  • view -Compose组件
  • viewmodels - viewmodel

二、一些的功能点的介绍

主要是开发过程中遇到的一些问题

加载图片并获取主色,再讲主色设置为背景

展示图片本来有封装好的CommonImage.kt用来展示图片,但是在列表中每一张图片的背景色都是动态获取的,当时做的时候觉得比较难弄,后面实现了过后就觉得还好啦。

引入的库

    implementation "io.coil-kt:coil-compose:2.1.0"
        //get Dominant image color
    implementation 'androidx.palette:palette-ktx:1.0.0'

主要代码在FullScreenView.kt中的 item()

	//我们所动态获取的图片背景色
	var backgroundColor by remember { mutableStateOf(0) }
    val context = LocalContext.current
    //ImageRequest
    val modelBuilder = ImageRequest.Builder(context).data(item.url.getPicUrl()).crossfade(false)
        .allowHardware(false).transformations().placeholder(R.drawable.ic_pokeball)
        .error(R.drawable.ic_pokeball)

	//开启一个获取协程的附带效应当ImageRequest发生改变时,通过ImageRequest来动态获取bitmap
	//再通过Palette来获取其主色
    LaunchedEffect(modelBuilder.build()) {
        val bitmap = context.imageLoader.execute(modelBuilder.build()).drawable?.toBitmap(
            config = Bitmap.Config.RGBA_F16
        )
        bitmap?.let {
            val palette = Palette.from(bitmap).generate()
            //当backgroundColor得到值,可组合项重组
            backgroundColor = palette.getDominantColor(0)
        }
    }

上面的代码最终能实现我想要的效果,但是我始终觉得不够优雅,后面有机会在封装一下吧

一个进度缓慢增加的圆形进度条

也是封装好的通用组件CommonCircularProgress.kt

@Composable
fun CommonAttributeCircularProgress(text:String,content:String,mProgress: Float,modifier: Modifier){
    Column(
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        var progress = remember {
            mutableStateOf(0.0f)
        }
        LaunchedEffect(true){
            var state = 0.0f
            while (state <= mProgress) {
                progress.value = state
                state += mProgress / 10f
                delay(50)
            }
        }

        Box(){
            Text(text = text,modifier = modifier.align(Alignment.Center))
            CircularProgressIndicator(progress = 1f,
                color = Color(0xFFffcba4),
                modifier = modifier
                    .align(Alignment.Center)
                    .size(150.cdp, 150.cdp)
            )
            CircularProgressIndicator(progress = progress.value,
                color = MaterialTheme.colors.secondary,
                modifier = modifier
                    .align(Alignment.Center)
                    .size(150.cdp, 150.cdp)
            )
        }
        Text(text = content, modifier = modifier.padding(top = 10.cdp))
    }
}

我没有找到能给CircularProgressIndicator可组合项目设置进度条范围内的背景的属性,所以使用了box将其覆盖一个CircularProgressIndicator可组合项来实现其背景的假象

单Activity使用navigation跳转Compose可组合项返回时页面重组的问题

列表项数据我按照官方推荐使用的方法直接使用了collectAsLazyPagingItems,然后我发现它确实起作用了,但是也发生了上诉问题,我每一次从详情页返回到列表页,列表页都会闪烁然后重组。这是因为每一次返回,可组合项都重新进行了请求导致数据发生变化,从而导致重组,为了解决这一问题,我在viewmodel中保存了一份请求得到的数据

@HiltViewModel
class PokemonListViewModel @Inject constructor(
    private val pokemonRepository: PokemonRepository
) :
    ViewModel() {


    // 宝可梦列表数据流  currentResult是为了保证从详情页面返回时不重新加载数据
    var currentResult: Flow<PagingData<PokemonResult>>? = null

    fun getPokemon(searchString: String?): Flow<PagingData<PokemonResult>> {
        val newResult = pokemonRepository.getPokemon(searchString).cachedIn(viewModelScope)
        currentResult = newResult
        return newResult
    }



}

并在页面中这样正确使用collectAsLazyPagingItems

    var list: LazyPagingItems<PokemonResult>? = null
    list = if (vm.currentResult != null) {
        vm.currentResult!!.collectAsLazyPagingItems()
    } else {
        vm.getPokemon(searchString.value).collectAsLazyPagingItems()
    }

这样当我从详情页返回到列表页时,页面显示正常

hiltViewModel()

在使用viemodel时,一开始我按照官方使用viewmodel的示例使用了**viewModel()**方法,并且在调试中是正常的。

val vm: PokemonListViewModel = viewModel()

可当我在加入navigation 后,viewmodel并不能正常的工作,后来查阅资料发现要使用

    implementation "androidx.navigation:navigation-compose:2.5.0-beta01"

包中的 hiltViewModel()

val vm: PokemonListViewModel = hiltViewModel()

主要参考项目

Jetpack Compose仿写网易云音乐
NCMusic;
一个使用原生xml kotlin写的宝可梦图鉴
PokeApi-Pokedex;

总结

整个项目其实就两个可组合项,一个是FullScreenView(列表页),一个是AttributeDetailView(详情页),每个页面就200行代码左右,对比起原生xml,的确是少了很多样板代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python爬虫|全国补充耕地项目数量爬取与分析——多进程案例

一、使用的库 import requests from lxml import etree import time import random import re import openpyxl import openpyxl from pyecharts.charts import Bar, Pie from pyecharts import options as opts from multiprocessing.dummy import Pool 二、数据爬取思路 1…

手拉手Centos7安装配置Redis7

Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 Redis是一个NoSQL数据库&#xff0c;常用缓存(cache) Re…

Spark 安装及WordCount编写(Spark、Scala、java三种方法)

Spark 官网&#xff1a;Apache Spark™ - Unified Engine for large-scale data analytics Spark RDD介绍官网&#xff1a;https://spark.apache.org/docs/2.2.0/api/scala/index.html#org.apache.spark.rdd.RDD 下载好spark解压mv到软件目录 linux>mv spark-xxx-xxx /op…

统计套利策略

统计套利策略套利策略跨品种套利标的择时风控套利策略 套利是&#xff0c;某种商品在&#xff08;在同一市场或不同市场&#xff09;拥有两个价格的情况下&#xff0c;以较低的价格买进&#xff0c;较高的价格卖出&#xff0c;从而实现获利的交易方式。 比如咖啡店里有小杯、…

【jvm系列-04】精通运行时数据区共享区域---堆

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

chapter-6数据库设计原则

以下课程来源于MOOC学习—原课程请见&#xff1a;数据库原理与应用 考研复习 数据库设计 数据库设计是基于应用系统需求分析中对数据的需求&#xff0c;解决数据的抽象、数据的表达和数据的存储等问题&#xff0c;其目标是设计出一个满足应用要求&#xff0c;简洁、高效、规范…

【c语言】二维数组

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ…

「计算机控制系统」3. 计算机控制系统的数学描述

差分方程 Z变换 脉冲传递函数 计算机控制系统的响应 文章目录差分方程基础知识差分方程的解Z变换定义与性质求Z变换Z变换表求Z反变换用Z变换解差分方程脉冲传递函数脉冲传递函数与差分方程的相互转化开环脉冲传递函数闭环脉冲传递函数计算机控制系统的响应差分方程 基础知识 …

Photoshop CS6安装包下载及安装教程(Photoshop 2016)

下载链接&#xff1a; https://pan.quark.cn/s/f961759b36cc “Adobe Photoshop是一款集图像扫描、编辑修改、图像制作、广告创意、图像输入输出于一体的图形图像处理软件,简称ps,对于这款软件大家应该并不陌生,而今天小编带来的是Photoshop2023中文版,也是该系列的最新版本,不…

WAF攻防-菜刀冰蝎哥斯拉流量通讯特征绕过检测反制感知

文章目录菜刀-流量&绕过&特征&检测特征绕过检测冰蝎3-流量&绕过&特征&检测特征通讯过程检测绕过哥斯拉-流量&绕过&特征&检测特征Other使用Proxifier进行流量转发至Burp抓包分析(使用Wireshake也可以) 菜刀-流量&绕过&特征&检…

Java阶段一Day21

Java阶段一Day21 文章目录Java阶段一Day21多线程并发原理使用场景创建并启动线程创建线程的方法进程线程的生命周期获取线程信息的方法教师总结新单词多线程概念线程:一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。多线程:多个单一顺序执行的流程…

最新!AI第一次有了国家标准,北大、华为、百度等单位共同编制

最近&#xff0c;国家标准全文公开系统网站正式发布了国家标准《神经网络表示与模型压缩 第一部分&#xff1a;卷积神经网络》&#xff08;GB/T 42382.1-2023&#xff09;&#xff0c;此标准由北京大学、鹏城实验室、华为、百度等16家单位共同编制。 &#xff08;来源&#xff…

考试前临时抱佛脚有用吗?这篇复习攻略会告诉你答案

夏天来了&#xff0c;大家的期末考试也将不远了。不知平时大家是如何准备考试的&#xff0c;是平时学习计划有序进行复习&#xff0c;还是考试前临时抱佛脚呢&#xff1f;今天就来跟大家讲一讲&#xff0c;学习中很重要的一个环节&#xff0c;如何复习。所以敲黑板&#xff0c;…

基于 AT89C51 单片机的数字时钟设计

目录 1.设计目的、作用 2.设计要求 3.设计的具体实现 3.1 设计原理 3.2 硬件系统设计 3.2.1 AT89C51 单片机原理 3.2.2 晶振电路设计 3.2.3 复位电路设计 3.2.4 LED 数码管显示 3.3 系统实现 3.3.1 系统仿真与调试 3.3.2 演示结果 4.总结 附录 附录 1 附录 2 1.…

【JVM】常量池

常量池&#xff08;Runtime Constant Poo&#xff09; 常量池Java中可以分为三种&#xff1a;字符串常量池&#xff08;堆&#xff09;、Class文件常量池、运行时常量池&#xff08;堆&#xff09;。 1.字符串常量池&#xff08;String Pool&#xff09; 为了提升性能和减少…

C++变量限定

C的变量限定指可以在变量类型的基础上加上特殊的限定条件&#xff0c;主要包括&#xff1a;是不是const&#xff0c;是不是volatile&#xff0c;是左值还是右值&#xff0c;是不是引用&#xff0c;是左值引用还是右值引用&#xff0c;等等。 1. 为什么要研究这个东西 主要是c…

练习之烦人的递归

文章目录1.删除公共字符2.读入一串以?结束的字符串&#xff0c;逆序输出。法一&#xff1a;常规递归法二&#xff1a;投机取巧3.递归将整数输出为字符串4.递归输出1--n的平方和5.递归计算222222...6.递归求最大公约数7.递归输出x的n次方8. 递归计算下列式子的值1.删除公共字符…

从FPGA说起的深度学习(六)-任务并行性

这是新的系列教程&#xff0c;在本教程中&#xff0c;我们将介绍使用 FPGA 实现深度学习的技术&#xff0c;深度学习是近年来人工智能领域的热门话题。在本教程中&#xff0c;旨在加深对深度学习和 FPGA 的理解。用 C/C 编写深度学习推理代码高级综合 (HLS) 将 C/C 代码转换为硬…

还在回想Midjourney的参数,Claude来帮你

本来是想整理一份Midjourne使用的参数表&#xff0c;看来是不用了&#xff0c;Claude很方便的就能帮到我们。 问下Claude: 你知道 Midjourne 的参数吗 Claude 回答如下&#xff1a; 是回答出来了&#xff0c;但是并不是非常的好&#xff0c;我们继续引导他一下&#xff1a; 你…

堆的实际应用(topk问题以及堆排序)

目录 前言&#xff1a; 一:解决topk问题 二:堆排序 【1】第一种方法(很少用) 【2】第二种方法(很实用) 前言&#xff1a; 上一次我们进行了二叉树的初步介绍并实现了堆的基本功能&#xff0c;但堆的作用并不是存储数据&#xff0c;它可以用来解决topk问题(求一组数据较大或…