簡體   English   中英

Jetpack Compose 全屏對話框

[英]Jetpack Compose Fullscreen Dialog

我嘗試使用以下代碼使用 Jetpack Compose 制作全屏對話框:

Dialog(onDismissRequest = { /*TODO*/ }) {
           NewPostDialog()
       }

它最終看起來像這樣。 如何刪除側面的邊距(標記為紅色)?

例子

更新:正如@Nestor Perez 提到的,由於 compose 1.0.0-rc01 您可以在DialogProperties中設置usePlatformDefaultWidth以使對話框填充整個屏幕寬度:

Dialog(
    properties = DialogProperties(usePlatformDefaultWidth = false),
    onDismissRequest...
    ){
      Surface(modifier = Modifier.fillMaxSize()) {
          DialogContent()
      }
    }

Compose Dialog使用ContextThemeWrapper ,因此您應該能夠使用自定義樣式為您的對話框設置主題。

themes.xml

 <style name="Theme.YourApp" parent="Theme.MaterialComponents.Light.NoActionBar">
       //theme content...
        <item name="android:dialogTheme">@style/Theme.DialogFullScreen</item>
    </style>

 <style name="Theme.DialogFullScreen" parent="@style/ThemeOverlay.MaterialComponents.Dialog.Alert">
        <item name="android:windowMinWidthMajor">100%</item>
        <item name="android:windowMinWidthMinor">100%</item>
    </style>

在代碼中:

@Composable
fun FullScreenDialog(showDialog:Boolean, onClose:()->Unit) {
    if (showDialog) {
        Dialog(onDismissRequest =  onClose ) {
            Surface(
                modifier = Modifier.fillMaxSize(),
                shape = RoundedCornerShape(16.dp),
                color = Color.LightGray
            ) {
                Box(
                    contentAlignment = Alignment.Center
                ) {
                    Text(modifier = Modifier.align(Alignment.TopCenter),
                        text = "top")
                    Text("center")
                    Text(
                        modifier = Modifier.align(Alignment.BottomCenter),
                        text = "bottom")
                }
            }
        }
    }
}

jns 的解決方案對我來說效果不佳,如果有人仍在尋找,我會在此處留下另一個解決方案:

將主題實現為 jns 答案:

<style name="Theme.Outlay" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    ...
    <!-- Customize your theme here. -->
    <item name="android:dialogTheme">@style/Theme.DialogFullScreen</item    >
</style>

<style name="Theme.DialogFullScreen" parent="@style/ThemeOverlay.MaterialComponents.Dialog.Alert">
    <item name="android:windowMinWidthMajor">100%</item>
    <item name="android:windowMinWidthMinor">100%</item>
</style>

為對話框創建一個腳手架並在對話框屬性上添加實驗屬性“usePlatformDefaultWidth = false”:

Dialog(
    onDismissRequest = onBackPressed,
    properties = DialogProperties(
        usePlatformDefaultWidth = false
    )
) {
    Scaffold(topBar = { TopBar(onBackPressed = onBackPressed) }) {
        Content()
    }
}

如果您想完全避免使用 xml 主題並避免對所有對話框執行此操作,您可以將requiredWidth修飾符設置為等於LocalConfiguration.current.screenWidthDp.dp (您可以乘以某個分數)。

占據屏幕寬度0.96f的示例:

@Composable
fun LargerDialog(
    dialogOpen: MutableState<Boolean>
) {
    Dialog(onDismissRequest = { dialogOpen.value = false }) {
        Card( // or Surface
            elevation = 8.dp,
            modifier = Modifier
                .requiredWidth(LocalConfiguration.current.screenWidthDp.dp * 0.96f)
                .padding(4.dp)
        ) {
            // content
        }
    }
}

使用以下代碼使用 Jetpack Compose 制作全屏對話框: EG1:全屏對話框截圖

package compose.material.theme

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import compose.material.theme.ui.theme.Material3ComposeTheme



class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Material3ComposeTheme {
                val openFullDialogCustom = remember { mutableStateOf(false) }

                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {

                    Column(
                        modifier = Modifier
                            .padding(20.dp)
                            .verticalScroll(rememberScrollState())
                    ) {

                        //...................................................................
                        // * full screen custom dialog
                        Button(
                            onClick = {
                                openFullDialogCustom.value = true
                            },
                            modifier = Modifier.align(Alignment.CenterHorizontally)
                        ) {
                            Text(text = "No internet",style = MaterialTheme.typography.labelLarge)
                        }
                    }
                }

                //...............................................................................
                //Full screen Custom Dialog Sample
                NoInternetScreen(openFullDialogCustom)

            }
        }
    }


    @OptIn(ExperimentalComposeUiApi::class)
    @Composable
    private fun NoInternetScreen(openFullDialogCustom: MutableState<Boolean>) {
        if (openFullDialogCustom.value) {

            Dialog(
                onDismissRequest = {
                    openFullDialogCustom.value = false
                },
                properties = DialogProperties(
                    usePlatformDefaultWidth = false // experimental
                )
            ) {
                Surface(modifier = Modifier.fillMaxSize()) {

                    Column(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {



                        Image(
                            painter = painterResource(id = R.drawable.no_intrenet),
                            contentDescription = null,
                            contentScale = ContentScale.Fit,
                            modifier = Modifier
                                .height(200.dp)
                                .fillMaxWidth(),

                            )

                        Spacer(modifier = Modifier.height(20.dp))
                        //.........................Text: title
                        Text(
                            text = "Whoops!!",
                            textAlign = TextAlign.Center,
                            modifier = Modifier
                                .padding(top = 20.dp)
                                .fillMaxWidth(),
                            letterSpacing = 2.sp,
                            fontWeight = FontWeight.Bold,
                            style = MaterialTheme.typography.titleLarge,
                            color = MaterialTheme.colorScheme.primary,
                        )
                        Spacer(modifier = Modifier.height(8.dp))

                        //.........................Text : description
                        Text(
                            text = "No Internet connection was found. Check your connection or try again.",
                            textAlign = TextAlign.Center,
                            modifier = Modifier
                                .padding(top = 10.dp, start = 25.dp, end = 25.dp)
                                .fillMaxWidth(),
                            letterSpacing = 1.sp,
                            style = MaterialTheme.typography.bodyLarge,
                            color = MaterialTheme.colorScheme.primary,
                        )
                        //.........................Spacer
                        Spacer(modifier = Modifier.height(24.dp))

                        val cornerRadius = 16.dp
                        val gradientColor = listOf(Color(0xFFff669f), Color(0xFFff8961))
                        GradientButton(
                            gradientColors = gradientColor,
                            cornerRadius = cornerRadius,
                            nameButton = "Try again",
                            roundedCornerShape = RoundedCornerShape(topStart = 30.dp,bottomEnd = 30.dp)
                        )

                    }

                }
            }

        }
    }


}

//...........................................................................
@Composable
fun GradientButton(
    gradientColors: List<Color>,
    cornerRadius: Dp,
    nameButton: String,
    roundedCornerShape: RoundedCornerShape
) {

    Button(
        modifier = Modifier
            .fillMaxWidth()
            .padding(start = 32.dp, end = 32.dp),
        onClick = {
            //your code
        },

        contentPadding = PaddingValues(),
        colors = ButtonDefaults.buttonColors(
            containerColor = Color.Transparent
        ),
        shape = RoundedCornerShape(cornerRadius)
    ) {

        Box(
            modifier = Modifier
                .fillMaxWidth()
                .background(
                    brush = Brush.horizontalGradient(colors = gradientColors),
                    shape = roundedCornerShape
                )
                .clip(roundedCornerShape)
                /*.background(
                    brush = Brush.linearGradient(colors = gradientColors),
                    shape = RoundedCornerShape(cornerRadius)
                )*/
                .padding(horizontal = 16.dp, vertical = 8.dp),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = nameButton,
                fontSize = 20.sp,
                color = Color.White
            )
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM