Flutter, React Native(Expo), Xamarin.Formsで、振る舞いが同じアプリを作っているんですが、その時にそれぞれのフレームワークでテキスト表示の部分だけを、別のファイルに切り出した(ファイル分割した)場合にどのようになるのか調べました。
1つのファイルで作り込んでそのファイルが肥大化した場合に、どうやってファイルを切り出すか知っていると、プロジェクトの内部構成を整理整頓する時に役立つと思い。。。
留意事項
その1
「こう実装すればこう動く、ってことが分かればそれでOK!」を方針に実装進めた個人開発の内容を記載しましたので、「なぜその実装が必要なのか?」や「なぜその実装で動くのか?」は分かってない部分多数です。。。
その2
筆者は実戦経験が乏しい(というより、アプリ開発は個人開発を除いて、現場での開発が未経験。。)、なので、ご指摘は「ここは、こうした方が良いよ」くらいのノリでお願いします。
その3
「HelloWorldまでできたけど、こんなことできたら嬉しいな〜」って自分が思っていた時のことを思い出して書きました。そのため、強々エンジニアや超人エンジニアの方々はこのページを参考にしない方が良いと思います。
Flutter
以下の記事を参考に、Flutterでテキストの表示を別ファイルに切り出しました。
参照記事:https://qiita.com/i47_rozary/items/21ea4ba1713334b2a4ba
切り出し前
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("切り出す部分のテキスト表示"), //このテキストを別ファイルに切り出す
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
切り出し後
別ファイルに切り出す場合、大まかには以下のことをやります
- 「child.dart」ファイルを新規作成
- child.dartファイルにmain.dartから呼び出すときのクラス名「Child」を作成
- オプションでmain.dartから呼び出すメソッド「callChild」を生成
- child.dartにTextを生成
- main.dartにchild.dartをimport
- main.dartのText部分をchild.dartのクラス名「Child」に変更
import 'package:flutter/material.dart';
GlobalKey<_ChildState> childKey = new GlobalKey<_ChildState>();
//呼び出すクラス名を「Child」に統一
class Child extends StatefulWidget {
Child({Key key}) : super(key: key);
@override
_ChildState createState() => _ChildState();
}
//Stateにするクラス名を「Child」に統一
class _ChildState extends State<Child> {
//main.dart(呼び出し元)からChildクラスのメソッドを呼べるようにするため、メソッドを作成
void callChild(String message) {
print(message);
}
@override
Widget build(BuildContext context) {
return new Text('切り出す部分のテキスト表示');
}
}
import 'package:flutter/material.dart';
import 'child.dart'; //切り出したテキストを表示するファイルをimport
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
// 切り出したChildクラスにあるcallChildメソッドを呼び出す
// Childクラスに設定したkey「childKey」を使って、callChildメソッドを呼び出す
childKey.currentState.callChild("message");
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//呼び出すクラス「Child」
//Childクラスのメソッドを呼ぶ場合のkey「childKey」を設定
Child(key: childKey),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
React Native(Expo)
以下の記事を参考に、React Native(Expo)でテキストの表示を別ファイルに切り出しました。
参照記事:https://dev.to/codekagei/react-native-custom-tab-component-reactnative-navigation-1d39
切り出し前
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>切り出す部分のテキスト表示</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
切り出し後
別ファイルに切り出す場合、大まかには以下のことをやります
- 「Child.js」ファイルを新規作成
- Child.jsファイルにTextを生成
- App.jsにChild.jsをimport
- App.jsのText部分をChild.jsの宣言「Child」に変更
import React from "react";
import { Text, StyleSheet } from "react-native";
export default function App() {
return (
<Text style={styles.textWhite}>切り出す部分のテキスト表示</Text>
);
};
const styles = StyleSheet.create({
textWhite: {
backgroundColor: "white",
color: "black"
}
});
import React from 'react';
import { StyleSheet, View } from 'react-native';
//タグ「Child」で統一
import Child from "./Child";
export default function App() {
return (
<View style={styles.container}>
//Childタグでchild.jsのTextを参照(?)する
<Child />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Xamarin.Forms
以下の記事を参考に、Xamarin.Formsでテキスト(Label)の表示を別ファイルに切り出しました。
参照記事:https://somostechies.com/using-xml-namespaces-to-optimize-your-imports-in-xamarin-forms/
切り出し前
<?xml version="1.0" encoding="utf-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="xamarin.forms_project.MainPage">
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
</Frame>
<Label FontSize="26"
TextColor="Black"
BackgroundColor="Aqua">切り出す部分のテキスト表示</Label>
</StackLayout>
</ContentPage>
切り出し後
別ファイルに切り出す場合、大まかには以下のことをやります
- 新しいファイル -> ContentPage XAML -> 「MyLabel」ファイルを新規作成
- MyLabel.xamlファイルにLabelを生成
- MainPage.xamlのnamespaceにMyLabel.xamlがある階層をmypageとして定義
- MainPage.xamlのLabel部分をmypage:MaLabelに変更
<?xml version="1.0" encoding="UTF-8"?>
<Label xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
FontSize="26"
TextColor="Black"
BackgroundColor="Aqua"
x:Class="xamarin.forms_project.Pages.MyLabel">
切り出す部分のテキスト表示
</Label>
<?xml version="1.0" encoding="utf-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mypage="clr-namespace:xamarin.forms_project.Pages"
x:Class="xamarin.forms_project.MainPage">
<StackLayout>
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
</Frame>
<mypage:MyLabel />
</StackLayout>
</ContentPage>
感想
「別のファイル作って、そこに書くだけじゃん!」って、思ってた時の自分にこのページを教えてあげたい