LoginSignup
1
0

More than 3 years have passed since last update.

Flutter, React Native(Expo), Xamarin.Formsでテキストの表示を別のファイルに切り出す場合の実装を比べる

Last updated at Posted at 2020-09-15

Flutter, React Native(Expo), Xamarin.Formsで、振る舞いが同じアプリを作っているんですが、その時にそれぞれのフレームワークでテキスト表示の部分だけを、別のファイルに切り出した(ファイル分割した)場合にどのようになるのか調べました。
1つのファイルで作り込んでそのファイルが肥大化した場合に、どうやってファイルを切り出すか知っていると、プロジェクトの内部構成を整理整頓する時に役立つと思い。。。

留意事項

その1

「こう実装すればこう動く、ってことが分かればそれでOK!」を方針に実装進めた個人開発の内容を記載しましたので、「なぜその実装が必要なのか?」や「なぜその実装で動くのか?」は分かってない部分多数です。。。 :bow:

その2

筆者は実戦経験が乏しい(というより、アプリ開発は個人開発を除いて、現場での開発が未経験。。)、なので、ご指摘は「ここは、こうした方が良いよ:wink:」くらいのノリでお願いします。:pray::pray::pray:

その3

「HelloWorldまでできたけど、こんなことできたら嬉しいな〜」って自分が思っていた時のことを思い出して書きました。そのため、強々エンジニアや超人エンジニアの方々はこのページを参考にしない方が良いと思います。:expressionless::sleepy: :cold_sweat:

Flutter

以下の記事を参考に、Flutterでテキストの表示を別ファイルに切り出しました。
参照記事:https://qiita.com/i47_rozary/items/21ea4ba1713334b2a4ba

切り出し前

main.dart
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),
      ),
    );
  }
}

切り出し後

別ファイルに切り出す場合、大まかには以下のことをやります

  1. 「child.dart」ファイルを新規作成
  2. child.dartファイルにmain.dartから呼び出すときのクラス名「Child」を作成
    1. オプションでmain.dartから呼び出すメソッド「callChild」を生成
  3. child.dartにTextを生成
  4. main.dartにchild.dartをimport
  5. main.dartのText部分をchild.dartのクラス名「Child」に変更
child.dart
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('切り出す部分のテキスト表示');
  }
}
main.dart
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',
  },
});

切り出し後

別ファイルに切り出す場合、大まかには以下のことをやります

  1. 「Child.js」ファイルを新規作成
  2. Child.jsファイルにTextを生成
  3. App.jsにChild.jsをimport
  4. App.jsのText部分をChild.jsの宣言「Child」に変更
Child.js
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"
  }
});
App.js
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/

切り出し前

MainPage.xaml
<?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>

切り出し後

別ファイルに切り出す場合、大まかには以下のことをやります

  1. 新しいファイル -> ContentPage XAML -> 「MyLabel」ファイルを新規作成
  2. MyLabel.xamlファイルにLabelを生成
  3. MainPage.xamlのnamespaceにMyLabel.xamlがある階層をmypageとして定義
  4. MainPage.xamlのLabel部分をmypage:MaLabelに変更
MyLabel.xaml
<?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>
MainPage.xaml
<?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>

感想

「別のファイル作って、そこに書くだけじゃん!」って、思ってた時の自分にこのページを教えてあげたい:smirk:

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0