Android Jetpack Compose 中的Tabs(TabLayout)

news2024/11/17 8:34:25

Android Jetpack Compose 中的Tabs(TabLayout)

添加依赖

我们需要依赖于2个 accompanist组件,你可以从下面链接中获取最新版本https://github.com/google/accompanist/tree/main/pager#pager-composable-for-jetpack-compose

def accompanist_version = "0.28.0"
implementation "com.google.accompanist:accompanist-pager:$accompanist_version" // Pager
implementation "com.google.accompanist:accompanist-pager-indicators:$accompanist_version" // Pager Indicators

准备

在实现Tabs之前,我们将创建data类和Screen类。

data class TabRowItem(
    val title: String,
    val icon: ImageVector,
    val screen: @Composable () -> Unit,
)

这个数据类可以根据要求更改。您可以删除titleicon,但其中至少一个必须保留。

@Composable
fun TabScreen(
    text: String,
) {
    Box(
        modifier = Modifier
            .fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Text(
            text = text,
            style = MaterialTheme.typography.body1,
        )
    }
}

这将用于我们的示例。您可以并应该稍后更改它。
最后,让我们创建选项卡列表。

val tabRowItems = listOf(
    TabRowItem(
        title = "Tab 1",
        screen = { TabScreen(text = "Tab 1") },
        icon = Icons.Rounded.Place,
    ),
    TabRowItem(
        title = "Tab 2",
        screen = { TabScreen(text = "Tab 2") },
        icon = Icons.Rounded.Search,
    ),
    TabRowItem(
        title = "Tab 3",
        screen = { TabScreen(text = "Tab 3") },
        icon = Icons.Rounded.Star,
    )
)

实现

val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()

pagerState将需要记住和保持页面器的状态。

coroutineScope将用于pagerState滚动。

Column(
    modifier = Modifier
        .padding(contentPadding)
) {
    TabRow(
        selectedTabIndex = pagerState.currentPage,
        indicator = { tabPositions ->
            TabRowDefaults.Indicator(
                Modifier.pagerTabIndicatorOffset(pagerState, tabPositions),
                color = MaterialTheme.colors.secondary
            )
        },
    ) {
        // Will be added later
    }
}

我们首先添加TabRow,这将是Tab的容器。

selectedTabIndex是当前选定选项卡的索引。

indicator表示当前选定的选项卡。

Column(
    modifier = Modifier
        .padding(contentPadding)
) {
    TabRow(
        //..
    ) {
        tabRowItems.forEachIndexed { index, item ->
            Tab(
                selected = pagerState.currentPage == index,
                onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } },
                icon = {
                   Icon(imageVector = item.icon, contentDescription = "")
                },
                text = {
                    Text(
                        text = item.title,
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis,
                    )
                }
            )
        }
    }

在TabRow里,我们将创建Tab。由于我们已经创建了tabs列表,因此我们将简单地调用tabRowItems.forEachIndex并设置Tabs

选择selected属性,即此选项卡是否被选中。

icontext是可选的。您可以选择其中一个或两者,就像我们的示例一样。

onClick方法中,我们启动coroutineScope并调用animateScrollToPage函数。它简单地将给定页面动画滚动到视图的中心。

Column(
    modifier = Modifier
        .padding(contentPadding)
) {
    TabRow(
        //...
    ) {
        //...
    }
    HorizontalPager(
        count = tabRowItems.size,
        state = pagerState,
    ) {
        tabRowItems[pagerState.currentPage].screen()
    }
}

HorizontalPager是一种水平滚动布局,允许用户在左右两侧之间翻转项目。

最后,我们将添加HorizontalPagercount是页面数量,state是用于控制或观察分页器状态的对象,我们已经在上面创建了它。

HorizontalPager中,我们将获取当前页面并调用Screen,这也是我们在自定义数据类中已经创建的。
tabs
完整代码如下:

val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()

Column(
    modifier = Modifier
        .padding(contentPadding)
) {
    TabRow(
        selectedTabIndex = pagerState.currentPage,
        indicator = { tabPositions ->
            TabRowDefaults.Indicator(
                Modifier.pagerTabIndicatorOffset(pagerState, tabPositions),
                color = MaterialTheme.colors.secondary
            )
        },
    ) {
        tabRowItems.forEachIndexed { index, item ->
            Tab(
                selected = pagerState.currentPage == index,
                onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } },
                icon = {
                   Icon(imageVector = item.icon, contentDescription = "")
                },
                text = {
                    Text(
                        text = item.title,
                        maxLines = 2,
                        overflow = TextOverflow.Ellipsis,
                    )
                }
            )
        }
    }
    HorizontalPager(
        count = tabRowItems.size,
        state = pagerState,
    ) {
        tabRowItems[pagerState.currentPage].screen()
    }
}

效果动画如下:
tabs swipe effects

源码地址

https://johncodeos.com/how-to-create-tabs-with-jetpack-compose/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/636714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索LowLatency的HLS低延迟直播协议

HLS全称为HTTP Live Streaming,其中m3u8作为描述协议,指向一系列切片文件。支持多码流与自适应码率,支持广告无缝播放,支持CMAF协议的低延时直播,也支持CDN动态选择。 我们先看下HLS整体架构,由三部分构成…

莫顿曲线映射 一维到二维的变换 MD(莫顿)码 反向变换 线性四叉树

函数声明&#xff1a; #include <stdio.h> #include <math.h>#define MAXSIZE 200 #define N 8typedef struct //栈的存储结构 {int data[MAXSIZE];int MD[MAXSIZE];int top; }stack1;void stackinitiate(stack1 *s); //初始化栈 void push (s…

【已解决】c++ 读入灰度图进行dft变换报错

报错原因&#xff1a; 1、imread函数读入默认参数为1&#xff0c;即彩色三通道图像&#xff0c;而我们要指定参数为0&#xff0c;读入灰度图像 2、在进行傅里叶变换前要将图像数据类型转为CV_32F&#xff0c;因为默认灰度图像类型为CV_8U 正确代码&#xff1a; #include <…

Vue中如何进行滚动加载与无限滚动?

Vue中如何进行滚动加载与无限滚动&#xff1f; 随着Web应用程序的复杂性和数据量的增加&#xff0c;滚动加载和无限滚动成为了Web开发中常见的需求。在Vue中&#xff0c;我们可以使用一些插件和技术来实现这些功能。 本文将介绍Vue中如何进行滚动加载和无限滚动&#xff0c;包…

内核实现信号捕捉的过程,以及要用到的函数sigaction

1.信号捕捉过程 1.在执行主控制流程的某条指令时因为中断、异常或系统调用进入内核。 2.内核处理完异常准备回用户模式之前先处理当前进程中可以递送的信号。 3.do_signal(); 如果信号的处理动作为自定义的信号处理函数&#xff0c;则回到用户模式执行信号处理函数&#xff08…

prometheus监控应用数据(一)

prometheus监控应用数据(一) 以下代码实现均使用go语言,至于其他语言请参照其他语言的prometheus api文档 获取go package: prometheus: go get -u github.com/prometheus/client_golang/prometheus搭建程序基本骨架 IP地址暂定为: localhost启用prometheus的监控端口是2112以…

互联网大厂Java面试题1500+附答案详解(2023版)

很多 Java 工程师的技术不错&#xff0c;但是一面试就头疼&#xff0c;10 次面试 9 次都是被刷&#xff0c;过的那次还是去了家不知名的小公司。 问题就在于&#xff1a;面试有技巧&#xff0c;而你不会把自己的能力表达给面试官。 应届生&#xff1a;你该如何准备简历&#…

2020310

Selenium: 基于WebDriver协议的 Web应用程序测试的工具 精简版&#xff1a; selenium脚本通过http请求发送命令和参数给httpserver httpserver通过json wire protocol格式转发命令和参数给webdriver webdriver通过原生API或者JavaScript代码执行操作给浏览器 浏览器通过json wi…

材料微观结构表征技术:电子背散射衍射EBSD

材料微观结构表征技术&#xff1a;电子背散射衍射EBSD 电子背散射衍射&#xff08;EBSD&#xff09;是一种材料表征技术&#xff0c;通过使用电子束对材料进行照射&#xff0c;并测量背向散射的电子的衍射模式&#xff0c;可以提供关于材料微观结构的详细信息。这项技术结合了…

DAY 75 【分布式应用】消息队列之卡夫卡 + EFLFK集群部署

pache公司的软件包官方下载地址&#xff1a;archive.apache.org/dist/ 注&#xff1a;kafka从3.0版本之后&#xff0c;不再依赖zookeeper Zookeeper 概述 官方下载地址&#xff1a;https://archive.apache.org/dist/zookeeper/ Zookeeper 定义 Zookeeper是一个开源的分布式…

【Linux脚本篇】循环语句-for

目录 &#x1f341;for的语法格式 &#x1f341;for循环案例 &#x1f343;案例一&#xff1a;循环创建文件 &#x1f343;案例二&#xff1a;应用引号或转义符 &#x1f343;案例三&#xff1a;从变量中取值 &#x1f343;案例四&#xff1a;从命令中取值 &#x1f343;案例五…

Vulkan入门精要

Vulkan入门精要 (fuxiii.github.io)https://fuxiii.github.io/Essentials.of.Vulkan/

开始在适用于 Linux 的 Windows 子系统上使用 Git

目录 Git 可以安装在 Windows 和 WSL 上安装 GitGit 配置文件设置Git 凭据管理器设置使用 SSH 的 GitAzure 的其他配置添加 Git Ignore 文件Git 和 VS CodeGit 行尾其他资源 Git 是最常用的版本控制系统。 使用 Git&#xff0c;可以跟踪对文件所做的更改&#xff0c;以便记录已…

java使用aspose.pdf或者spire.pdf 将pdf文件转word,实测

1. aspose.pdf aspose.pdf不是破解版的只能转3页&#xff0c;所以我弄了个破解版&#xff0c; aspose.pdf破解版在网上都有破解方法也比较简单&#xff0c;这里就不说了&#xff0c;直接引入破解版的jar包&#xff0c;在这里我用的是aspose-pdf-21.11.jar版本&#xff0c;代码…

【电路】电路与电子技术基础 课堂笔记 第9章 集成运算放大器基础

本章的研究对象是集成运算放大器的应用&#xff0c; 主要关注如何利用理想运放的特点&#xff0c;分析放大电路&#xff0c; 不讨论继承运放的工作原理和内部结构。 9.3 集成运放的主要参数与选择 9.4 集成运放的应用 集成运放应用于信号运算&#xff0c;信号处理&#xff…

调用阿里API实现手机号归属地查询

调用阿里API实现手机号归属地查询 1&#xff0e;作者介绍2&#xff0e;号码归属地介绍2.1 什么是手机号码归属地&#xff1f;2.2 为什么需要手机号码归属地&#xff1f;2.3 手机号码归属地查询对个人的运用 3&#xff0e;调用阿里API实现手机号归属地查询3.1阿里API调用3.2补充…

BYC30W-600P-ASEMI代理NXP快恢复二极管BYC30W-600P

编辑&#xff1a;ll BYC30W-600P-ASEMI代理NXP快恢复二极管BYC30W-600P 型号&#xff1a;BYC30W-600P 品牌&#xff1a;NXP/恩智浦 封装&#xff1a;TO-247-2L 最大漏源电流&#xff1a;30A 漏源击穿电压&#xff1a;600V 引脚数量&#xff1a;2 恢复时间&#xff1a;2…

JavaScript:获取当前日期、星期、时间 | Data对象

文章目录 1 Date对象2 代码示例3 获取 yyyy-MM-dd 格式的日期 1 Date对象 JavaScript 中的 Date 对象表示日期和时间。Date 对象基于自 1970 年 1 月 1 日 00:00:00 UTC&#xff08;协调世界时&#xff09;以来的毫秒数。以下是 Date 对象的一些常用方法和属性。 getFullYear…

H5页面这样测,业务方反馈 0 Bug!

部门最近的H5相关项目挺多的&#xff0c;由于团队之前接触的大多是Web项目&#xff0c;很少涉及H5&#xff0c;想着给团队成员培训下&#xff0c;减少漏测率&#xff0c;于是整理了一个文档。 别说&#xff0c;效果还挺不错的&#xff0c;连着上线6个版本&#xff0c;都没有收…

Python3数据分析与挖掘建模(10)多因子:复合分析-交叉分析与实现示例

1. 复合分析 1.1 概述 复合分析&#xff08;Factorial Analysis&#xff09;是一种统计分析方法&#xff0c;用于研究多个因素对观测结果的影响&#xff0c;并探究各个因素之间的相互作用效应。 在复合分析中&#xff0c;研究者会选择多个因素&#xff08;也称为处理变量或独…