(编写用户界面)-键盘(IME)与应用程序的内容重叠 [英] (Compose UI) - Keyboard (IME) overlaps content of app

查看:23
本文介绍了(编写用户界面)-键盘(IME)与应用程序的内容重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前,我遇到一个问题,我的部分视图被键盘覆盖。

假设我们有3个不同的对话框(可以是任何内容),如下所示:

当我想写任何东西时,最后一个对话框被键盘覆盖:

而且无法看到用户写了什么。以下是我的代码:

@Composable
fun BuildWordsView(navController: NavController, sharedViewModel: SharedViewModel) {

        Column(
            modifier = Modifier
                .fillMaxWidth()
                .background(PrimaryLight)
                .fillMaxSize()

        ) {
            BuildWordsScreenContents()
        }

}

@Composable
fun BuildWordsScreenContents() {

    Column(
        Modifier
            .fillMaxSize()
            .padding(all = 16.dp)

    ) {

        val inputBoxModifier = Modifier
            .clip(RoundedCornerShape(10.dp))
            .background(Primary)
            .weight(12f)
            .wrapContentHeight()

        InputBlock("Dialog1", inputBoxModifier)
        Spacer(Modifier.weight(1f))
        InputBlock("Dialog2", inputBoxModifier)
        Spacer(Modifier.weight(1f))
        InputBlock("Dialog3", inputBoxModifier)
    }
}



@Composable
fun InputBlock(dialogText: String, inputBlockModifier: Modifier) {
    Column(modifier = inputBlockModifier) {
        Text(
            dialogText,
            fontSize = 30.sp,
            textAlign = TextAlign.Center,
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentSize(Alignment.Center)
        )
        var text by remember { mutableStateOf("") }

        TextField(
            value = text,
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentSize(Alignment.Center),
            onValueChange = { text = it },
            label = { Text("Label") }
        )
    }
}

此问题似乎与我的相似,但答案修改了我要避免的查看内容:

Software keyboard overlaps content of jetpack compose view

现在我想出了如何解决这个问题,我分享了我的方法作为答案

推荐答案

我处理此问题的方法是使用Jetpack Compose的插入

https://google.github.io/accompanist/insets/

为了开始处理问题,您需要将依赖项添加到Gradle(当前版本为0.22.0-rc)。

dependencies { 
    implementation "com.google.accompanist:accompanist-insets:0.22.0-rc"
}

然后您需要在活动中使用ProvideWindowInsets

包装您的内容
setContent {
    ProvideWindowInsets {
        YourTheme {
            //YOUR CONTENT HERE
        }
    }
}

此外,您还需要在Activity onCreate()函数中添加以下行:

WindowCompat.setDecorFitsSystemWindows(window, false)

更新:尽管推荐使用此功能,但根据我的经验,它可能会使此方法不起作用。如果您遇到任何问题,您可能需要删除此行。

现在您的项目已设置为使用插图

在接下来的步骤中,我将使用我提供的代码

首先,您需要用

对主列进行换行

ProvideWindowInsets(windowInsetsAnimationsEnabled = true)

然后让我们稍微修改一下修饰符,添加:

.statusBarsPadding()
.navigationBarsWithImePadding()
.verticalScroll(rememberScrollState())

如您所见,我的方法的诀窍是使用verticalScroll()。主列的最终代码应如下所示:

@Composable
fun BuildWordsView(navController: NavController, sharedViewModel: SharedViewModel) {

    ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {

        Column(
            modifier = Modifier
                .fillMaxWidth()
                .background(PrimaryLight)
                .statusBarsPadding()
                .navigationBarsWithImePadding()
                .verticalScroll(rememberScrollState())
                .fillMaxSize()

        ) {
            BuildWordsScreenContents()
        }
    }
}

现在让我们修改fun BuildWordsScreenContents()中的列的修饰符

主要修改是通过以下方式提供屏幕高度:

.height(LocalConfiguration.current.screenHeightDp.dp)

这意味着我们列的高度正好适合我们的屏幕。因此,当键盘未打开时,该列将无法滚动

这里有完整的代码:

@Composable
fun BuildWordsView(navController: NavController, sharedViewModel: SharedViewModel) {

    ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {

        Column(
            modifier = Modifier
                .fillMaxWidth()
                .background(PrimaryLight)
                .statusBarsPadding()
                .navigationBarsWithImePadding()
                .verticalScroll(rememberScrollState())
                .fillMaxSize()

        ) {
            BuildWordsScreenContents()
        }
    }
}

@Composable
fun BuildWordsScreenContents() {

    Column(
        Modifier
            .height(LocalConfiguration.current.screenHeightDp.dp)
            .padding(all = 16.dp)

    ) {

        val inputBoxModifier = Modifier
            .clip(RoundedCornerShape(10.dp))
            .background(Primary)
            .weight(12f)
            .wrapContentHeight()

        InputBlock("Dialog1", inputBoxModifier)
        Spacer(Modifier.weight(1f))
        InputBlock("Dialog2", inputBoxModifier)
        Spacer(Modifier.weight(1f))
        InputBlock("Dialog3", inputBoxModifier)
    }
}





@Composable
fun InputBlock(dialogText: String, inputBlockModifier: Modifier) {
    Column(modifier = inputBlockModifier) {
        Text(
            dialogText,
            fontSize = 30.sp,
            textAlign = TextAlign.Center,
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentSize(Alignment.Center)
        )
        var text by remember { mutableStateOf("") }

        TextField(
            value = text,
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentSize(Alignment.Center),
            onValueChange = { text = it },
            label = { Text("Label") }
        )
    }
}

最后的代码允许我们向下滚动视图:

API 30-

重要说明

对于低于30的API,您需要修改androidManifest.xml文件

在<;活动中,您需要添加android:windowSoftInputMode="adjustResize"以使其工作。它不会调整组件大小,但必须使用此方法

清单应如下所示:

<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="adjustResize"

请随时给我任何提示,我如何才能改进我的问题。AFAIK这个问题和Android一样古老,我想创建一个快速教程来解决这个问题。编码快乐!

这篇关于(编写用户界面)-键盘(IME)与应用程序的内容重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆