カテゴリー
App

SwiftとKotlinとFlutterの画面レイアウト作成-01

モバイルアプリのUIを作成する方法を勉強してみます。

大昔のシステム開発ではUIもその裏の処理もプログラムを組んでいましたが、いつの頃からかUIはデザインツールを使ってXMLでレイアウトを作るようになりました。

ですが、最近はUIもプログラムでまた作るようになってきました。元に戻ったのですね。それとも流行の繰り返しでしょうか。


早速、主要なモバイルアプリ開発環境でのUIの作り方を見てみましょう。

SwiftでiOSアプリを開発する時は、

Xcodeに含まれるInterface Builderを使用してXMLのレイアウトファイルを作成していました。これからはSwiftUIでプログラムと同じようにレイアウトを作ります。

// SwiftUIでレイアウトを書くとこんな感じになります。

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .font(.largeTitle)
            .padding()
    }
}

KotlinでAndroidアプリを開発する時は、

AndroidStudioに含まれるLayout Editorを使用してXMLのレイアウトファイルを作成していました。これからはComposeでプログラムと同じようにレイアウトを作ります。

// Composeでレイアウトを書くとこんな感じになります。

fun AppContent() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "Hello, World!", style = MaterialTheme.typography.h4)
    }
}

FlutterでiOS, Androidアプリを開発する時は、

プログラムと同じようにDartでレイアウトを作ります。Flutterは最初からレイアウトをプログラムとして記述する方法でした。

SwiftUIやComposeがFlutterのUI作成方法に寄ってきた感じがします。

// Flutterでレイアウトを書くとこんな感じになります。

Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Hello World App',
    home: Scaffold(
      appBar: AppBar(
        title: Text('Hello World'),
      ),
      body: Center(
        child: Text('Hello, World!'),
      ),
    ),
  );
}

では、実際に「Hello World」を画面に表示してみます。

SwiftUIでHello World

//
//  LayoutSample01App.swift
//  LayoutSample01
//
//  アプリメイン
//  Created by mymyser.com on 2023/08/29.
//

import SwiftUI

@main
struct LayoutSample01App: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
//
//  ContentView.swift
//  LayoutSample01
//
//  画面レイアウト
//  Created by mymyser.com on 2023/08/29.
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello World")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

たった2つのクラスで画面表示だけのアプリができます。XibとObjective-CやStoryBoardとSwiftでアプリを作っていた頃と比べると隔世之感がありますね。

ComposeでHello World

AndroidStudioでプロジェクトを新規作成するときCompose用のテンプレートは出てきません。

公式には出てくるようなことが書いてありますが、新規作成の時にEmpty Activityを選ぶとCompose用のプロジェクトが書き出されます。

package com.mymyser.skf.layout.layoutsample01

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.mymyser.skf.layout.layoutsample01.ui.theme.LayoutSample01Theme

// アプリメイン
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LayoutSample01Theme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting()
                }
            }
        }
    }
}

// 画面レイアウト
@Composable
fun Greeting(modifier: Modifier = Modifier) {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = "Hello World",
            modifier = modifier
        )
    }
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    LayoutSample01Theme {
        Greeting()
    }
}

AndroidではXMLのレイアウトを読み込み画面に表示する仕組みでしたが、たった1つのクラスでアプリのメインと画面レイアウトを作ることができます。

LayoutEditorを使って制約やらプロパティやらを設定したり、知らない間にGitでレイアウトファイルの差分が出てしまったり苦労が絶えませんでした。

これからはソースと一体化して扱えるのでComposeへの期待が大きいです。

FlutterでHello World

import 'package:flutter/material.dart';

// アプリメイン
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

// 画面レイアウト
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('Hello World',),
        ],
      ),
    );
  }
}

Flutterは良いですね。最初からプログラムもレイアウトも同じようにDartで書けます。

操作を覚えるのが大変なレイアウトツールを使わなくても良いです。

別に作ったレイアウトファイルを読み込んだり定義したりもありません。処理とレイアウトをソースコードとして扱えます。

Gitでの差分の管理が楽ですね。


モバイルアプリ開発のUI作成は暫くこれらのように

画面のソースコード + 処理のソースコード

の組み合わせが続くと思います。

Swift, Kotlin, Flutterそれぞれ開発言語・環境は異なりますがその向かっている方向は同じような気がします。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です