1. 程式人生 > 其它 >Jetpack Compose - TabRow、ScrollableTabRow

Jetpack Compose - TabRow、ScrollableTabRow

技術標籤:Jetpack-ComposeJetpackComposeTabTabRowScrollableTab

Jetpack Compose - TabRow、ScrollableTabRow

Compose系列文章,請點原文閱讀。原文,是時候學習Compose了!

0、介紹

0.1、TabRow

TabRow包含一行Tab,並在當前選定的Tab下方顯示一個指示器。 TabRow將其Tab在整行中均勻分佈,每個選項卡佔用相等的空間。

0.2、ScrollableTabRow

ScrollableTabRow包含一行Tab,並在當前選定的選項卡下方顯示一個指示器。 ScrollableTabRow將其Tab從起始位置開始放置,並允許滾動到螢幕外放置的Tab。

0.3、Tab

通常用於TabRow內部,一般是使用文字或圖標表示。

1、屬性一覽

【目前基於alpha09版本】

1.1、TabRow:

@Composable fun TabRow(
    selectedTabIndex: Int, 
    modifier: Modifier = Modifier, 
    backgroundColor: Color = MaterialTheme.colors.primarySurface, 
    contentColor: Color = contentColorFor(backgroundColor), 
    indicator: (tabPositions: List<TabPosition>) -> Unit = { tabPositions ->
        TabDefaults.Indicator(
            Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
        )
    }, 
    divider: () -> Unit = {
        TabDefaults.Divider()
    }, 
    tabs: () -> Unit
): Unit

屬性引數含義:

引數含義
modifier: Modifier = Modifier應用於佈局的修飾符
selectedTabIndex: Int當前所選Tab的索引
backgroundColor: Color = MaterialTheme.colors.primarySurfaceTabRow的背景顏色
contentColor: Color = contentColorFor(backgroundColor)內容子級的顏色
indicator: (tabPositions: List) -> Unit = { tabPositions -> TabDefaults.Indicator( Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]) ) }代表當前選擇哪個Tab的指示器。預設情況下,它是一個TabDefaults.Indicator,使用TabDefaults.tabIndicatorOffset修飾符為其位置設定動畫
divider: () -> Unit = { TabDefaults.Divider() }顯示在TabRow底部的分隔線
tabs: () -> Unit此TabRow中的選項卡。通常包含多個選項卡。將測量此lambda中的每個元素,並將其均勻地放置在TabRow上,每個元素佔據相等的空間。

1.2、ScrollableTabRow

@Composable fun ScrollableTabRow(
    selectedTabIndex: Int, 
    modifier: Modifier = Modifier, 
    backgroundColor: Color = MaterialTheme.colors.primarySurface, 
    contentColor: Color = contentColorFor(backgroundColor), 
    edgePadding: Dp = TabDefaults.ScrollableTabRowPadding, 
    indicator: (tabPositions: List<TabPosition>) -> Unit = { tabPositions ->
        TabDefaults.Indicator(
            Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
        )
    }, 
    divider: () -> Unit = {
        TabDefaults.Divider()
    }, 
    tabs: () -> Unit
): Unit

該函式和上面函式引數類似,這裡只介紹一個不同的引數:

引數含義
edgePadding: Dp = TabDefaults.ScrollableTabRowPaddingScrollableTabRow的開始和結束邊緣與其內部選項卡之間的距離(預設是有52dp的一個padding)

1.3、Tab

關於tab有兩個函式,如下:

@Composable fun Tab(
    selected: Boolean, 
    onClick: () -> Unit, 
    modifier: Modifier = Modifier, 
    text: () -> Unit = emptyContent(), 
    icon: () -> Unit = emptyContent(), 
    interactionState: InteractionState = remember { InteractionState() }, 
    selectedContentColor: Color = AmbientContentColor.current, 
    unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)
): Unit
@Composable fun Tab(
    selected: Boolean, 
    onClick: () -> Unit, 
    modifier: Modifier = Modifier, 
    interactionState: InteractionState = remember { InteractionState() }, 
    selectedContentColor: Color = AmbientContentColor.current, 
    unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium), 
    content: ColumnScope.() -> Unit
): Unit
引數含義
selected: Boolean該Tab是否被選中
onClick: () -> Unit點選該Tab時候的回撥事件
modifier: Modifier = Modifier應用於該Tab的修飾符
text: () -> Unit = emptyContent()顯示在該Tab中的文字
icon: () -> Unit = emptyContent()顯示在該Tab中的圖示
interactionState: InteractionState = remember { InteractionState() }該Tab的互動狀態
selectedContentColor: Color = AmbientContentColor.current選中該Tab時內容的顏色,以及水波紋的顏色
unselectedContentColor: Color = selectedContentColor.copy(alpha = ContentAlpha.medium)未選中該Tab時內容的顏色

當我們需要自定義Tab的時候可以使用第二個函式,自定義引數如下:

引數含義
content: ColumnScope.() -> Unit自定義Tab的內容,預設是縱向佈局

2、使用示例

我們直接對比這兩個函式來使用,在TabRow中我們定義了3個Tab,第三個Tab的內容很長,在ScrollableTabRow中我們定義了5個Tab,第五個Tab的內容很長,程式碼如下:


@Composable
fun TabRowDemo() {
    var state = remember { mutableStateOf(0) }
    val titles = listOf("標籤1", "標籤2", "這是很長的標籤3")

    Column {
        TabRow(selectedTabIndex = state.value) {
            titles.forEachIndexed { index, title ->
                Tab(
                    text = { Text(title) },
                    selected = state.value == index,
                    onClick = { state.value = index }
                )
            }
        }

        Spacer(modifier = Modifier.height(20.dp))

        Text(
            modifier = Modifier.align(Alignment.CenterHorizontally),
            text = "第${state.value + 1}個標籤被選中了",
            style = MaterialTheme.typography.body1
        )
    }
}

@Composable
fun ScrollableTabRowDemo() {
    var state = remember { mutableStateOf(0) }
    val titles = listOf("標籤1", "標籤2", "標籤3", "標籤4", "這是很長的標籤5")
    Column {
        ScrollableTabRow(
            selectedTabIndex = state.value,
            modifier = Modifier.wrapContentWidth(),
            edgePadding = 16.dp
        ) {
            titles.forEachIndexed { index, title ->
                Tab(
                    text = { Text(title) },
                    selected = state.value == index,
                    onClick = { state.value = index }
                )
            }
        }

        Spacer(modifier = Modifier.height(20.dp))

        Text(
            modifier = Modifier.align(Alignment.CenterHorizontally),
            text = "第${state.value + 1}個標籤被選中了",
            style = MaterialTheme.typography.body1
        )
    }
}

所以實現效果如下所示:

在這裡插入圖片描述

3、版本更新

  • 暫無

4、未解決問題

目前TabRow的基本使用就是這樣了,關於自定義的內容我們稍後再講,現在還沒有ViewPager的相關資訊,很期待在Compose中ViewPager將會以什麼樣的方式登場。