たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 1942
どうもこんばんわ。Xperia 1 VII
の交換面倒だからって後回しにしてたらついにハガキ来た。
いや、いい加減いかないとまずいと思って、今、交換機の入荷待ちなのよね。メッセージR
(←え?!??!!!?)で連絡が来るとかなんとか
数日後にはショートメールも来た。2回目くらい。
ブラウザのシークレットモードってUI
がライトテーマでも、シークレット感を出すため?なのか、無理やりダークモードになりますよね。
こーゆーのを実装するの、テーマによらず常にそれ用の色を当てる真面目な方法がありますが、もう一つ、すでにあるダークテーマを無理やり適用する事もできます。
JetpackCompose
でContext#createConfigurationContext
を使いたい。
返り値の、無理やりダークモードにしたResouces
をなんとか適用したい。
無理やりすればcolors.xml
もそれ用になるし、言語を無理やり変えればその言語のstrings.xml
になります。
これをJetpackCompose
でうまく使う方法を思いつきました。ここに書きます。
(というかJetpackCompose
のstringResource()
コード眺めたたら見つけた)
Jetpack Compose BOM 2025.08.00
が必要です
なまえ | あたい |
---|---|
Android Studio | Android Studio Narwhal 3 Feature Drop 2025.1.3 |
端末 | Pixel 8 Pro |
2025.08.00 ?
からLocalResources
ってComposition Local
ができました。
今まではLocalContext.current.resources
してアクセスしていましたが、いまは出来た方を使ってるはず?
で、そのLocalResources
の値をCompositionLocalProvider { }
で上書きしちゃえば、Context#createConfigurationContext
で出来たResouces
がJetpackCompose
でも使える!!
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
LocelResourcesDarkTheme {
MainScreen()
}
}
}
}
@Composable
private fun MainScreen() {
val context = LocalContext.current
val configuration = LocalConfiguration.current
// Resources を作る
// 多分本来は Context を作るものだが、Context は上書きしたくないので、Resources だけ取得する
val newResources = context.createConfigurationContext(Configuration(configuration).apply {
uiMode = Configuration.UI_MODE_NIGHT_YES
}).resources
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
.background(Color.Red)
) {
CompositionLocalProvider(LocalResources provides newResources) {
// colorResource 等は今の LocalResources を参照するので
Text(
text = "Resources 上書き",
color = colorResource(R.color.text_color)
)
}
Text(
text = "Resources もともと",
color = colorResource(R.color.text_color)
)
}
}
}
違いがわかるようにvalues/colors.xml (ライトテーマ)
とvalues-night/colors.xml (ダークテーマ)
にそれぞれ別の色を当てます。
<color name="text_color">@android:color/black</color>
<color name="text_color">@android:color/white</color>
LocalContext
をCompositionLocalProvider { }
で上書きすれば、過去バージョでも動くじゃん。
↓
それだと、LocalContext.current as Activity
が利用できなくなります。Context#createConfigurationContext
で返ってきたContext
は、たとえ元々がActivity
でも、android.app.ContextImpl
が返され、もちろんinstanceof Activity
はfalse
を返します。
Xperia 1 VII
はやく来てほしいです