modifier

Swift修饰符详解
本文深入探讨Swift中的三种关键修饰符:@discardableResult用于忽略方法返回值,@inline(__always)提升函数执行效率,以及@available用于处理API的可用性和废弃情况。通过具体示例,帮助读者理解这些修饰符的使用场景和作用。

Swift 中的修饰符

@discardableResult

  • 描述 当一个方法有返回值时,如果我们没有接收方法的返回值,这是 XCode 我警告我们,如果想消除这个警告,可以在方法前加上 @discardableResult。
  • 示例
@discardableResult
func increment(number: inout Int) -> Int {
    let old = number
    number += 1
    return old
}

var x = 10
increment(number: &x)

@inline(__always)

  • 描述 内联函数,提高代码的执行效率
  • 示例
@discardableResult
@inline(__always)
func increment(number: inout Int) -> Int {
    let old = number
    number += 1
    return old
}

var x = 10
increment(number: &x)

@available

@available(*, deprecated, message: "Use `Element` instead.")
typealias E = Element
首先画面描画上,JAFRSHO07020Popup和JAFRSHO07030Popup布局等很像 将下面的JAFRSHO07030Popup完全按照JAFRSHO07020Popup的布局写法,逻辑实现等不变 JAFRSHO07020Popup有受付完了日時,出勤場所,氏名,車名,依頼内容 在JAFRSHO07030Popup中保留有受付完了日時,改写出勤場所为取消理由并去掉参照ボタン,改写氏名为メモ保留参照ボタン 其他的可以去掉 改写: package jp.or.jaf.syg.feature.jafrsho07.jafrsho07030 import android.os.Build import androidx.annotation.RequiresApi 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.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource 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 androidx.hilt.navigation.compose.hiltViewModel import jp.or.jaf.syg.core.designsystem.theme.* import jp.or.jaf.syg.core.ui.components.JafText import jp.or.jaf.syg.core.ui.components.JafThemelessBottomButton import jp.or.jaf.syg.feature.R import jp.or.jaf.syg.feature.jafrsho99.components.JafUiStateHost import org.json.JSONObject /** * JAFRSHO07030 指令確認画面_指令取消受信ポップアップ * * 設計書: JAFRSHO07030_画面設計書.xlsx * */ @RequiresApi(Build.VERSION_CODES.O) @Composable fun JAFRSHO07030Popup( params: JSONObject, modifier: Modifier = Modifier, viewModel: JAFRSHO07030ViewModel = hiltViewModel() ) { // パラメータから初期値を抽出 val ifShikibetsuCd by remember { mutableStateOf(params.optString("ifShikibetsuCd", "")) } val userCd by remember { mutableStateOf(params.optString("userCd", "")) } val shireiMngCd by remember { mutableStateOf(params.optString("shireiMngCd", "")) } val hanyoReasonCd by remember { mutableStateOf(params.optString("hanyoReasonCd", "")) } // 初期化処理 LaunchedEffect(Unit) { viewModel.handleAction( JAFRSHO07030Action.Initialize( ifShikibetsuCd = ifShikibetsuCd, userCd = userCd, shireiMngCd = shireiMngCd, hanyoReasonCd = hanyoReasonCd ) ) } // UiState の監視 val uiState by viewModel.uiState.collectAsState() if (uiState.isVisible) { Dialog( onDismissRequest = { viewModel.handleAction(JAFRSHO07030Action.OnClosePopup) }, properties = DialogProperties( dismissOnBackPress = false, dismissOnClickOutside = false ) ) { JAFRSHO07030PopupContent( uiState = uiState, onOkClick = { viewModel.handleAction(JAFRSHO07030Action.OnBtnRefer(shireiMngCd)) }, onCancelClick = { viewModel.handleAction(JAFRSHO07030Action.OnBtnRoger(shireiMngCd)) } ) } } } @Composable private fun JAFRSHO07030PopupContent( uiState: JAFRSHO07030UiStateData, onOkClick: () -> Unit, onCancelClick: () -> Unit ) { // ラベル幅統一 val labelWidth: Dp = 200.dp Column( modifier = Modifier .fillMaxWidth(0.95f) .clip(MaterialTheme.shapes.searchFormOpenButtonShape) .background( brush = MaterialTheme.gradientColorScheme.knowMiddleLayer, shape = MaterialTheme.shapes.searchFormOpenButtonShape ) ) { // トップバー Box( modifier = Modifier .fillMaxWidth() .height(50.dp) .background(color = MaterialTheme.colorScheme.knowTopBar) ) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { JafText( text = "指令取消受信", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } Box( modifier = Modifier.fillMaxSize().padding(end = 16.dp), contentAlignment = Alignment.CenterEnd ) { JafText( text = uiState.receptionTime ?: "", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } } Spacer(modifier = Modifier.height(16.dp)) Column( modifier = Modifier .fillMaxWidth() .padding(horizontal = 20.dp) .verticalScroll(rememberScrollState()) ) { // 指令No表示 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "指令No", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f).clip(MaterialTheme.shapes.medium)) { JafText( text = uiState.shireiNo ?: "", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } Spacer(modifier = Modifier.height(20.dp)) // コンテンツボックス領域 Column( modifier = Modifier .fillMaxWidth() .background( shape = MaterialTheme.shapes.searchFormOpenButtonShape, color = MaterialTheme.colorScheme.KnowContentLayer ) ) { Spacer(modifier = Modifier.height(20.dp)) // 取消理由 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "取消理由", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f)) { JafText( text = uiState.torookeshiRiyuName ?: "", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } // 追加メッセージ(存在時のみ) if (!uiState.tuikaMassage.isNullOrBlank()) { Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "追加情報", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f)) { JafText( text = uiState.tuikaMassage, textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } } Spacer(modifier = Modifier.height(20.dp)) } // エラーメッセージ uiState.errorMessage?.let { message -> Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 8.dp), horizontalArrangement = Arrangement.Center ) { Text( text = message, color = MaterialTheme.colorScheme.error, fontSize = 16.sp, textAlign = TextAlign.Center ) } } // ローディング中 if (uiState.isLoading) { Row( modifier = Modifier .fillMaxWidth() .height(60.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { CircularProgressIndicator(strokeWidth = 2.dp, modifier = Modifier.size(30.dp)) } } // 確認メッセージ Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 16.dp), horizontalArrangement = Arrangement.Center ) { JafText( text = "この指令を取消しますか?", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, fontWeight = FontWeight.Medium, textAlign = TextAlign.Center, style = JafTypography.message ) } // ボタンエリア Row( modifier = Modifier .fillMaxWidth() .padding(bottom = 15.dp), horizontalArrangement = Arrangement.Center ) { // キャンセルボタン JafThemelessBottomButton( onClick = onCancelClick, modifier = Modifier.size(220.dp, 75.dp), enabled = uiState.isCancelButtonEnabled && !uiState.isLoading, text = stringResource(R.string.cancel), style = JafTypography.bottomLayerText ) Spacer(modifier = Modifier.width(20.dp)) // OKボタン JafThemelessBottomButton( onClick = onOkClick, modifier = Modifier.size(220.dp, 75.dp), enabled = uiState.isOkButtonEnabled && !uiState.isLoading, text = "OK", style = JafTypography.bottomLayerText ) } } } } 参照: /*********************************************************** * Copyright NEC Corporation 2025. All rights reserved * No permission to use, copy, modify and distribute this * software and its documentation for any purpose is granted. * This software is provided under applicable license * agreement only. * * システム名 : JAF RSシステム * サブシステム名 : 車業アプリ * クラス名 : JAFRSHO07020Popup * * @author NEC * ***********************************************************/ package jp.or.jaf.syg.feature.jafrsho07.jafrsho07020 import android.os.Build import androidx.annotation.RequiresApi import androidx.compose.foundation.ScrollState import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource 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.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewmodel.compose.viewModel import jp.or.jaf.syg.core.designsystem.theme.JafTextFieldLabelWidthPopup import jp.or.jaf.syg.core.designsystem.theme.JafTypography import jp.or.jaf.syg.core.designsystem.theme.KnowContentLayer import jp.or.jaf.syg.core.designsystem.theme.bottomLayerText import jp.or.jaf.syg.core.designsystem.theme.gradientColorScheme import jp.or.jaf.syg.core.designsystem.theme.knowContentLayerText import jp.or.jaf.syg.core.designsystem.theme.knowTopBar import jp.or.jaf.syg.core.designsystem.theme.knowTopBarText import jp.or.jaf.syg.core.designsystem.theme.middleLayerText import jp.or.jaf.syg.core.designsystem.theme.message import jp.or.jaf.syg.core.designsystem.theme.popupTitleLabel import jp.or.jaf.syg.core.designsystem.theme.searchFormOpenButtonShape import jp.or.jaf.syg.core.designsystem.theme.textFieldLabel import jp.or.jaf.syg.core.designsystem.theme.topbarText import jp.or.jaf.syg.core.ui.components.JafRefrenceButton import jp.or.jaf.syg.core.ui.components.JafText import jp.or.jaf.syg.core.ui.components.JafThemelessBottomButton import jp.or.jaf.syg.feature.R import jp.or.jaf.syg.feature.jafrsho99.components.JafUiStateHost import jp.or.jaf.syg.core.designsystem.theme.jafFFA722 import jp.or.jaf.syg.core.designsystem.theme.jaf4DD1BE import jp.or.jaf.syg.core.designsystem.theme.JafKnowContentLayerTextDark import jp.or.jaf.syg.core.designsystem.theme.requiredMark import org.json.JSONObject /** * JAFRSHO07020Popup * * 指令確認画面_指令変更受信ポップアップ画面 * モーダルダイアログとして表示されるポップアップ */ @RequiresApi(Build.VERSION_CODES.O) @Composable fun JAFRSHO07020Popup( params: JSONObject, modifier: Modifier = Modifier, viewModel: JAFRSHO07020ViewModel = hiltViewModel() ) { // 画面の状態データ JafUiStateHost( modifier = modifier.fillMaxSize(), viewModel = viewModel, params = params ) { stateData -> JAFRSHO07020ContentView(modifier, viewModel, stateData) } } @Composable fun JAFRSHO07020ContentView( modifier: Modifier, viewModel: JAFRSHO07020ViewModel, stateData: JAFRSHO07020UiStateData ){ // ラベルの幅を統一 val labelWidth: Dp = 200.dp // コンテンツ Column( modifier = Modifier .fillMaxSize() .background( brush= MaterialTheme.gradientColorScheme.knowMiddleLayer, shape = MaterialTheme.shapes.searchFormOpenButtonShape ) ) { // トップバー Box( modifier = Modifier .fillMaxWidth() .height(50.dp) .background(color = MaterialTheme.colorScheme.knowTopBar) ) { // タイトル中央揃え Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { // タイトル JafText( text = "指令変更受信", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } // 右側時間+受信 Box( modifier = Modifier .fillMaxSize() .padding(end = 16.dp), contentAlignment = Alignment.CenterEnd ) { // 指示受信時刻 JafText( text = stateData.lblReceptionTime, textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } } // スペース Spacer(modifier = Modifier.height(16.dp)) // コンテンツ領域 Column( modifier = Modifier .fillMaxWidth() .padding(horizontal = 20.dp) ) { // 指令Noを示す Column( modifier = Modifier.fillMaxWidth() ) { Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically ) { // ラベルセクション Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) ) { JafText( text = "指令No", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } // コンテンツセクション Column( modifier = Modifier .weight(1f) .fillMaxWidth() .clip(MaterialTheme.shapes.medium) ) { JafText( text = stateData.lblInstructionNo, textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } } // スペース Spacer(modifier = Modifier.height(20.dp)) // コンテンツボックス領域 Column( modifier = Modifier .fillMaxWidth() .weight(1f) .background( shape = MaterialTheme.shapes.searchFormOpenButtonShape, color = MaterialTheme.colorScheme.KnowContentLayer ) ) { // スペース Spacer(modifier = Modifier.height(20.dp)) // コンテンツ行の指令(TODO) //受付完了日時 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically ) { // ラベルセクション Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) ) { JafText( text = stringResource(id = R.string.column_completion_time), textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } // コンテンツセクション Column( modifier = Modifier .weight(1f) .fillMaxWidth() .clip(MaterialTheme.shapes.medium) ) { JafText( text = stateData.lblUketsukeCompDatetime, textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } //出動場所 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp) .background(if(stateData.locationChangeFlg) jafFFA722 else MaterialTheme.colorScheme.KnowContentLayer), verticalAlignment = Alignment.CenterVertically ){ // ラベルセクション Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) ) { JafText( text = stringResource(id = R.string.dispatch_place), textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } // コンテンツセクション Column( modifier = Modifier .weight(1f) .fillMaxWidth() .clip(MaterialTheme.shapes.medium) ) { Row{ JafText( text = (stateData.lblLocation).take(if(stateData.lblLocation.length > 54) 53 else stateData.lblLocation.length), textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, textAlign = TextAlign.Left, style = JafTypography.middleLayerText ) // 参照ボタン if (stateData.lblLocation.length > 54) { JafRefrenceButton( modifier = Modifier.size(28.dp), enabled = true, onClick = { viewModel.onAction(JAFRSHO07020Action.ReferenceButton("出動場所")) } ) } } } } //氏名 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp) .background(if(stateData.kaiinNameChangeFlg) jafFFA722 else MaterialTheme.colorScheme.KnowContentLayer), verticalAlignment = Alignment.CenterVertically ) { // ラベルセクション Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) ) { JafText( text = stringResource(id = R.string.customer_name), textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } // コンテンツセクション Column( modifier = Modifier .weight(1f) .fillMaxWidth() .clip(MaterialTheme.shapes.medium) ){ Row{ JafText( text = (stateData.lblKaiinName).take(if (stateData.lblKaiinName.length > 40) 39 else stateData.lblKaiinName.length), textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, textAlign = TextAlign.Left, style = JafTypography.middleLayerText ) // 参照ボタン if (stateData.lblKaiinName.length > 40) { JafRefrenceButton( modifier = Modifier.size(28.dp), enabled = true, onClick = { viewModel.onAction(JAFRSHO07020Action.ReferenceButton("氏名")) } ) } } } } //車名 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp) .background(if(stateData.carTsushoNameChangeFlg) jafFFA722 else MaterialTheme.colorScheme.KnowContentLayer), verticalAlignment = Alignment.CenterVertically, ) { // ラベルセクション Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) ) { JafText( text = stringResource(id = R.string.car_name), textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } // コンテンツセクション Column( modifier = Modifier .weight(1f) .fillMaxWidth() .clip(MaterialTheme.shapes.medium) ){ Row{ JafText( text = (stateData.lblCarTsushoName).take(if (stateData.lblCarTsushoName.length > 30) 29 else stateData.lblCarTsushoName.length), textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, textAlign = TextAlign.Left, style = JafTypography.middleLayerText ) // 参照ボタン if (stateData.lblCarTsushoName.length > 30) { JafRefrenceButton( modifier = Modifier.size(28.dp), enabled = true, onClick = { viewModel.onAction(JAFRSHO07020Action.ReferenceButton("車名")) } ) } } } } //依頼内容 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp) .background(if(stateData.iraiContChangeFlg) jafFFA722 else MaterialTheme.colorScheme.KnowContentLayer), verticalAlignment = Alignment.CenterVertically, ) { // ラベルセクション Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) ) { JafText( text = stringResource(id = R.string.request_content), textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } // コンテンツセクション Column( modifier = Modifier .weight(1f) .fillMaxWidth() .clip(MaterialTheme.shapes.medium) ){ Row{ JafText( text = stateData.lblIraiCont, textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, textAlign = TextAlign.Left, style = JafTypography.middleLayerText ) //緊急 if(stateData.lblKinkyu.isNotEmpty()){ Row( modifier = modifier.background(MaterialTheme.colorScheme.requiredMark) ){ JafText( text = stateData.lblKinkyu, textcolor = JafKnowContentLayerTextDark, fontSize = 22.sp, style = JafTypography.middleLayerText, ) } } } } } } //指令変更ありと対話履歴変更あり(TODO) if(stateData.lblShireiChange.isNotEmpty() || stateData.lblTaiwaHistoryChange.isNotEmpty()){ // スペース Spacer(modifier = Modifier.height(20.dp)) Row( modifier = Modifier.fillMaxWidth() .fillMaxWidth() .height(60.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center ){ if(stateData.lblShireiChange.isNotEmpty()){ Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) .background(jafFFA722) ){ // タイトル JafText( text = "指令変更あり", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } } if(stateData.lblTaiwaHistoryChange.isNotEmpty()){ Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(end = 40.dp) .background(jaf4DD1BE) ){ // タイトル JafText( text = "対話履歴変更あり", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } } } } // スペース Spacer(modifier = Modifier.height(20.dp)) //通知メッセージ Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ){ JafText( text = stateData.lblMessage, textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.message ) } // スペース Spacer(modifier = Modifier.height(20.dp)) // ボタンについて Box( modifier = Modifier .fillMaxWidth() .padding(bottom = 15.dp), contentAlignment = Alignment.Center, ) { // 了解ボタン JafThemelessBottomButton( onClick = { (viewModel::onAction)(JAFRSHO07020Action.Ryoukai( stateData.shireiMngCd, stateData.ifCd, "" )) }, modifier = Modifier.size(220.dp, 75.dp), text = stringResource(R.string.i_recv_i_ack_ryokai), style = JafTypography.bottomLayerText ) } } } }
09-20
根据你的要求,我们需要将 `JAFRSHO07030Popup` 的布局结构**完全参照 `JAFRSHO07020Popup` 的样式进行重构**,同时保留原有逻辑(如 ViewModel、Action 处理等),但做如下调整: --- ### ✅ 改写目标 | 原字段 | 新字段 | 是否保留按钮 | |--------|-------|-------------| | 受付完了日時 | ✅ 保留 | — | | 出勤場所 → | **取消理由** | ❌ 去掉「参照ボタン」 | | 氏名 → | **メモ** | ✅ 保留「参照ボタン」(当内容过长时) | | 車名、依頼内容等 | ❌ 删除 | 此外: - 使用 `JafUiStateHost` 统一状态管理(与 JAFRSHO07020 一致) - 整体布局风格、间距、颜色、字体大小等保持统一 - 移除原滚动条外层的 `verticalScroll`,改用内层 `weight(1f)` 实现可滚动区域 --- ### ✅ 改写后的代码:`JAFRSHO07030Popup.kt` ```kotlin package jp.or.jaf.syg.feature.jafrsho07.jafrsho07030 import android.os.Build import androidx.annotation.RequiresApi 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.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource 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 androidx.hilt.navigation.compose.hiltViewModel import jp.or.jaf.syg.core.designsystem.theme.* import jp.or.jaf.syg.core.ui.components.JafRefrenceButton import jp.or.jaf.syg.core.ui.components.JafText import jp.or.jaf.syg.core.ui.components.JafThemelessBottomButton import jp.or.jaf.syg.feature.R import jp.or.jaf.syg.feature.jafrsho99.components.JafUiStateHost import org.json.JSONObject /** * JAFRSHO07030 指令確認画面_指令取消受信ポップアップ * * 設計書: JAFRSHO07030_画面設計書.xlsx * レイアウトは JAFRSHO07020 をベースに統一。 */ @RequiresApi(Build.VERSION_CODES.O) @Composable fun JAFRSHO07030Popup( params: JSONObject, modifier: Modifier = Modifier, viewModel: JAFRSHO07030ViewModel = hiltViewModel() ) { // パラメータ抽出 val ifShikibetsuCd by remember { mutableStateOf(params.optString("ifShikibetsuCd", "")) } val userCd by remember { mutableStateOf(params.optString("userCd", "")) } val shireiMngCd by remember { mutableStateOf(params.optString("shireiMngCd", "")) } val hanyoReasonCd by remember { mutableStateOf(params.optString("hanyoReasonCd", "")) } // 初期化 LaunchedEffect(Unit) { viewModel.handleAction( JAFRSHO07030Action.Initialize( ifShikibetsuCd = ifShikibetsuCd, userCd = userCd, shireiMngCd = shireiMngCd, hanyoReasonCd = hanyoReasonCd ) ) } // UiState 監視 + Dialog 表示制御 val uiState by viewModel.uiState.collectAsState() if (uiState.isVisible) { Dialog( onDismissRequest = { }, properties = DialogProperties( dismissOnBackPress = false, dismissOnClickOutside = false ) ) { JafUiStateHost( modifier = Modifier.fillMaxSize(), viewModel = viewModel, params = params ) { stateData -> JAFRSHO07030ContentView( modifier = modifier, viewModel = viewModel, stateData = stateData, onOkClick = { viewModel.handleAction(JAFRSHO07030Action.OnBtnRefer(shireiMngCd)) }, onCancelClick = { viewModel.handleAction(JAFRSHO07030Action.OnBtnRoger(shireiMngCd)) } ) } } } } @Composable private fun JAFRSHO07030ContentView( modifier: Modifier, viewModel: JAFRSHO07030ViewModel, stateData: JAFRSHO07030UiStateData, onOkClick: () -> Unit, onCancelClick: () -> Unit ) { val labelWidth: Dp = 200.dp Column( modifier = Modifier .fillMaxWidth(0.95f) .clip(MaterialTheme.shapes.searchFormOpenButtonShape) .background( brush = MaterialTheme.gradientColorScheme.knowMiddleLayer, shape = MaterialTheme.shapes.searchFormOpenButtonShape ) ) { // トップバー Box( modifier = Modifier .fillMaxWidth() .height(50.dp) .background(color = MaterialTheme.colorScheme.knowTopBar) ) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { JafText( text = "指令取消受信", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } Box( modifier = Modifier.fillMaxSize().padding(end = 16.dp), contentAlignment = Alignment.CenterEnd ) { JafText( text = stateData.receptionTime ?: "", textcolor = MaterialTheme.colorScheme.knowTopBarText, fontSize = 22.sp, style = JafTypography.topbarText ) } } Spacer(modifier = Modifier.height(16.dp)) Column( modifier = Modifier .fillMaxWidth() .padding(horizontal = 20.dp) ) { // 指令No表示 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "指令No", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f).clip(MaterialTheme.shapes.medium)) { JafText( text = stateData.shireiNo ?: "", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } Spacer(modifier = Modifier.height(20.dp)) // コンテンツボックス領域(可変高さでスクロール可能) Column( modifier = Modifier .fillMaxWidth() .weight(1f) .background( shape = MaterialTheme.shapes.searchFormOpenButtonShape, color = MaterialTheme.colorScheme.KnowContentLayer ) .verticalScroll(rememberScrollState()) ) { Spacer(modifier = Modifier.height(20.dp)) // 受付完了日時 Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = stringResource(id = R.string.column_completion_time), textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, textAlign = TextAlign.Left, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f).clip(MaterialTheme.shapes.medium)) { JafText( text = stateData.uketsukeCompDatetime ?: "", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } // 取消理由(参照ボタンなし) Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "取消理由", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f).clip(MaterialTheme.shapes.medium)) { JafText( text = stateData.torookeshiRiyuName ?: "", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } // 追加メッセージ(存在時のみ) if (!stateData.tuikaMassage.isNullOrBlank()) { Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "追加情報", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f)) { JafText( text = stateData.tuikaMassage, textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, style = JafTypography.middleLayerText ) } } } // メモ(=元の氏名欄を流用。長すぎると参照ボタン表示) Row( modifier = Modifier .clip(MaterialTheme.shapes.medium) .padding(horizontal = 14.dp) .padding(top = 16.dp), verticalAlignment = Alignment.CenterVertically ) { Row(modifier = Modifier.padding(end = 40.dp)) { JafText( text = "メモ", textcolor = MaterialTheme.colorScheme.popupTitleLabel, fontSize = 26.sp, style = JafTypography.topbarText, modifier = Modifier.width(labelWidth) ) } Column(modifier = Modifier.weight(1f).clip(MaterialTheme.shapes.medium)) { val memoText = stateData.memo ?: "" Row { JafText( text = memoText.take(if (memoText.length > 40) 39 else memoText.length), textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, textAlign = TextAlign.Left, style = JafTypography.middleLayerText ) // 長い場合に参照ボタン表示 if (memoText.length > 40) { JafRefrenceButton( modifier = Modifier.size(28.dp), enabled = true, onClick = { viewModel.handleAction(JAFRSHO07030Action.ReferenceButton("メモ")) } ) } } } } Spacer(modifier = Modifier.height(20.dp)) } // エラーメッセージ stateData.errorMessage?.let { message -> Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 8.dp), horizontalArrangement = Arrangement.Center ) { Text( text = message, color = MaterialTheme.colorScheme.error, fontSize = 16.sp, textAlign = TextAlign.Center ) } } // ローディング中 if (stateData.isLoading) { Row( modifier = Modifier .fillMaxWidth() .height(60.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { CircularProgressIndicator(strokeWidth = 2.dp, modifier = Modifier.size(30.dp)) } } // 確認メッセージ Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 16.dp), horizontalArrangement = Arrangement.Center ) { JafText( text = "この指令を取消しますか?", textcolor = MaterialTheme.colorScheme.knowContentLayerText, fontSize = 22.sp, fontWeight = FontWeight.Medium, textAlign = TextAlign.Center, style = JafTypography.message ) } // ボタンエリア Row( modifier = Modifier .fillMaxWidth() .padding(bottom = 15.dp), horizontalArrangement = Arrangement.Center ) { JafThemelessBottomButton( onClick = onCancelClick, modifier = Modifier.size(220.dp, 75.dp), enabled = stateData.isCancelButtonEnabled && !stateData.isLoading, text = stringResource(R.string.cancel), style = JafTypography.bottomLayerText ) Spacer(modifier = Modifier.width(20.dp)) JafThemelessBottomButton( onClick = onOkClick, modifier = Modifier.size(220.dp, 75.dp), enabled = stateData.isOkButtonEnabled && !stateData.isLoading, text = "OK", style = JafTypography.bottomLayerText ) } } } } ``` --- ### 🔍 解释说明 | 特性 | 说明 | |------|------| | ✅ 布局统一 | 完全模仿 `JAFRSHO07020Popup` 的 UI 结构,包括 label 宽度、padding、背景色、字体等 | | ✅ 使用 `JafUiStateHost` | 统一状态处理方式,便于后期维护和扩展 | | ✅ 可滚动内容区 | 使用 `.weight(1f)` + `verticalScroll` 实现中间区域滚动 | | ✅ 字段重命名 | “出勤場所” → “取消理由”,“氏名” → “メモ” | | ✅ 条件性按钮显示 | “メモ” 内容超长时才显示「参照ボタン」,符合原始设计规范 | | ✅ 清理冗余项 | 删除了車名、依頼内容等无关字段 | | ✅ 保留业务逻辑 | ViewModel 和 Action 触发逻辑未改动,仅视觉重构 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值