【问题标题】:TopAppBar not adjusting height automatically in Compose and TabRow not workingTopAppBar 在 Compose 和 TabRow 中没有自动调整高度不起作用
【发布时间】:2021-09-02 14:38:29
【问题描述】:

基本上,我有两个可组合的函数,它们创建一个 TopAppBar 并添加一个包含在应用栏中的选项卡布局:

@Composable
fun ZCryptAppBar(
    modifier: Modifier = Modifier,
    title: @Composable RowScope.() -> Unit
) {
    Column(Modifier.fillMaxWidth()) {
        TopAppBar(
            title = {
                Column {
                    Row { title() }
                    Row {
                        TabLayout()
                    }
                }
            },
            modifier = modifier,
            backgroundColor = MaterialTheme.colors.primary,
            contentColor = Color.White
        )
    }
}

@Composable
fun TabLayout() {
    var selectedTab by remember {
        mutableStateOf(0)
    }
    TabRow(
        modifier = Modifier.fillMaxWidth(),
        selectedTabIndex = selectedTab,
        backgroundColor = MaterialTheme.colors.primary,
        tabs = {
            Tab(
                selected = selectedTab == 0,
                onClick = { selectedTab = 0 },
                text = { Text(stringResource(R.string.encrypt)) },
                icon = {
                    Image(
                        painterResource(id = R.drawable.ic_padlock_black),
                        stringResource(R.string.descr_icon_padlock)
                    )
                }
            )
            Tab(
                selected = selectedTab == 0,
                onClick = { selectedTab = 0 },
                text = { Text(stringResource(R.string.decrypt)) },
                icon = {
                    Image(
                        painterResource(id = R.drawable.ic_padunlock_black),
                        stringResource(R.string.descr_icon_padunlock)
                    )
                }
            )
        }
    )
}

但是我在这里遇到了两个问题:首先,当我点击一个标签时,什么也没有发生,并且应用程序停留在同一个标​​签中。

其次,TopAppBar 似乎不会自动调整其高度,因为选项卡名称和图标都被裁剪了:

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案1】:

    TopAppBar 实现了Material design specs 并具有56.dp 的固定高度。

    你可以使用:

    Column(Modifier.fillMaxWidth()) {
        TopAppBar(
            title = {
                Column() {
                    Row { Text("Title") }
                }
            },
            backgroundColor = MaterialTheme.colors.primary,
            contentColor = Color.White
        )
        TabLayout()
    }
    

    然后在你的TabLayout 中使用:

           Tab(
                selected = selectedTab == 0,
                onClick = { selectedTab = 0 },
                //.....
            )
            Tab(
                selected = selectedTab == 1,
                onClick = { selectedTab = 1 },
                //.....
            )
    

    【讨论】:

    • 哦,谢谢你成功了。哪里说 TopAppBar 的高度是固定的?我在文档中没有看到这一点,我会将其转化为对 Google 的建议
    • @ScarySneer TopAppBar 实现了材料设计specs。您也可以检查代码。它使用带有此修饰符的AppBar.height(AppBarHeight) 其中AppBarHeight = 56.dp
    【解决方案2】:
    @Composable
    fun ZCryptAppBar(
        modifier: Modifier = Modifier,
        title: @Composable RowScope.() -> Unit
    ) {
        Column(Modifier.fillMaxWidth()) {
            TopAppBar(
                content = {
                    Column {
                        Row { title() }
                        Row {
                            TabLayout()
                        }
                    }
                },
                modifier = modifier,
                backgroundColor = MaterialTheme.colors.primary,
                contentColor = Color.White
            )
        }
    }
    
    @Composable
    fun TabLayout() {
        var selectedTab by remember {
            mutableStateOf(0)
        }
        TabRow(
            modifier = Modifier.fillMaxWidth(),
            selectedTabIndex = selectedTab,
            backgroundColor = MaterialTheme.colors.primary,
            tabs = {
                Tab(
                    selected = selectedTab == 0,
                    onClick = { selectedTab = 0 },
                    text = { Text(stringResource(R.string.encrypt)) },
                    icon = {
                        Image(
                            painterResource(id = R.drawable.ic_padlock_black),
                            stringResource(R.string.descr_icon_padlock)
                        )
                    }
                )
                Tab(
                    selected = selectedTab == 1,
                    onClick = { selectedTab = 1 },
                    text = { Text(stringResource(R.string.decrypt)) },
                    icon = {
                        Image(
                            painterResource(id = R.drawable.ic_padunlock_black),
                            stringResource(R.string.descr_icon_padunlock)
                        )
                    }
                )
            }
        )
    }
    

    复制和粘贴时,忘记更改值是很常见的。有趣的是它经常发生,我自己做了很多次。试试看

    哦,顺便说一句,你在这里使用了错误的变体 ``TopAppBar``` 剪辑的原因可能是您将所有内容都塞进了栏的标题中。改用“内容”应该可以解决这个问题。如果没有,请尝试 Modifier.wrapContentSize()

    标签没有改变,因为您在两个标签中应用了相同的逻辑。

    【讨论】:

    • 大声笑我很抱歉这是一个虚拟的复制粘贴问题。谢谢,现在选项卡正在切换,但即使使用内容参数而不是标题,图标和文本仍会被裁剪。顺便说一句,为什么谷歌提供像 1 func 名称但它可以指向行为完全不同的两个不同函数。这也发生在具有 2 个完全不同的功能的 Tab 元素上。为什么不命名它们或以不同的方式命名它们并在文档中解释两者之间的差异?
    • 不应该真的发生。您是否尝试过设置明确的高度以查看它是否有效?
    • 当然不是解决办法,只是为了获取信息,试试看
    • 关于 Google 这样做的原因,不止一个。这是编程中的一种常见技术,称为方法重载。我们可以根据需要创建尽可能多的变体,名称相同,但签名(参数)不同。这样我们就可以使用最适合我们用例的那个。倒是一个优势。在文档中,您将看到它是构成开箱即用支持的材料组件的一部分。因此,为了支持不同的材质样式(比如有或没有图标),有多个同名的方法
    • 关于应用栏的两件事。我首先尝试删除 tabrow 并为第一行设置一个非常高的 fontSize { title() },结果 appBar 也不会自动调整其高度以显示整个标题。标题刚刚被裁剪,appbar 保持相同的高度。但是,如果我设置自定义 Modifier.size() 则 appbar 会根据我传递的参数更改其高度和宽度。我认为这种编码 UI 的方式不是很好,哈哈。我错过了什么/做错了,或者这只是一个错误,因为 jetpack compose 仍处于测试阶段?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    相关资源
    最近更新 更多