Верхняя панель не настраивает высоту автоматически при создании, а вкладка не работает

#android #kotlin #android-jetpack-compose

Вопрос:

В принципе, у меня есть две составные функции, которые создают 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 кажется, что он автоматически не регулирует свою высоту, так как название вкладки и значок обрезаны :

Ответ №1:

Он TopAppBar реализует спецификации дизайна материалов и имеет фиксированную высоту 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 },
            //.....
        )
 

введите описание изображения здесь

Комментарии:

1. О, спасибо, это сработало. Где сказано, что высота верхней панели фиксирована ? Я не видел этого в документах, я бы превратил это в предложение для Google

2. @ScarySneer TopAppBar реализует спецификации дизайна материалов. Вы также можете проверить код. Он использует 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. Лол, мне так жаль, что это фиктивная проблема с копипастом. Спасибо, теперь вкладки переключаются, однако значки и текст по-прежнему обрезаются, даже используя параметр содержимого вместо заголовка. Кстати, почему Google предлагает как 1 название функции, но которое может указывать на две разные функции, которые ведут себя совершенно по-разному. Это также происходит для элемента Tab, который имеет 2 совершенно разные функции. Почему бы просто не назвать их или по-другому и не объяснить в документах различия между 2 ?

2. На самом деле этого не должно было произойти. Вы пробовали установить явную высоту, чтобы посмотреть, работает ли это?

3. Конечно, это не решение, но просто чтобы получить информацию, попробуйте это

4. О том, почему Google это делает, я говорю не только об этом. Это распространенный метод в программировании, называемый перегрузкой методов. Мы можем создать столько вариантов, сколько потребуется, с одним и тем же именем, но разными сигнатурами (параметрами). Это делается для того, чтобы мы могли использовать тот, который лучше всего подходит для нашего варианта использования. Это скорее преимущество. В документах вы увидите, что это часть компонентов материала, которые составляют опоры из коробки. Следовательно, для поддержки различных стилей материалов (например, со значками или без них) существует несколько методов с одним и тем же именем

5. Итак, две вещи о панели приложений. Сначала я попытался удалить вкладку и установить очень высокий размер шрифта для первой строки { title ()}, и оказалось, что панель приложений также не автоматически регулирует свою высоту, чтобы отобразить весь заголовок. Заголовок просто обрезан, а панель приложений сохраняет прежнюю высоту. Однако, если я задам пользовательский модификатор.size (), панель приложений изменит свою высоту и ширину в соответствии с переданными мной параметрами. Я думаю, что такой способ кодирования пользовательского интерфейса не очень хорош, лол. Я что-то упускаю/делаю неправильно или это просто ошибка, так как jetpack compose все еще находится в бета-версии ?