jetpack组件-----声明式UI:Compose(一):简单实现一个界面

最近一直在准备软考,天天在看教学视频,这不后天就要考试了,我报的是软件设计师,说说我对软考的理解吧,软考高级我不知道,就中级而言,非常符合中国的应试性教育。考的都很广,但没有一样东西考的精,我学了那么长时间,知识储备已经有了,考试应付足够了,但我觉得我可能永远没有机会把这些只是应用到实际中。扯多了,回归正题。
我第一次听说compose是在逛Android大牛讲堂的时候,大佬说这会成为以后UI的主流框架,就很好奇到底是什么样的东西能够动摇xml那么多年的老大哥位置,还一直被谷歌力推,下面就让我们来一步步走近它。
参看文章:Android开发者平台

什么是compose

先看官方的解释:
Jetpack Compose 是一个适用于 Android 的新式声明性界面工具包。Compose 提供声明性 API,让您可在不以命令方式改变前端视图的情况下呈现应用界面,从而使编写和维护应用界面变得更加容易。此术语需要一些解释说明,它的含义对应用设计非常重要。
这里我就官方解释给出自己的理解,不以命令方式改变前端视图来呈现应用界面,其实就是叫我们摒弃命令式UI,来使用Compose这种声明式UI。那为什么要这样做呢?
我们的传统式UI在绘制界面上都是重新生成整个视图,如果我们从服务器拿到一条数据需要适配给多个视图,那更新起来会很麻烦,甚至出现忘记去更改数据的情况,Compose可以避免这种情况,当然,这是后话了。还有一个原因是传统命令式UI需要重新绘制视图,从头到尾重新渲染,这会导致消耗资源大,速度慢,而Compose做的只是在概念上从头开始重新生成整个屏幕,实际上只执行必要的更改。这就是他相比较于xml的优势所在。

compose的简单使用

Compose的使用需要下载Android studio的Fox及以上版本,然后new一个compose的新工程,选择Empty Compose Activity


image.png

基本代码如下:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeDemo2Theme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemo2Theme {
        Greeting("Android")
    }
}

我们可以看到很多不一样的东西,首先看到两个注解@compose和@Preview,@compose注解表示此注释可告知 Compose 编译器:此函数旨在将数据转换为界面。也就是说带有@conpose注解的函数都是编写界面的函数,通常我们叫它可组合函数。
对于@Preview注解看看官方的解释:
Android Studio 允许您在 IDE 中预览可组合函数,无需将应用安装到 Android 设备或模拟器中。可组合函数必须为任何参数提供默认值。因此,您无法直接预览 MessageCard() 函数,而是需要创建另一个名为 PreviewMessageCard() 的函数,由该函数使用适当的参数调用 MessageCard()。请在 @Composable 上方添加 @Preview 注解。
就是@Preview注解的函数编写的界面会展示在预览区中。和实际效果不一定相同。
比如上述代码改成

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeDemo2Theme {
                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    Greeting("蒙奇.D.路飞")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemo2Theme {
        Greeting("Android")
    }
}

我们可以看到在setContent中调用的和在预览函数中调用的Greeting函数传的参数不一样,所以预览视图和实际运行界面也不一样
预览视图:


image.png

实际界面截图:


Screenshot_2021-11-04-15-33-19-904_com.example.co.jpg

那要怎么让他们统一呢,很简单,我们只需要在setContent里面也调用预览函数就可以了,如下:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DefaultPreview()
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemo2Theme {
        Greeting("蒙奇.D.路飞")
    }
}

这样预览效果和实际效果就是一样的了。

compose实现简单布局

我们以官方给出的简单demo为例:比如我们要创建这样一个视图:


image.png

首先在布局里面添加三个文本:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DefaultPreview()
        }
    }
}

@Composable
fun message(name: String, othername: String, phone: Long) {
        Text(text = "绰号:$othername", fontSize = 14.sp)
        Text(text = "电话号码:$phone", fontSize = 14.sp)
        Text(text = "姓名: $name!", fontSize = 14.sp)
}


@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemoTheme {
            message(name = "张志平", othername = "大帅比", phone = 110)
    }
}

效果如图所示:


image.png

我们会发现重叠在了一起,这时候使用Cloumn可以使他们竖直排序

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DefaultPreview()
        }
    }
}

@Composable
fun message(name: String, othername: String, phone: Long) {
    Column {
        Text(text = "绰号:$othername", fontSize = 14.sp)
        Text(text = "电话号码:$phone", fontSize = 14.sp)
        Text(text = "姓名: $name!", fontSize = 14.sp)
    }
}


@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemoTheme {
        message(name = "张志平", othername = "大帅比", phone = 110)
    }
}

如图:


image.png

接下来添加图片,图片与文字水平,使用Row

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DefaultPreview()
        }
    }
}

@Composable
fun message(name: String, othername: String, phone: Long) {
    Column {
        Text(text = "绰号:$othername", fontSize = 14.sp)
        Text(text = "电话号码:$phone", fontSize = 14.sp)
        Text(text = "姓名: $name!", fontSize = 14.sp)
    }
}


@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemoTheme {
        Row(modifier = Modifier.padding(all = 8.dp)) {
            Image(
                painter = painterResource(id = R.drawable.tx),
                contentDescription = "联系人照片",
                modifier = Modifier
                    .size(60.dp)
                    .scale(1.0F),
                contentScale = ContentScale.FillBounds
            )
            Spacer(modifier = Modifier.width(8.dp))
            message(name = "张志平", othername = "大帅比", phone = 110)
        }
    }
}

图片如图所示:


image.png

到此,一个compose的简单例子就完成了,可能里面有些方法和写法大家会觉得很不熟悉,建议点进去看一下源码,我也是看着源码写的,源码的注释已经很清楚了,不会看的兄弟们一定要学着去看,其实很简单,不要自己把自己劝退,比如Image()里面的构造参数,怎么调大小,怎么调比例,都是在源码里面可以找到的,后续我会逐渐深入地去了解它,也会写出文章和大家交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容