JetPack Compose 实战 Jetchat(4)

时间:2021-7-3 作者:qvyue

我们继续官方Jetchat这个项目讲解

MainActivity 的入口最后一部分代码

 JetchatScaffold(
                        scaffoldState,
                        onChatClicked = {
                            findNavController(R.id.nav_host_fragment)
                                .popBackStack(R.id.nav_home, true)
                            scaffoldState.drawerState.close()
                        },
                        onProfileClicked = {
                            val bundle = bundleOf("userId" to it)
                            findNavController(R.id.nav_host_fragment).navigate(
                                R.id.nav_profile,
                                bundle
                            )
                            scaffoldState.drawerState.close()
                        }
                    ) {
                        // Workaround for https://issuetracker.google.com/178174718
                        // and https://issuetracker.google.com/179181757

                        // Inflate the XML layout using View Binding:
                        val bindingRef = remember { Ref() }
                        val currentView = LocalView.current

                        AndroidViewBinding({ inflater, parent, attachToParent ->
                            if (bindingRef.value == null) {
                                val binding: ViewBinding =
                                    ContentMainBinding.inflate(inflater, parent, attachToParent)
                                bindingRef.value = binding
                                binding.root.compositionContext =
                                    currentView.findViewTreeCompositionContext()
                            }
                            bindingRef.value as ViewBinding
                        })
                        // End of workaround

                        // AndroidViewBinding(ContentMainBinding::inflate)
                    }

JetchatScaffold
封装了自己的脚手架或者页面主题和布局

@Composable
fun JetchatScaffold(
    scaffoldState: ScaffoldState = rememberScaffoldState(),
    onProfileClicked: (String) -> Unit,
    onChatClicked: (String) -> Unit,
    content: @Composable (PaddingValues) -> Unit
) {
    JetchatTheme {
        Scaffold(
            scaffoldState = scaffoldState,
            drawerContent = {
                JetchatDrawer(
                    onProfileClicked = onProfileClicked,
                    onChatClicked = onChatClicked
                )
            },
            bodyContent = content
        )
    }
}

利用组合思想内部封装了JetchatTheme 自定义主题

@Composable
fun JetchatTheme(
    isDarkTheme: Boolean = isSystemInDarkTheme(),
    colors: Colors? = null,
    content: @Composable () -> Unit
) {
    val myColors = colors ?: if (isDarkTheme) JetchatDarkPalette else JetchatLightPalette

    MaterialTheme(
        colors = myColors,
        content = content,
        typography = JetchatTypography,
        shapes = JetchatShapes
    )
}

我们看到这里就要回顾主题相关知识。isDarkTheme 判断是否是深色主题,那么MaterialDesign方式封装了两套主题。深色和浅色

JetchatDarkPalette 和 JetchatLightPalette

private val JetchatDarkPalette = darkColors(
    primary = Blue200,
    primaryVariant = Blue400,
    onPrimary = Color.Black,
    secondary = Yellow400,
    onSecondary = Color.Black,
    onSurface = Color.White,
    onBackground = Color.White,
    error = Red300,
    onError = Color.Black
)

private val JetchatLightPalette = lightColors(
    primary = Blue500,
    primaryVariant = Blue800,
    onPrimary = Color.White,
    secondary = Yellow700,
    secondaryVariant = Yellow800,
    onSecondary = Color.Black,
    onSurface = Color.Black,
    onBackground = Color.Black,
    error = Red800,
    onError = Color.White
)

使用看来很简单,特别想C++里面的结构提,其实就是两个全局变量

封装自己的字体等样式排版,val JetchatTypography---Typography

特别接近CSS 有这个感觉没,好像高级CSS也是面向对象,本人对网页不是很熟。

学习到定义形状,三个Shapes

val JetchatShapes = Shapes(
    small = RoundedCornerShape(50),
    medium = RoundedCornerShape(8.dp),
    large = RoundedCornerShape(0.dp)
)

看似有电生疏,我们没有做东西而已。

系统MaterialTheme 定义好了参数,我们自定义传入就好

接下来,我们要到过来,向上层看。

JetchatTheme 组合传入的就是JetchatDrawer 上篇文章提到过。

JetPack Compose 实战 Jetchat(4)
jetpack_jetdrawer.png

封装的就是这个布局和点击事件 onProfileClicked,onChatClicked

  1. 粗略的看 Spacer 定义了layout布局传入Modifier

  2. 类似Android传统,定义Header DawerHeader()—组合Row两个Image

  3. 运行项目会看到一个分割线 Divider(),

  4. DrawerItemHeader 定义标题头 Chats

  5. 接下来定义两个ChatItem,包括点击事件,就不看封装源码。

  6. DrawerItemHeader 标题头

  7. 接下来定义两个ProfileItem 组合控件。

继续向上层回溯看。

JetchatScoffold里面 定义跳转用的Navigation,NavController

内容,用View Binding结合inflate出XML布局

                        // Inflate the XML layout using View Binding:
                        val bindingRef = remember { Ref() }
                        val currentView = LocalView.current

                        AndroidViewBinding({ inflater, parent, attachToParent ->
                            if (bindingRef.value == null) {
                                val binding: ViewBinding =
                                    ContentMainBinding.inflate(inflater, parent, attachToParent)
                                bindingRef.value = binding
                                binding.root.compositionContext =
                                    currentView.findViewTreeCompositionContext()
                            }
                            bindingRef.value as ViewBinding
                        })

我们注意到remember 记录值用的,可以理解缓存。
还有很多地方,看的不是很清晰,整体来看,大致整个小项目,还是很简单。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。