二、使用Jetpack Compsoe编写一个写小说的Android应用:新建小说界面篇

前排叠甲:我只是门外汉学着玩,大佬轻喷,有些地方设计的不是特别人性化请见谅。

主要功能:本次要设计的是第二个界面,就是在主页面的右上角点一下加号就能跳转到这一页。

1、首先是设计第二页,新建小说页面。

(本页面还会和第一页的修改小说名字按钮有关联,但是先不实现该功能,问就是还没做到那。)

我对项目结构进行了调整,后续可能还会调整,注意你的目录结构。

这次直接上全代码,有了上一篇的知识,这一篇的界面代码应该不用怎么细讲了,所以先上代码。

@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Previe
fun FictionNamePage() {
    Scaffold(
        topBar = {
            TopAppBar(
                modifier = Modifier.height(50.dp), // 设置高度为 50dp
                title = { Text("") },
                colors = TopAppBarDefaults.smallTopAppBarColors(
                    containerColor = colorResource(id = R.color.toolbar_color)
                ),
                actions = {
                    Row (modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically){
                        IconButton(onClick = {}
                            ,modifier = Modifier.size(50.dp),) {
                            Image(painter = painterResource(id = R.drawable.btn_back),
                                contentDescription = "add a book" )
                        }
                        Text(text = "新建小说",fontSize=22.sp)
                        IconButton(onClick = { },modifier = Modifier.size(50.dp)) {
                            Image(painter = painterResource(id = R.drawable.btn_finish),
                                contentDescription = "add a book" )
                        }
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier
                .padding(innerPadding),
        ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 20.dp, top = 80.dp)
                ,
                horizontalArrangement = Arrangement.Start,
                verticalAlignment = Alignment.CenterVertically
            )
            {
                Text(
                    text = "小说名称",
                    fontSize = 20.sp
                )
            }
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 24.dp, top = 10.dp)
                ,
                horizontalArrangement = Arrangement.Start,
                verticalAlignment = Alignment.CenterVertically
            )
            {

                OutlinedTextField(value = "",
                    onValueChange = {""},
                    label = { Text(text = "请输入小说名称")},
                    singleLine = true,
                    maxLines = 1,
                    modifier = Modifier.background(Color.White)
                )
            }
        }
    }
}

实现的效果大概是这样的:

当然你也可以运行以下看看效果,这个文本输入框是带特效的,当输入文本时它的提示词会自己上去,比如我将OutlinedTextField中的value =""改为value ="哈哈"

这一段代码中topbar的前半部分完全是复制粘贴主页面的,就把Text改改,把图标换掉就完事。

下半部分也很简单,就一个文本Text和一个输入框TextField。

其实输入框有很多类型,我一开始用的是最简单的TextField,发现他有一个难看的背景,而且我还不会去掉它的背景,好像是将color设置为transparent,但是感觉这个Outlined的也挺好用,所以就用这个了。有需求的话自己去我上次给的开发者网站找示例。

2、实现最简单的跳转功能

1)给页面添加跳转代码

现在我们有了两个页面MainPage和FictionNamePage,自然而然就会想到先实现跳转,但是跳转说实话好像稍微有点麻烦,所以这次就先实现一个最简单的不带参数的跳转。

为什么说最简单的呢,因为一般页面跳转会涉及到页面间数据的传递,单纯的页面跳转好像没啥用吧?

但是这里先实现跳转再往下实现传递数据,所以这里就要用到Compose中的导航了Navigation。

首先添加扩展:(要在app的那个gradle中添加)

implementation ("androidx.navigation:navigation-compose:2.6.0-alpha08")

添加完成后点击同步,前面的都是自己生成的,注意版本,如果你看到这篇文章的时间比较靠后,它的版本和功能可能都会出现变化,那个时候就祝你好运了!

好的,扩展下载完成后,Sync Now会变成Open,之后我们打开MainPage,添加导航控制器:

注意你在页面处传入参数后将不再能进行预览,此时Preview会报错,我不知道有没有其他方法,之后只能运行软件进行调试或者脑内实时渲染了。

首先MainPage改成了这样:

fun MainPage(navController: NavController) {}

其次在+号按钮的onClick中添加代码navController.navigate:

IconButton(
           onClick = {
                     navController.navigate("mod_fic_page"){launchSingleTop = true}
                      },
                            modifier = Modifier.size(50.dp)
                        ) {
                            Image(
                                painter = painterResource(id = R.drawable.btn_add),
                                contentDescription = "add a book"
                            )
                        }

但是这时又出现了另一个问题,当你写navController.navigate这个函数时,它需要一个route路线,我的代码中直接给了mod_fic_page,但是如果直接按这样是运行不了的,因为我们还没定义mod_fic_page,所以要先定义这个东西。

这里同时提一下launchSingleTop这个参数,这是单例启动,好像是跳转到这个页面时会清空栈内在它上面的其他界面,会对返回操作有影响,尤其是使用手机上的物理返回键,先就这样用,之后逻辑可能会更改。

2)创建导航

为了进行分类管理现在创建一个PageNavHost函数专门进行页面的跳转管理:

@Composable
fun PageNavHost() {
    // 创建NavController
    val navController: NavHostController = rememberNavController()
    // 用NavHost将NavController和导航图相关联,startDestination指定起始的可组合项
    NavHost(navController = navController, startDestination = "main_page") {
        // 给主页指定路径
        composable("main_page") { MainPage(navController) }
        // 给新建小说指定路径
        composable("mod_fic_page") { FictionNamePage() }

    }
}

目前我的文件分类为

为了和函数名对应,将mod_fic_page改为了fic_name_page,当然MainPage里面也要改,这里就不展示了

到这里就完成了简单的页面切换,现在来体验一下!

3)运行软件

这里还有一点小问题需要注意,运行时要先打开MainActivity文件,将无用的函数删掉,随后写上导航的函数

之后就能运行了!效果图如下,我不会搞动图就不搞了,你们自己试试。

完事,最简单的页面跳转完成!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是使用 JetPack Compose 编写悬浮窗的示例代码: ``` @Composable fun FloatingWindow() { val windowParams = remember { WindowManager.LayoutParams().apply { type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN format = PixelFormat.TRANSLUCENT gravity = Gravity.TOP or Gravity.START width = 200.dp.toPx() height = 200.dp.toPx() x = 0 y = 0 } } val windowManager = LocalWindowManager.current val density = LocalDensity.current var offsetX by remember { mutableStateOf(0f) } var offsetY by remember { mutableStateOf(0f) } var isDragging by remember { mutableStateOf(false) } Box( Modifier .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) } .background(Color.White, RoundedCornerShape(8.dp)) .pointerInput(Unit) { forEachGesture { awaitPointerEventScope { val down = awaitFirstDown() isDragging = true val position = down.position val density = LocalDensity.current val offsetXStart = with(density) { position.x.toDp() } val offsetYStart = with(density) { position.y.toDp() } val startX = offsetX val startY = offsetY val touchSlop = with(density) { 8.dp.toPx() } drag(down.id) { val dx = it.positionChange().x val dy = it.positionChange().y if (sqrt(dx * dx + dy * dy) > touchSlop) { offsetX = startX + dx offsetY = startY + dy } } isDragging = false } } } ) { Text( "Hello, World!", Modifier.padding(16.dp), color = Color.Black, fontSize = 16.sp ) } LaunchedEffect(windowManager) { windowManager.addView( AndroidView( factory = { context -> AndroidView(context).apply { layoutParams = windowParams } }, update = { view -> view.setContent { Box( Modifier .fillMaxSize() .background(Color.Transparent) ) { if (!isDragging) { windowParams.x = offsetX.roundToInt() windowParams.y = offsetY.roundToInt() windowManager.updateViewLayout(view, windowParams) } [email protected](this) } } } ) ) } } ``` 这个示例代码使用 `WindowManager` 创建了一个悬浮窗,并使用 `JetPack Compose` 实现了拖拽功能。你可以根据自己的需求修改代码,比如更改悬浮窗的大小、位置等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HO灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值