Tiktok像JetPack组合一样导航和Android中的ModalBottomSheetOut
#kotlin #android #mobile #tristan

目录

  1. What we are talking about
  2. Getting started
  3. GitHub
  4. YouTube

我在Google Playstore上的应用程序

github代码

YouTube版本

简介

  • 本系列将是对我在开发Android应用程序时面临的任何问题或任何观察结果的非正式演示。本系列中的每个博客文章都将是独特的,并且与其他博客文章是独一无二的,因此请随时环顾四周。

我们在说什么

  • 如果您像我一样,并且您已经在Tiktok上度过了任何时间,您可能已经注意到,当您在个人资料页面上时,您可以单击Little Hamburger图标,并且从底部弹出一点模态
  • 在本教程中,我们将在设计的半娱乐活动中尽力而为。

  • tiktok的模态导航:

TikTok's modal navigation

  • 我们的娱乐活动:

The copy of TikTok's modal navigation

  • 显然,我们的活动不会是一对一的娱乐。但是,我们将重新创建小型模态的基本功能:

入门

  • 在JetPack组成中,本教程有两个主要组成部分:

1)脚手架
2)Modalbottomsheetlayout

脚手架

  • 如文档所述:

Compose provides convenient layouts for combining Material Components into common screen patterns. Composables such as Scaffold provide slots for various components and other screen elements.

- 但我们真正需要知道的是脚手架是给我们不错的小汉堡菜单的东西:

val bottomModalState = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden,
        skipHalfExpanded = true
    )

Scaffold(
        backgroundColor = MaterialTheme.colors.primary,
        topBar = {
            TopAppBar(
                title = { Text("Calf Tracker") },
                navigationIcon = {
                    IconButton(
                        onClick = {
                            scope.launch {
                                bottomModalState.show()

                            }
                        }
                    ) {
                        Icon(Icons.Filled.Menu, contentDescription = "Toggle navigation drawer")
                    }
                }
            )
        },
    ){
// This is where the ModalBottomSheetLayout is going

}

  • 我们将在下一部分中更多地谈论bottomModalState

  • 要获得我们漂亮的Topbar,我们将依靠K​​oude3库给我们的预先构建的TopAppBar。我们要做的就是提供标题(实际上这是可选的)和汉堡偶像:

title = { Text("Calf Tracker") },
                navigationIcon = {
                    IconButton(
                        onClick = {
                            scope.launch {
                                bottomModalState.show()

                            }
                        }
                    ) {
                       //Hamburger Icon
                        Icon(Icons.Filled.Menu, contentDescription = "Toggle navigation drawer") 
                    }
                }

  • 但是,如果预先构建的TopAppBar不符合您的要求,则可以创建自己的topappbar。这是我自己创建的自定义一个,带有搜索栏和可滚动芯片:
    Custom Top Bar implementation

  • 完整的github代码找到了HERE和以下实现:

@Composable
fun CustomTopBar(chipTextList:List<String>,searchMethod:(String)->Unit){
    Column() {
        Surface(
            modifier = Modifier.fillMaxWidth(),
            color = MaterialTheme.colors.primary,
            elevation = 8.dp
        ) {
            Column() {


                 SearchText(searchMethod= { tagNumber -> searchMethod(tagNumber) })
                    //CHIPS GO BELOW HERE
                    LazyRow(
                        modifier= Modifier
                            .fillMaxWidth()
                            .padding(horizontal = 18.dp, vertical = 8.dp),
                        horizontalArrangement = Arrangement.spacedBy(4.dp),
                    ) {
                        items(chipTextList){
                            Chip(it)
                        }
                    }
            }


        }

    }
}

modalbottomsheetlayout

  • 如文档所述:Modal bottom sheets present a set of choices while blocking interaction with the rest of the screen. They are an alternative to inline menus and simple dialogs, providing additional room for content, iconography, and actions.

  • 我们需要知道的是,这是给我们褪色的背景和弹出模式的原因。在脚手架的内容lambda中:

ModalBottomSheetLayout(
            sheetState = bottomModalState,
            sheetContent = {
                ModalContents(
                    onNavigate = onNavigate,
                    bottomModalState = bottomModalState
                )
            }

        ){
            YourComposableFunctionHere()//what the modal covers up
        }

  • bottomModalState是代表模态状态的原因,并确定是否应显示。模态的初始起始状态由以下方式表示:
val bottomModalState = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden,
        skipHalfExpanded = true
    )

  • 通过上面的代码块,我们告诉模态其初始状态为Hidden。如果您想知道skipHalfExpanded是什么,为什么不将其设置为false并找出答案;)

  • bottomModalState.show()弹出时,sheetContent是向用户显示的。

  • 这可以是您想要的任何东西,但我的实现看起来像这样:

data class ModalNavigation(
    val title:String,
    val contentDescription:String,
    val navigationDestination:Int,
    val icon:ImageVector,
    val key:Int,

)
val navItems = listOf(
    ModalNavigation(
        title ="Settings",
        contentDescription = "navigate to settings",
        navigationDestination = R.id.action_subscriptionFragment_to_settingsFragment,
        icon = Icons.Default.Settings,
        key =0
    ),
    ModalNavigation(
        title ="Calves",
        contentDescription = "navigate to calves screen",
        navigationDestination = R.id.action_subscriptionFragment_to_mainFragment22,
        icon = Icons.Default.Home,
        key =1
    )
)
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun ModalContents(
    onNavigate: (Int) -> Unit = {},
    bottomModalState:ModalBottomSheetState

){
    val scope = rememberCoroutineScope()

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .background(MaterialTheme.colors.primary),
        contentAlignment = Alignment.Center


    ){
        LazyVerticalGrid(
            columns = GridCells.Adaptive(minSize = 128.dp)
        ) {

            items(navItems) { navItem ->
                Card(
                    modifier = Modifier
                        .padding(8.dp).clickable {
                            scope.launch {
                                bottomModalState.hide()
                                onNavigate(navItem.navigationDestination)
                            }
                        },
                    backgroundColor = MaterialTheme.colors.secondary,
                    elevation = 8.dp,
                ) {
                    Column(
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally,
                        modifier = Modifier
                            .padding(vertical = 12.dp, horizontal = 4.dp),

                        ){
                        Icon(
                            imageVector = navItem.icon,
                            contentDescription = navItem.contentDescription,
                            modifier = Modifier.size(28.dp)
                        )
                        Text(navItem.title)
                    }
                }
            }
        }
    }
}

  • 如果您使用的是基于组合的导航,则可以将navigationDestination更改为目标字符串,而onNavigate功能将是您的基于组合的导航功能。

结论

  • 感谢您抽出宝贵的时间阅读我的博客文章。如果您有任何疑问或疑虑,请在下面发表评论或在Twitter上与我联系。