You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Compose同结构函数在模拟器中渲染不一致问题

两个结构相似的Composable函数渲染效果不一致问题

环境配置

sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
kotlinOptions.jvmTarget = "1.8"
kotlinCompilerExtensionVersion '1.4.6'
implementation platform('androidx.compose:compose-bom:2023.03.00')
androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00')

第一个屏幕代码与效果

代码

@Composable
fun BuildScreenHouse(viewModel: InventoryViewModel, navController: NavHostController, houseId: String?, name: String?, use: String?, location: String?)  {

val house = houseId!!.toLong()

ScreenLandscape()

Column {


    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .padding(top = 22.dp, start = 6.dp, end = 6.dp)
            .fillMaxWidth()
        //.verticalScroll(state = scrollState)

    ) {

        Row(verticalAlignment = Alignment.CenterVertically) {


            Text(
                text = "Nick Name", fontSize = 20.sp,
                modifier = Modifier.fillMaxWidth(0.50f),
                color = Color.Black,
                fontWeight = FontWeight.Bold

            )

            Text(
                text = "Use", fontSize = 20.sp,
                modifier = Modifier.fillMaxWidth(0.50f),
                color = Color.Black,
                fontWeight = FontWeight.Bold

            )
        }

        Row(verticalAlignment = Alignment.CenterVertically) {

            Text(
                text = name!!, fontSize = 20.sp,
                modifier = Modifier.fillMaxWidth(0.50f),
                color = Color.Black

            )

            Text(
                text = use!!, fontSize = 20.sp,
                modifier = Modifier.fillMaxWidth(0.50f),
                color = Color.Black

            )
        }


        Button(
            onClick = { navController.navigate("InsertScreenFloor/${houseId}/${URLEncoder.encode(location, "utf-8")}") },
            //Modifier.align(Alignment.CenterHorizontally),
            colors = ButtonDefaults.buttonColors(Color.Blue)

        ) {
            Text(text = "Insert Floor into House")
        }
    }

    Column(
        //horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .padding(top = 22.dp, start = 6.dp, end = 6.dp)
            .fillMaxWidth()
        //.verticalScroll(state = scrollState)

    ) {
        // The House List
        FloorsList(viewModel = viewModel, navController, house, location!!)

    }
}

渲染效果

第一个屏幕渲染效果

第二个屏幕代码与效果

代码

@Composable
fun BuildScreenFloor(viewModel: InventoryViewModel, navController: NavHostController, floorId: String?, floorname: String?, location: String?) {

val floor = floorId!!.toLong()

ScreenLandscape()

Column {

    Column(horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .padding(top = 22.dp, start = 6.dp, end = 6.dp)
            .fillMaxWidth()
        //.verticalScroll(state = scrollState)


    ) {


        Row(verticalAlignment = Alignment.CenterVertically) {

            Text(
                text = "Floor Name", fontSize = 20.sp,
                modifier = Modifier.fillMaxWidth(),
                color = Color.Black,
                fontWeight = FontWeight.Bold

            )

        }

        Row(verticalAlignment = Alignment.CenterVertically) {

            Text(
                text = floorname!!, fontSize = 20.sp,
                modifier = Modifier.fillMaxWidth(),
                color = Color.Black

            )
        }
    }

    Button(
        onClick = { navController.navigate("InsertScreenRoom/${floorId}/${URLEncoder.encode(location, "utf-8")}") },
        colors = ButtonDefaults.buttonColors(Color.Blue)

    ) {
        Text(text = "Insert Room into Floor")
    }

    Column(
        //horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .padding(top = 22.dp, start = 6.dp, end = 6.dp)
            .fillMaxWidth()
        //.verticalScroll(state = scrollState)

    ) {

        // The House List
        RoomsList(viewModel = viewModel, navController, floor, location!!)

    }
}

渲染效果

第二个屏幕渲染效果

问题

第二个屏幕的首段内容("Floor Name"和对应的floorname)向左对齐,而非像第一个屏幕那样居中显示,原因是什么?

原因分析

两个Composable的核心差异在于Text组件的modifier设置:

  • 第一个屏幕的Text使用Modifier.fillMaxWidth(0.50f),只占据Row宽度的一半,此时父Row的宽度未被填满,父Column的horizontalAlignment = Alignment.CenterHorizontally会让Row整体居中,视觉上呈现文本居中的效果。
  • 第二个屏幕的Text使用Modifier.fillMaxWidth(),会完全填满所在Row的宽度。此时Text自身宽度等于Row宽度,父Column的居中对齐对Text不再生效,而Text默认的textAlign是TextAlign.Start(左对齐),所以内容会向左对齐。

解决方案

有两种方式可以让第二个屏幕的Text内容居中:

方案1:给Text添加textAlign = TextAlign.Center

保持fillMaxWidth()的同时,显式设置文本对齐方式:

Text(
    text = "Floor Name", fontSize = 20.sp,
    modifier = Modifier.fillMaxWidth(),
    color = Color.Black,
    fontWeight = FontWeight.Bold,
    textAlign = TextAlign.Center // 添加文本居中配置
)

方案2:移除Text的fillMaxWidth()

让Text自适应内容宽度,父Row会跟随Text宽度,父Column的horizontalAlignment = Alignment.CenterHorizontally会让Row整体居中:

Text(
    text = "Floor Name", fontSize = 20.sp,
    color = Color.Black,
    fontWeight = FontWeight.Bold
)

内容的提问来源于stack exchange,提问作者jetberrocal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:34:57