画面のコンポーネント
今回はポンコツ2人組がJetpack Composeの画面コンポーネントをいろいろ試してみました! 画面のコンポーネントの種類はたくさんありますが、基本的な部品は押さえておきたいですね。
MainActivity.kt
下記の部品を1つの画面に表示するサンプルプログラムです。
・テキスト
・ボタン
・イメージ
・リスト
・カード
・ボックス
・サーフェス
・スイッチ
・チェックボックス
・ラジオボタン
・表形式(LazyColumnとLazyRowの組み合わせ)
・ドロップダウンメニュー
イメージについては「sample_image.jpg」という名前の画像ファイルを追加する必要があります。 下記のスクリーンショットを参考に画像ファイルをドラッグ&ドロップするだけでOKです。
package com.example.sampleparts
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.sampleparts.ui.theme.SamplePartsTheme
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Switch
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SamplePartsTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting()
}
}
}
}
}
@Composable
fun Greeting(modifier: Modifier = Modifier) {
//context
val context = LocalContext.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Row {
Text(
text = "Jetpack Compose",
fontWeight = FontWeight.Bold,
color = Color.Black,
modifier = Modifier
.width(300.dp)
)
Spacer(modifier = Modifier.height(50.dp))
Button(
onClick = {
Toast.makeText(context, "クリックしたよ", Toast.LENGTH_SHORT).show()
}) {
Text("Click Me")
}
Spacer(modifier = Modifier.height(16.dp))
Image(
painter = painterResource(id = R.drawable.sample_image),
contentDescription = "Sample Image",
modifier = Modifier
.size(200.dp)
.clip(shape = MaterialTheme.shapes.medium),
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.height(16.dp))
val listItems = remember { (1..3).toList() }
val listState = rememberLazyListState()
LazyColumn(
state = listState,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
) {
items(listItems) { index ->
Text(
text = "Item $index",
fontSize = 20.sp,
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
}
}
}
Card(
modifier = Modifier
.fillMaxWidth()
.height(30.dp)
) {
Text(
text = "この部品はcard",
modifier = Modifier.padding(5.dp)
)
}
Spacer(modifier = Modifier.height(16.dp))
Row {
Box(
modifier = Modifier
.size(100.dp)
.background(Color.Red)
.border(2.dp, Color.Green)
.padding(8.dp)
)
Surface(
modifier = Modifier
.size(150.dp)
.clip(shape = CircleShape)
.shadow(8.dp),
color = Color.Yellow
) {
Text(
text = "Surface",
modifier = Modifier.padding(16.dp)
)
}
var switchState by remember { mutableStateOf(false) }
Switch(
checked = switchState,
onCheckedChange = { checked -> switchState = checked },
modifier = Modifier.padding(8.dp)
)
var checkboxState by remember { mutableStateOf(false) }
Checkbox(
checked = checkboxState,
onCheckedChange = { checked -> checkboxState = checked },
modifier = Modifier.padding(8.dp)
)
var radioCheckedIndex by remember { mutableStateOf(0) }
Column {
RadioButton(
selected = radioCheckedIndex == 0,
onClick = { radioCheckedIndex = 0 },
modifier = Modifier.padding(8.dp)
)
RadioButton(
selected = radioCheckedIndex == 1,
onClick = { radioCheckedIndex = 1 },
modifier = Modifier.padding(8.dp)
)
}
}
val tableData = listOf(
listOf("Name", "Age", "Gender"),
listOf("Latte", "1", "Female"),
listOf("Alice", "7", "Female")
)
LazyColumn(
modifier = Modifier
.border(1.dp, Color.Gray)
.padding(8.dp)
) {
tableData.forEach { rowData ->
item {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
rowData.forEach { cellData ->
Text(
text = cellData,
modifier = Modifier
.border(1.dp, Color.Gray)
.padding(8.dp)
)
}
}
}
}
}
var expanded by remember { mutableStateOf(false) }
val items = listOf("Option 1", "Option 2", "Option 3", "Option 4")
Box(modifier = Modifier.padding(8.dp)) {
Box(
modifier = Modifier
.background(Color.LightGray)
.clickable { expanded = true }
.padding(8.dp)
) {
Text(
text = "Dropdown ",
modifier = Modifier.padding(8.dp)
)
Icon(
imageVector = Icons.Default.ArrowDropDown,
contentDescription = "Dropdown",
modifier = Modifier.align(Alignment.CenterEnd)
)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
modifier = Modifier
.background(Color.LightGray)
.border(1.dp, Color.Gray)
) {
items.forEach { item ->
DropdownMenuItem(
text = { Text(text = item) },
onClick = {
expanded = false
Toast.makeText(context, item, Toast.LENGTH_SHORT).show()
}
)
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
SamplePartsTheme {
Greeting()
}
}
処理結果は次の通りです。
MainActivity.kt
一応 build.gradle(:app) の内容も掲載しておきます。
ポンコツ2人組が試した環境は「Android Studio Giraffe」ですがビルドに失敗したのでcompileSdkを34に変更しています。
ここは環境によって変わると思いますので適宜変更してください。
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.example.sampleparts'
compileSdk 34
defaultConfig {
applicationId "com.example.sampleparts"
minSdk 30
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.4.3'
}
packaging {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
implementation 'androidx.activity:activity-compose:1.8.0'
implementation platform('androidx.compose:compose-bom:2023.03.00')
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview'
implementation 'androidx.compose.material3:material3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation platform('androidx.compose:compose-bom:2023.03.00')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
}
今回のサンプルでは、出番が多そうな部品をピックアップしてみました。他にもいろいろな部品があるので
気になる人は挑戦してみてください。
さて、今回のサンプルプログラムは理解できましたか?
よく分からなかったという人は部品のプロパティをいろいろ変更してみて何が変わったのかを理解してみてください。 覚えることは多いですが、スキルアップ目指して頑張って勉強しましょうね!