5.Android アプリに画像を追加する / パスウェイ 3 基本的なレイアウトを作成する / ユニット 1: 初めての Android アプリ
状態:未解決
閲覧数:24
投稿日:2024-10-24
更新日:2024-11-14
2. アプリを準備する
プロジェクトに画像を追加する
このタスクでは、インターネットから画像をダウンロードし、Happy Birthday アプリに追加します。
3.画像を右クリックし、パソコンに androidparty.png というファイル名で保存します。
5.Android Studio のメニューで、[View] > [Tool Windows] > [Resource Manager] をクリックするか、[Project] ウィンドウの横にある [Resource Manager] タブをクリックします。
注: Resource Manager は、アプリへのリソースのインポートや、アプリ内でのリソースの作成、管理、使用のためのツール ウィンドウです。
6.[+](モジュールにリソースを追加)> [Import Drawables] をクリックします。
7.ファイル ブラウザで、ダウンロードした画像ファイルを選択して [Open] をクリックします。
この操作により、[Import drawables] ダイアログが開きます。
8.Android Studio に画像のプレビューが表示されます。[QUALIFIER TYPE] プルダウン リストから [Density] を選択します。
9.[VALUE] リストから [No Density] を選択します。
Android デバイスは、画面サイズ(スマートフォン、タブレット、TV など)だけでなく、画面のピクセルサイズもさまざまです。1 平方インチあたり 160 ピクセルのデバイスもあれば、480 ピクセルのデバイスもあります。ピクセル密度の違いを考慮しないと、画像が拡大されてぼやける、メモリを大量に消費する大きな画像になる、あるいは不適切にサイズ変更された画像になることがあります。
Android システムが処理できるよりも大きな画像のサイズを変更しようとすると、メモリ不足エラーがスローされます。写真であったり、現在の画像 androidparty.png のような背景画像であったりする場合は、drawable-nodpi フォルダに置く必要があります。ここに置くとサイズ変更が行われなくなります。
ピクセル密度について詳しくは、各種のピクセル密度をサポートするをご覧ください。
10.[Next] をクリックします。
11.Android Studio に、画像が配置されるフォルダ構造が表示されます。先ほど説明した drawable-nodpi フォルダがあるはずです。
12.[Import(C)] をクリックします。
Android Studio によって drawable-nodpi フォルダが作成され、そこに画像が配置されます。Android Studio のプロジェクト ビューに、androidparty.png (nodpi) というリソース名で表示されます。Android Studio によって、パソコンのファイル システムに drawable-nodpi というフォルダが作成されます。
画像が正常に読み込まれると、Android Studio によって画像が [Drawable] タブのリストに追加されます。このリストには、アプリのすべての画像とアイコンが入っています。これで、この画像をアプリで使用できるようになりました。
13.[View] > [Tool Windows] > [Project] をクリックするか、左端の [Project] タブをクリックして、プロジェクト ビューに戻ります。
14.[app] > [res] > [drawable] をクリックして、画像が drawable フォルダにあることを確認します。
3. Image コンポーザブルを追加する
Text コンポーザブルを使用してテキストを表示する場合と同じようにして、Image コンポーザブルを使用して画像を表示できます。
このタスクでは、Image コンポーザブルをアプリに追加し、ダウンロードした画像をアプリの画像に設定して、その画像のサイズと位置を画面内に収まるように調整します。
画像を追加するためにコンポーズ可能な関数を追加する
1.MainActivity.kt ファイルで、GreetingText() 関数の後にコンポーズ可能な関数 GreetingImage() を追加します。
2.GreetingImage() 関数に 2 つの String パラメータを渡します。一つは誕生日祝いのメッセージの message、もう一つは署名の from です。
@Composable
fun GreetingImage(message: String, from: String) {
}
3.すべてのコンポーズ可能な関数は、オプションの Modifier パラメータを受け入れる必要があります。
修飾子は、UI 要素に対して親レイアウト内での配置、表示、動作を指示します。
GreetingImage() コンポーザブルで別のパラメータを追加します。
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
}
Jetpack Compose のリソース
リソースとは、コードが使用する追加のファイルと静的コンテンツであり、ビットマップ、ユーザー インターフェース文字列、アニメーション命令などがあります。
Android のリソースについて詳しくは、アプリのリソースの概要 をご覧ください。
画像や文字列などのアプリリソースは必ずコードとは別にする必要があります。
それにより、コードとは独立して管理できるようになります。
実行時に、Android は現在の設定に基づいて適切なリソースを使用します。た
とえば、画面サイズごとに異なる UI レイアウトや言語設定ごとに異なる文字列を指定できます。
リソースのグループ化
リソースは種類ごとにプロジェクトの res/ ディレクトリの対応するサブディレクトリに保存する必要があります。
たとえば、単純なプロジェクトのファイル階層の例を次に示します。
MyProject/
src/
MyActivity.kt
res/
drawable/
graphic.png
mipmap/
icon.png
values/
strings.xml
この例では、res/ ディレクトリのサブディレクトリにすべてのリソースが保存されていて、画像リソースは drawable/ ディレクトリ、ランチャー アイコンは mipmap/ ディレクトリ、文字列リソースは values/ ディレクトリに入ります。
アプリリソースの使用方法、形式、構文の詳細については、リソースタイプの概要をご覧ください。
リソースへのアクセス
Jetpack Compose は、Android プロジェクトで定義されたリソースにアクセスできます。
リソースにアクセスするには、プロジェクトの R クラスで生成されたリソース ID を使用します。
R クラスは、Android によって自動生成されたクラスであり、プロジェクト内のすべてのリソースの ID を含むクラスです。
ほとんどの場合、リソース ID はファイル名と同じになります。
たとえば、前のファイル階層の画像にアクセスするには、次のコードを使用します。
R.drawable.graphic
次のタスクでは、前のタスクに追加した画像ファイル androidparty.png を使用します。
1.GreetingImage() 関数の中で、image という名前の val プロパティを宣言します。
2.androidparty リソースを渡して painterResource() 関数を呼び出します。その戻り値を image 変数に代入します。
val image = painterResource(R.drawable.androidparty)
アプリをコンパイルするには関数をインポートする必要があるため、Android Studio は painterResource コードをハイライト表示します。
3.Android Studio でハイライト表示されている .painterResource をクリックします。
4.ポップアップで [Import] をクリックし、androidx.compose.ui.res.painterResource のインポートを追加します。
painterResource() 関数は、ドローアブル画像リソースを読み込みます。引数としてリソース ID(この場合は R.drawable.androidparty)を取ります。
5.painterResource() 関数の呼び出しの後に、Image コンポーザブルを追加し、painter という名前付きの引数として image を渡します。
Image(
painter = image
)
アプリをコンパイルするには関数をインポートする必要があるため、Android Studio は Image コードをハイライト表示します。
この警告を解決するには、MainActivity.kt ファイルの先頭に次のインポートを追加します。
import androidx.compose.foundation.Image
最初の警告は解決されましたが、Android Studio で単語 Image にカーソルを合わせると、[None of the following functions can be called with the arguments supplied] という新しい警告が表示されます。これは、提供された引数が Image 関数シグネチャのいずれとも一致しないためです。
アプリのユーザー補助対応を確認する
ユーザー補助を意識したコーディング習慣に従うことで、障がいを持つユーザーを含めた、すべてのユーザーがアプリ内の移動やアプリの操作を簡単に行えるようになります。
注: Android ではユーザー向けにさまざまなツールが用意されています。たとえば、TalkBack は Android デバイスに組み込まれている Google 製のスクリーン リーダーです。TalkBack により、画面を見ずにデバイスを使用できるよう音声フィードバックが提供されます。ユーザー補助機能について詳しくは、ユーザーが利用しやすいアプリを作成するをご覧ください。
Android Studio により、アプリのユーザー補助機能を強化するためのヒントと警告が提供されます。コンテンツの説明を使って UI 要素の目的を定義することで、TalkBack でアプリを利用しやすくなります。
しかし、このアプリの画像は装飾目的のみで使用されています。この場合は、画像にコンテンツの説明を追加すると TalkBack で利用しにくくなります。読み上げられるコンテンツの説明を設定するのではなく、画像の contentDescription 引数を null に設定すれば、TalkBack が Image コンポーザブルをスキップするようにできます。
Image コンポーザブルに、contentDescription という名前付き引数を追加し、その値は null に設定します。
Image(
painter = image,
contentDescription = null
)
Image コンポーザブルをプレビューする
このタスクでは、画像コンポーザブルをプレビューし、アプリをエミュレータまたはデバイスで実行します。
1.BirthdayCardPreview() 関数内の GreetingText() 関数の呼び出しを GreetingImage() 関数の呼び出しに置き換えます。
関数は次のコード スニペットのようになります。
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
2.[Design] ペインは自動更新されます。更新されない場合は、[609ccb451d05cf6b.png] をクリックしてビルドします。
すると、テキストが表示されなくなります。これは、新しい関数には Image コンポーザブルがあるだけで、Text コンポーザブルがなくなっているためです。
▼MainActivity.kt
package com.example.happybirthday
import android.os.Bundle
import android.text.Layout
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextAlign.Companion.Center
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HappyBirthdayTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) { GreetingText(
message = "Happy Birthday Sam!",
from = "From Emma",
modifier = Modifier.padding(8.dp)) }
}
}
}
}
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
textAlign = TextAlign.Center,
)
Text(
text = from,
fontSize = 36.sp,
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
)
}
}
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Image(
painter = image,
contentDescription = null
)
}
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
4. Box レイアウトを追加する
Compose には、基本的な標準レイアウト要素として、Column、Row、Box の 3 つのコンポーザブルがあります。Column コンポーザブルと Row コンポーザブルについては前の Codelab で学習したので、ここでは Box コンポーザブルについて詳しく学びます。
Box レイアウトは、Compose の標準レイアウト要素の一つです。Box レイアウトは、要素を別の要素の上に重ねるときに使用します。また、Box レイアウトを使用すると、それに含まれる要素の配置も設定することもできます。
1.次のように、GreetingImage() 関数内の Image コンポーザブルを Box コンポーザブルで囲みます。
2.Android Studio にプロンプトが表示されたら、androidx.compose.foundation.layout.Box 関数をインポートします。
3.modifier パラメータを Box コンポーザブルに渡すコードを追加します。
4.次のように、Box コンポーザブルの最後で GreetingText() 関数を呼び出し、誕生日メッセージと署名および修飾子を渡します。
5.[Design] ペインでプレビューが更新されます。
すると、テキストと画像が表示されます。
6.この変更をエミュレータまたはデバイスに反映させるために、onCreate() 関数内の GreetingText() 関数の呼び出しを GreetingImage() 関数の呼び出しに置き換えます。
その結果、setContent ブロックは次のコード スニペットのようになります。
画像は、画面と同じ幅になっていますが、画面の上側に寄せられています。画面の下側に空白があるので、あまり見栄えが良くありません。次のタスクでは、画面の上下左右に空白を作らないように、画像のサイズを画面全体のサイズに合わせます。
▼MainActivity.kt
Box レイアウトは、Compose の標準レイアウト要素の一つです。Box レイアウトは、要素を別の要素の上に重ねるときに使用します。また、Box レイアウトを使用すると、それに含まれる要素の配置も設定することもできます。
1.次のように、GreetingImage() 関数内の Image コンポーザブルを Box コンポーザブルで囲みます。
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Box {
Image(
painter = image,
contentDescription = null
)
}
}
2.Android Studio にプロンプトが表示されたら、androidx.compose.foundation.layout.Box 関数をインポートします。
3.modifier パラメータを Box コンポーザブルに渡すコードを追加します。
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Box(modifier) {
Image(
painter = image,
contentDescription = null
)
}
}
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Box(modifier) {
Image(
painter = image,
contentDescription = null
)
}
}
4.次のように、Box コンポーザブルの最後で GreetingText() 関数を呼び出し、誕生日メッセージと署名および修飾子を渡します。
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Box(modifier) {
Image(
painter = image,
contentDescription = null
)
GreetingText(
message = message,
from = from,
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
)
}
}
5.[Design] ペインでプレビューが更新されます。
すると、テキストと画像が表示されます。
6.この変更をエミュレータまたはデバイスに反映させるために、onCreate() 関数内の GreetingText() 関数の呼び出しを GreetingImage() 関数の呼び出しに置き換えます。
その結果、setContent ブロックは次のコード スニペットのようになります。
setContent {
HappyBirthdayTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
}
画像は、画面と同じ幅になっていますが、画面の上側に寄せられています。画面の下側に空白があるので、あまり見栄えが良くありません。次のタスクでは、画面の上下左右に空白を作らないように、画像のサイズを画面全体のサイズに合わせます。
▼MainActivity.kt
package com.example.happybirthday
import android.os.Bundle
import android.text.Layout
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextAlign.Companion.Center
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HappyBirthdayTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
}
}
}
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
textAlign = TextAlign.Center,
)
Text(
text = from,
fontSize = 36.sp,
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
)
}
}
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Box(modifier) {
Image(
painter = image,
contentDescription = null
)
GreetingText(
message = message,
from = from,
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
)
}
}
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
5. 不透明度を変更し、画像を拡大縮小する
このタスクでは、アプリの見栄えを良くするために画像が全画面に表示されるようにします。そのために、ContentScale パラメータを使用します。
アプリに画像を追加して、画像の位置設定を行いました。次は、画像のスケーリングの種類(画像のサイズの調整方法)を設定して、画像が全画面に表示されるようにします。
ContentScale には多数の種類が用意されています。ここでは ContentScale.Crop パラメータを使用し、画像の幅と高さが、それぞれ画面の幅と高さと等しいかそれ以上になるように、アスペクト比を維持しながら均等に画像を拡大します。
Image に ContentScale の名前付き引数を追加します。
2.Android Studio にプロンプトが表示されたら、androidx.compose.ui.layout.ContentScale インターフェースをインポートします。
3.[Design] ペインを確認します。
すると、次のスクリーンショットのように、画像がプレビュー画面全体に表示されます。
アプリのコントラストを向上させるには、背景画像の不透明度を変更します。
alpha パラメータを Image コンポーザブルに追加し、0.5F に設定します。
画像の不透明度が変更されます。
大量のコードになりましたが、その結果をプレビューしましょう。
デバイスまたはエミュレータでアプリを実行します。
修飾子は、Jetpack Compose UI 要素の装飾や、その動作の追加に使用されます。たとえば、行やテキスト、ボタンに、背景やパディング、動作を追加できます。このような設定をするには、コンポーザブルまたはレイアウトが修飾子をパラメータとして受け取る必要があります。
前回の Codelab で修飾子について説明した際には、パディング修飾子(Modifier.padding)を使用して、Text コンポーザブルの周囲に空白を追加しました。修飾子には多くの機能がありますが、それらは今回と以降で説明します。
たとえば、次の Text コンポーザブルには背景を緑色にする Modifier 引数があります。
上記の例と同様に、引数と引数修飾子をレイアウトに追加することで、Arrangement プロパティと Alignment プロパティを使用して子要素を配置できます。
Row 内の子の位置を設定するには、horizontalArrangement 引数と verticalAlignment 引数を設定します。Column の場合は、verticalArrangement 引数と horizontalAlignment 引数を設定します。
Arrangement プロパティは、レイアウトのサイズが子の合計よりも大きい場合に、子要素を配置するために使用されます。
たとえば、Column のサイズが子のサイズの合計よりも大きい場合、verticalArrangement を指定して Column 内の子の位置を定義できます。以下に、さまざまな垂直配置の図を示します。
同様に、Row のサイズが子のサイズの合計よりも大きい場合は、horizontalArrangement を指定して Row 内の子の位置を定義できます。以下に、さまざまな水平配置の図を示します。
Alignment プロパティは、子要素をレイアウトの先頭、中央、末端に配置するために使用されます。
▼MainActivity.kt
1.コンテンツのサイズを調整する
アプリに画像を追加して、画像の位置設定を行いました。次は、画像のスケーリングの種類(画像のサイズの調整方法)を設定して、画像が全画面に表示されるようにします。
ContentScale には多数の種類が用意されています。ここでは ContentScale.Crop パラメータを使用し、画像の幅と高さが、それぞれ画面の幅と高さと等しいかそれ以上になるように、アスペクト比を維持しながら均等に画像を拡大します。
Image に ContentScale の名前付き引数を追加します。
Image(
painter = image,
contentDescription = null,
contentScale = ContentScale.Crop
)
painter = image,
contentDescription = null,
contentScale = ContentScale.Crop
)
2.Android Studio にプロンプトが表示されたら、androidx.compose.ui.layout.ContentScale インターフェースをインポートします。
3.[Design] ペインを確認します。
すると、次のスクリーンショットのように、画像がプレビュー画面全体に表示されます。
不透明度の変更
アプリのコントラストを向上させるには、背景画像の不透明度を変更します。
alpha パラメータを Image コンポーザブルに追加し、0.5F に設定します。
Image(
painter = image,
contentDescription = null,
contentScale = ContentScale.Crop,
alpha = 0.5F
)
画像の不透明度が変更されます。
大量のコードになりましたが、その結果をプレビューしましょう。
アプリを実行する
デバイスまたはエミュレータでアプリを実行します。
レイアウト修飾子
修飾子は、Jetpack Compose UI 要素の装飾や、その動作の追加に使用されます。たとえば、行やテキスト、ボタンに、背景やパディング、動作を追加できます。このような設定をするには、コンポーザブルまたはレイアウトが修飾子をパラメータとして受け取る必要があります。
前回の Codelab で修飾子について説明した際には、パディング修飾子(Modifier.padding)を使用して、Text コンポーザブルの周囲に空白を追加しました。修飾子には多くの機能がありますが、それらは今回と以降で説明します。
たとえば、次の Text コンポーザブルには背景を緑色にする Modifier 引数があります。
// Example
Text(
text = "Hello, World!",
// Solid element background color
modifier = Modifier.background(color = Color.Green)
)
上記の例と同様に、引数と引数修飾子をレイアウトに追加することで、Arrangement プロパティと Alignment プロパティを使用して子要素を配置できます。
Row 内の子の位置を設定するには、horizontalArrangement 引数と verticalAlignment 引数を設定します。Column の場合は、verticalArrangement 引数と horizontalAlignment 引数を設定します。
Arrangement プロパティは、レイアウトのサイズが子の合計よりも大きい場合に、子要素を配置するために使用されます。
たとえば、Column のサイズが子のサイズの合計よりも大きい場合、verticalArrangement を指定して Column 内の子の位置を定義できます。以下に、さまざまな垂直配置の図を示します。
同様に、Row のサイズが子のサイズの合計よりも大きい場合は、horizontalArrangement を指定して Row 内の子の位置を定義できます。以下に、さまざまな水平配置の図を示します。
Alignment プロパティは、子要素をレイアウトの先頭、中央、末端に配置するために使用されます。
▼MainActivity.kt
package com.example.happybirthday
import android.os.Bundle
import android.text.Layout
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.ContentScale.Companion.Crop
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextAlign.Companion.Center
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HappyBirthdayTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
}
}
}
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
textAlign = TextAlign.Center,
)
Text(
text = from,
fontSize = 36.sp,
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
)
}
}
@Composable
fun GreetingImage(message: String, from: String, modifier: Modifier = Modifier) {
val image = painterResource(R.drawable.androidparty)
Box(modifier) {
Image(
painter = image,
contentDescription = null,
contentScale = Crop,
alpha = 0.5F
)
GreetingText(
message = message,
from = from,
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
)
}
}
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingImage(
message = "Happy Birthday Sam!",
from = "From Emma"
)
}
}
6. テキストの配置を調整する
このタスクでは、前の Codelab でアプリにテキストを配置するために追加したコードを確認します。
1.MainActivity.kt ファイルで、GreetingText() 関数までスクロールします。この列の verticalArrangement プロパティは Arrangement.Center に設定されています。テキスト コンテンツは画面の中央に配置されます。
UI 要素はコンテンツを囲んでいます。余白が狭すぎないようにするために、上下左右のパディングの量を指定できます。
パディングは修飾子として使用されるので、任意のコンポーザブルに適用できます。padding 修飾子は、コンポーザブルの上下左右のそれぞれに対してパディングの量を定義するオプションの引数を取ります。
1.実践しましょう。MainActivity.kt ファイルで、GreetingText() 関数が呼び出されるところまでスクロールし、パディング属性を確認します。
2.同様に、GreetingText() 関数の内側で、署名の Text コンポーザブルのパディングも確認します。
1.MainActivity.kt ファイルで、GreetingText() 関数までスクロールします。この列の verticalArrangement プロパティは Arrangement.Center に設定されています。テキスト コンテンツは画面の中央に配置されます。
@Composable
fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) {
Column(
verticalArrangement = Arrangement.Center,
modifier = modifier
) {
Text(
text = message,
fontSize = 100.sp,
lineHeight = 116.sp,
textAlign = TextAlign.Center
)
Text(
text = from,
fontSize = 36.sp,
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
)
}
}
パディング
UI 要素はコンテンツを囲んでいます。余白が狭すぎないようにするために、上下左右のパディングの量を指定できます。
パディングは修飾子として使用されるので、任意のコンポーザブルに適用できます。padding 修飾子は、コンポーザブルの上下左右のそれぞれに対してパディングの量を定義するオプションの引数を取ります。
// This is an example.
Modifier.padding(
start = 16.dp,
top = 16.dp,
end = 16.dp,
bottom = 16.dp
)
1.実践しましょう。MainActivity.kt ファイルで、GreetingText() 関数が呼び出されるところまでスクロールし、パディング属性を確認します。
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
2.同様に、GreetingText() 関数の内側で、署名の Text コンポーザブルのパディングも確認します。
modifier = Modifier
.padding(16.dp)
.align(alignment = Alignment.End)
7. 適切なコード プラクティスを採用する
「ハードコード」された文字列とは、アプリのコードに直接書き込まれた文字列です。ハードコードされた文字列を使用すると、アプリを他の言語に翻訳するのが難しくなり、アプリの文字列を別の場所で再利用するのが難しくなります。この問題は、文字列をリソース ファイルに抽出することで解決できます。具体的には、文字列をコード内にハードコードする代わりに別のファイルに格納して、文字列リソースに名前を付けます。文字列を使用するときには、この名前を使用するようにします。文字列を変更したり、他の言語に翻訳したりしても、名前は変わりません。
1.MainActivity.kt ファイルで、onCreate() 関数までスクロールします。誕生日祝いのメッセージ(Happy Birthday Sam! 文字列、引用符なし)を選択します。
2.画面左側の電球アイコンをクリックします。
3.[Extract string resource] を選択します。
Android Studio で [Extract Resource] ダイアログが開きます。このダイアログでは、文字列リソースの名前と保存方法の詳細をカスタマイズできます。[Resource name] フィールドには、文字列の名前を入力します。[Resource value] には、実際の文字列を入力します。
4.[Extract Resource] ダイアログで、[Resource name] を happy_birthday_text に変更します。
文字列リソースの名前には小文字を使用し、複数の単語はアンダースコアで区切るようにします。他の設定はデフォルトのままにします。
5.[OK] をクリックします。
6.コードの変更点を確認しましょう。
ハードコードされた文字列が getString() 関数の呼び出しに置き換えられています。
GreetingImage(
message = getString(R.string.happy_birthday_text),
from = "From Emma",
modifier = Modifier.padding(8.dp)
)
注: 一部の Android Studio バージョンでは、ハードコードされた文字列は getString() 関数に置き換えられます。このような場合は、手動で関数を stringResource() に変更してください。
必要に応じて、import androidx.compose.ui.res.stringResource を import セクションに追加します。
必要に応じて、import androidx.compose.ui.res.stringResource を import セクションに追加します。
7.[Project] ペインでパス app > res > values > strings.xml の strings.xml ファイルを開くと、happy_birthday_text という文字列リソースが Android Studio により作成されたのがわかります。
<resources>
<string name="app_name">Happy Birthday</string>
<string name="happy_birthday_text">Happy Birthday Sam!</string>
</resources>
strings.xml ファイルには、アプリによってユーザーに表示される文字列のリストが入っています。アプリの名前も文字列リソースです。文字列をすべて 1 か所にまとめることで、アプリ内のテキストの翻訳が簡単になり、アプリの別の場所で文字列を再利用するのも簡単になります。
8.同じ手順で署名である Text コンポーザブルのテキストを抽出しますが、今度は [Resource name] フィールドに signature_text を入力します。
完成したファイルは以下のようになります。
<resources>
<string name="app_name">Happy Birthday</string>
<string name="happy_birthday_text">Happy Birthday Sam!</string>
<string name="signature_text">From Emma</string>
</resources>
9.stringResource() と抽出された文字列を使用するように BirthdayCardPreview() を更新します。
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
GreetingImage(
message = stringResource(R.string.happy_birthday_text),
from = stringResource(R.string.signature_text)
)
}
}
注: Android Studio でstringResource にカーソルを合わせると、[Unresolved reference: stringResource] という警告メッセージが表示される場合は、stringResource() 関数を使用するために androidx.compose.ui.res.stringResource の import ステートメントを追加する必要があります。
10.アプリをもう一度実行し、変わらず動作していることを確認します。
「cluan project」では何も変わらずエラー
Invalidate Caches / Restartで期待した通り動作した
Android Studioのキャッシュが原因でエラーが発生した場合には、キャッシュエラーと表示させたい | 「Compose を用いた Android アプリ開発の基礎」カテゴリー | Kotlin 0
このエラーは、Kotlinのコンパイルデーモンに接続できないことが原因 | 「環境構築」カテゴリー | Kotlin 1