Android Compose 入门,深入底层源码分析

这篇具有很好参考价值的文章主要介绍了Android Compose 入门,深入底层源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Android Compose 入门,深入底层源码分析

我是跟着AS官网学习的,但是官方的教程写的不是很详细.官网链接
首先创建一个Compose项目,目录结构是这样:
ui
-> theme
-> -> Color.kt
-> -> Theme.kt
-> -> Type.kt
MainActivity.kt
通过阅读源码,发现实际上还少了一个Shapes.kt,我手动添加了.

Type.kt

/**  
 * 存放组件的Style  
 * Typography全部是文字的属性
 * 点开Typography的代码,结构很简单.
 * 存了一些TextStyle,提供以下功能:
 * 主构造函数: 使用一些默认参数初始化各个TextStyle
 * copy: 复制一份
 * equals: 比较每一个TextStyle
 * hashCode: 计算hash,把每个TextStyle都计算进去.
 * fromToken: internal修饰,为Typography类增加拓展函数,根据传进来的enum,确认获取哪个TextStyle.
 * 在class外部还有一个对象:
 * LocalTypography: internal修饰,被MaterialTheme作为默认参数使用
 */  
val Typography = Typography(  
    bodyLarge = TextStyle(  
        fontFamily = FontFamily.Default,  
        fontWeight = FontWeight.Normal,  
        fontSize = 16.sp,  
        lineHeight = 24.sp,  
        letterSpacing = 0.5.sp  
    )
)

Color.kt

/**  
 * 存放颜色值
 * darkColorScheme和lightColorScheme都属于ColorScheme  
 * 点开ColorScheme的代码,结构很简单.
 * 存了一些Color,提供以下功能:
 * 主构造函数: 颜色委托给mutableStateOf,使颜色值的变化可以被Compose观察.
 * copy: 复制一份
 * 剩下的是一些函数:
 * lightColorScheme: 提供默认的白天模式颜色
 * darkColorScheme: 提供默认的夜间模式颜色
 * ColorScheme.contentColorFor: 为ColorScheme类增加拓展函数,根据背景色使用对应的前景色,如果颜色不匹配,返回透明色.
 * contentColorFor: 提供一个函数,import这个函数来使用,如果颜色不匹配,返回黑色.
 * applyTonalElevation: internal修饰,为ColorScheme类增加拓展函数,返回新背景色,传入的背景色加上高度.
 * surfaceColorAtElevation: 为ColorScheme类增加拓展函数,计算不同高度的surface表面色调.
 * updateColorSchemeFrom: internal修饰,为ColorScheme类增加拓展函数,更新颜色,成本很高,但颜色委托给了mutableStateOf,忽略不变化的颜色值,提高运行效率.
 * fromToken: internal修饰,为ColorScheme类增加拓展函数,根据传进来的enum,确认获取哪个Color.
 * toColor: internal修饰,为ColorSchemeKeyTokens类增加拓展函数,将enum转换为对应的颜色,调用fromToken.
 * 在class外部还有两个对象:
 * LocalColorScheme: internal修饰,被MaterialTheme作为默认参数使用,默认使用lightColorScheme.
 * DisabledAlpha: internal修饰,禁用状态的前景色.比如禁用按钮的文字颜色.
 */  
val Purple80 = Color(0xFFD0BCFF)  
val PurpleGrey80 = Color(0xFFCCC2DC)  
val Pink80 = Color(0xFFEFB8C8)  

val Purple40 = Color(0xFF6650a4)  
val PurpleGrey40 = Color(0xFF625b71)  
val Pink40 = Color(0xFF7D5260)  

//深色模式  
val DarkColorScheme = darkColorScheme(  
    primary = Purple80,  
    secondary = PurpleGrey80,  
    tertiary = Pink80  
)  
  
//浅色模式  
val LightColorScheme = lightColorScheme(  
    primary = Purple40,  
    secondary = PurpleGrey40,  
    tertiary = Pink40,  
)

Shapes.kt

/**  
 * 默认创建的项目里没有创建Shapes  
 * 这里也简单介绍一下  
 * 点开Shapes代码,结构很简单.  
 * 存放了一些形状,提供以下功能:  
 * 主构造函数: 存放一些CornerBasedShape  
 * CornerBasedShape基于角的形状,子类有: AbsoluteCutCornerShape,AbsoluteRoundedCornerShape,CutCornerShape,RoundedCornerShape.  
 * https://developer.android.com/reference/kotlin/androidx/compose/foundation/shape/CornerBasedShape * copy: 复制一份  
 * equals: 比较每个shape  
 * hashCode: 计算hash,把每个shape都计算进去.  
 * 类外部:  
 * ShapeDefaults: 提供CornerBasedShape的默认参数  
 * top,bottom,start,end: internal修饰,帮助组件获取Shape.  
 * fromToken: internal修饰,根据传入的enum,返回对应的Shape.  
 * toShape: internal修饰,为ShapeKeyTokens增加扩展函数,把enum转为Shape,调用fromToken.  
 * LocalShapes: internal修饰,被MaterialTheme作为默认参数使用,默认使用ShapeDefaults.  
 */val shapes = Shapes(  
    extraSmall = ShapeDefaults.ExtraSmall  
)

Theme.kt

/**  
 * 构建一个Theme用来使用  
 * 如果不用自己构建的theme,会使用默认的theme.  
 * Theme很简单,分为两部分.  
 * 由Compose托管的:  
 * 使用colorScheme,shapes,typography,content创建一个MaterialTheme.  
 * content使用这个MaterialTheme,并且这个MaterialTheme会递归传递给content内的@Composable修饰的函数.  
 * 非Compose托管的:  
 * 一些不属于View的,属于window的.如状态栏颜色,导航栏是否显示等.  
 * 然后是MaterialTheme的源码
 * MaterialTheme是一个@Composable修饰的函数,按照顺序拆解:
 * rememberedColorScheme,用来更新颜色.调用updateColorSchemeFrom.使用remember让currentComposer缓存colorScheme.copy()返回的对象,下次重组时继续使用该值,涉及的内容太多,这里不再深入.
 * rippleIndication,波纹动画,默认使用透明色,也就是没有波纹动画.
 * selectionColors,文字选中颜色,默认使用:rememberedColorScheme.primary
 * CompositionLocalProvider,一个@Composable修饰的函数,使用上面的参数构建一个ProvidedValue对象,调用currentComposer.startProviders保存这些对象,然后调用content绘制,绘制时会使用这些ProvidedValue对象,然后调用currentComposer.endProviders()终止记录.
 */  
/**  
 * @param darkTheme 是否是深色模式  
 * @param dynamicColor 动态颜色 安卓12(api31) 新增,会基于系统壁纸的颜色使用对应的颜色,https://developer.android.com/develop/ui/views/theming/dynamic-colors  
 * @param content Composable代码块,使用colorScheme作为主题色  
 */  
@Composable  
fun Study1Theme(  
    darkTheme: Boolean = isSystemInDarkTheme(),  
    dynamicColor: Boolean = true,  
    content: @Composable () -> Unit  
) {  
    //Material Design 需要的颜色  
    val colorScheme = when {  
        //使用动态颜色,跟随壁纸,只有大于api31才能使用  
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {  
            val context = LocalContext.current  
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)  
        }  
  
        darkTheme -> DarkColorScheme  
        else -> LightColorScheme  
    }  
  
    //获取View,@Composable的组合函数实际上是一个View  
    val view = LocalView.current  
    //不是编辑模式的情况下,设置一些参数  
    if (!view.isInEditMode) {  
        //window不是Compose管理的对象,需要用SideEffect来共享Compose状态,SideEffect保证每次重组后都会执行  
        SideEffect {  
            //设置status bar 颜色  
            val window = (view.context as Activity).window  
            window.statusBarColor = colorScheme.primary.toArgb()  
            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme  
        }  
    }  
  
    //颜色,字体,代码块构建一个MaterialTheme对象,代码块的MaterialTheme对象会使用这个构建的对象  
    MaterialTheme(  
        colorScheme = colorScheme,  
        typography = typography,  
        shapes = shapes,  
        content = content  
    )  
}

MainActivity.kt

这个没什么好说的,官方的教程说的很明白了.这里简单贴一下代码.文章来源地址https://www.toymoban.com/news/detail-846839.html

class MainActivity : ComponentActivity() {  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        //setContent是Kotlin的扩展函数,使用Compose创建窗口  
        setContent {  
            //Study1Theme在theme/Theme.kt里,生成MaterialTheme给整个代码块用  
            Study1Theme(dynamicColor = false) {  
                //使用一个@Composable函数来作为界面的入口  
                MyApp(Modifier.fillMaxSize())  
            }  
        }    }  
  
    //界面入口,用来复用函数  
    @Composable  
    fun MyApp(modifier: Modifier = Modifier){  
        //Surface,一般显示组件的颜色,如卡片,表格,菜单的背景色  
        Surface(  
            //Modifier.fillMaxSize() 铺满父组件  
            modifier = modifier,  
            //使用Study1Theme里创建的MaterialTheme的colorScheme  
            //colorScheme现在有深色浅色两种模式,也可以添加更多风格.  
            color = MaterialTheme.colorScheme.primary  
        ) {  
            //Surface函数的最后一个参数是content: @Composable () -> Unit  
            //@Composable注解修饰的函数只能被同样@Composable修饰的函数调用  
            SayHello("Android")  
        }  
    }  
  
    //显示一个文本  
    @Composable  
    fun SayHello(name: String, modifier: Modifier = Modifier) {  
        Surface(color = MaterialTheme.colorScheme.primary) {  
            Text(  
                text = "Hello $name!",  
                modifier = modifier.padding(24.dp)  
            )  
        }  
    }  
  
    //Preview可以预览无参或者有默认参数的Compose函数  
    @Preview(showBackground = true, name = "Say Hello Preview")  
    @Composable  
    fun SayHelloPreview(name: String = "Compose") {  
        Study1Theme(dynamicColor = false) {  
            MyApp()  
        }  
    }  
}

到了这里,关于Android Compose 入门,深入底层源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Android JetPack深入分析LiveData源码

    Android JetPack深入分析LiveData源码

    Google Android开发者 LiveData概览 在了解 LiveData 源码之前,建议先了解 LifeCycle 相关知识,请参考:Android JetPack深入分析Lifecycle源码 定义 从定义中,我们可以大概知道: LiveData 是一个数据存储类,能够感知 Activity 、 Fragment 等组件的生命周期,并且支持对它存储的数据进行观察

    2024年02月12日
    浏览(13)
  • Android JetPack深入分析Lifecycle源码

    Android JetPack深入分析Lifecycle源码

    关键类介绍 Lifecycle 定义: 用于存储有关组件(如 activity 或 fragment)的生命周期状态的信息,并允许其他对象观察此状态。 它是一个 抽象类 ,具体实现类为 LifecycleRegistry ; 内部提供了 addObserver(LifecycleObserver observer) 添加观察者 、 removeObserver(LifecycleObserver observer)移除观察者

    2024年02月12日
    浏览(12)
  • 【Android】底层逻辑深入了解(学习笔记)(未完)

    【Android】底层逻辑深入了解(学习笔记)(未完)

    step by step. 目录 init启动 Zygote进程:  SystemServer处理过程 Binder: Launcher启动过程 Android系统启动流程 四大组件 Activity Service  BroadcastReceiver广播 ContentProvider内容提供者(进程内和进程间的数据共享)  Context上下文  AMS(ActivityManagerService) (在图书馆看了《Android进阶解密》,

    2024年02月15日
    浏览(11)
  • 源码分析——ConcurrentHashMap源码+底层数据结构分析

    源码分析——ConcurrentHashMap源码+底层数据结构分析

    1. 存储结构 Java 7 中 ConcurrentHashMap 的存储结构如上图,ConcurrnetHashMap 由很多个 Segment 组合,而每一个 Segment 是一个类似于 HashMap 的结构,所以每一个 HashMap 的内部可以进行扩容。但是 Segment 的个数一旦 初始化就不能改变 ,默认 Segment 的个数是 16 个,你也可以认为 ConcurrentH

    2024年02月13日
    浏览(16)
  • LinkedList部分底层源码分析

    LinkedList部分底层源码分析

    JDK版本为1.8.0_271,以插入和删除元素为例,LinkedList部分源码如下: 插入删除结点的过程如图所示: 只有1个元素的LinkedList 包含4个元素的LinkedList add(E e)方法 add(int index,E e)方法 remove(Object obj)方法 remove(int index)方法

    2024年04月13日
    浏览(13)
  • MyBatis底层源码分析

    MyBatis底层源码分析

    🎄欢迎来到@边境矢梦°的csdn博文🎄 🎄本文主要梳理MyBatis底层源码分析 🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆 Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑🌒🌓🌔🌕 

    2024年02月08日
    浏览(11)
  • ArrayList底层结构和源码分析

    1.permits all elements, including null,ArrayList 可以加入null,并且多个 2.ArrayList是由数组来实现数据存储的 3.ArrayList 基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码.在多线程情况下,不建议使用ArrayList 代码演示: ArrayList的底层操作机制源码分析 (重点,难点.) 1.Arra

    2023年04月24日
    浏览(11)
  • ArrayList 底层结构及源码分析

    ArrayList 实现了 List 接口。它可以存储包括 null 的任何类型的对象,允许重复元素。 ArrayList 在内部使用一个数组来存储元素,当元素数量超过数组容量时, ArrayList 会自动重新分配更大的内部数组,并且将现有元素复制到新数组中。 ArrayList 基本等同于 Vector ,但是 ArrayList 是

    2024年02月08日
    浏览(11)
  • ArrayList 底层结构和源码分析

    ArrayList 实现了 List 接口。它可以存储包括 null 的任何类型的对象,允许重复元素。 ArrayList 在内部使用一个数组来存储元素,当元素数量超过数组容量时, ArrayList 会自动重新分配更大的内部数组,并且将现有元素复制到新数组中。 ArrayList 基本等同于 Vector ,但是 ArrayList 是

    2024年02月08日
    浏览(11)
  • 源码分析——HashMap(JDK1.8)源码+底层数据结构分析

    源码分析——HashMap(JDK1.8)源码+底层数据结构分析

    HashMap 主要用来存放键值对,它基于哈希表的Map接口实现,是常用的Java集合之一。 JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈

    2024年02月13日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包