#1 ๊ฐ์
๊ฐ๋ฐํด ๋ ์ปค์คํ ์ปดํฌ๋ํธ๋ฅผ ๋ณธ ํ๋ก์ ํธ(Nutri Capture)์์ ์ฌ์ฉํ๋ค.
#2 ๊ฐ์ ํ ํฌ์ธํธ
ContentWithSwipeableBottomSheet()
#1 ๊ฐ์BottomSheetScaffold()์ ๋ฌธ์ ์ ์ ๊ฐ์ ํ, ์ปค์คํ ์ปดํฌ๋ํธ ContentWithSwipeableBottomSheet()๋ฅผ ๊ตฌํํ๋ค (๊ฒ์๊ธ ๋งจ ์๋์ ์์ค์ฝ๋ ์์). #2 BottomSheetScaffold()#2-1 ๊ฐ์ androidx.compose.material | API reference
kenel.tistory.com
์์ ์ปค์คํ Scaffold๋ฅผ Nutri Capture ํ๋ก์ ํธ์ ์ ์ฉํ๋ค.
#3 ์ฝ๋ ์ค๋ํซ
#3-1 class MainActivity
...
...
class MainActivity : ComponentActivity() {
...
...
override fun onCreate(savedInstanceState: Bundle?) {
...
...
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
setContent {
...
}
}
}
BottomSheet์ ๋งค๋๋ฌ์ด ๋์์ ์ํด, ContentWithSwipeableBottomSheet()๋ window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) ์์ด ๋์ํ์ง ์๋๋ก ์ค์ ํด ๋์๋ค. ๋ฐ๋ผ์ ์ ์ธํด ๋๋ค.
#3-2 fun NutrientScreen()
...
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NutrientScreen() {
val sheetState = rememberContentWithSwipeableBottomSheetState(
anchoredDraggableState = AnchoredDraggableState(SheetValue.PartiallyExpanded)
)
var sheetExpandedAnchorOffset by remember { mutableStateOf(0.dp) }
val statusBarHeightDp = with(LocalDensity.current) {
WindowInsets.statusBars.getTop(this).toDp()
}
LaunchedEffect(statusBarHeightDp) {
sheetExpandedAnchorOffset = statusBarHeightDp
}
ContentWithSwipeableBottomSheet(
sheetContent = {
NutrientBottomSheet()
},
modifier = Modifier
.fillMaxSize()
.background(BottomAppBarDefaults.containerColor),
sheetState = sheetState,
sheetExpandedAnchorOffset = sheetExpandedAnchorOffset,
sheetPartiallyExpandedHeight = storedImeMaxHeight(),
sheetSwipeEnabled = true,
hasContentNavigationBarPadding = true
) {
Column(modifier = Modifier.fillMaxSize()) {
NutrientHistory()
NutrientChatBar()
}
}
}
์ด ์ฝ๋๋ฅผ ์ฐธ์กฐํ๋ค.
#3-3 object SystemPreferences
// package com.example.datastore
import android.content.Context
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlin.math.roundToInt
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "system")
object SystemPreferences {
val IME_MAX_HEIGHT_VALUE_KEY = intPreferencesKey("ime_max_height_dp")
val DEFAULT_IME_MAX_HEIGHT_VALUE = 250.dp.value.roundToInt()
private lateinit var appContext: Context
fun init(context: Context) {
appContext = context
}
fun getImeMaxHeight(): Flow<Dp> {
return appContext.dataStore.data.map { preferences ->
(preferences[IME_MAX_HEIGHT_VALUE_KEY] ?: DEFAULT_IME_MAX_HEIGHT_VALUE).dp
}
}
suspend fun setImeMaxHeight(imeHeight: Dp) {
appContext.dataStore.edit { preferences ->
preferences[IME_MAX_HEIGHT_VALUE_KEY] = imeHeight.value.toInt()
}
}
}
Bottom Sheet๊ฐ ๋๊น์ง ์ฌ๋ผ์จ ๋์ด๋ฅผ ์ฐ๊ฑฐ๋ ์ฝ๋ ํด๋์ค๋ค. ":datastore"๋ผ๋ ๋ชจ๋์ ์๋ก ๋ง๋ค๊ณ ๊ทธ ์์ ์ด ํด๋์ค๋ฅผ ๋ฃ์๋ค.
#3-4 class Application (@HiltAndroidApp)
// package com.example.nutri_capture_new
import android.app.Application
import com.example.datastore.SystemPreferences
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class NcApplication : Application() {
override fun onCreate() {
super.onCreate()
SystemPreferences.init(context = this)
}
}
SystemPreferences๊ฐ UI ๋จ์ null ๊ฐ์ ์ ๋ฌํ๋ ๊ฑธ ๋ง๊ธฐ ์ํด, Application ํด๋์ค์์ ์ด๊ธฐํ ์์ ์ ํด์ค๋ค.
#4 ์์ค ์ฝ๋
#4-1 ์ด ๊ฒ์๊ธ ์์ ์ Commit
GitHub - Kanmanemone/nutri-capture-new
Contribute to Kanmanemone/nutri-capture-new development by creating an account on GitHub.
github.com
#4-2 ๋ณธ ํ๋ก์ ํธ์ ๊ฐ์ฅ ์ต์ Commit
GitHub - Kanmanemone/nutri-capture-new
Contribute to Kanmanemone/nutri-capture-new development by creating an account on GitHub.
github.com