株式会社INTSへようこそ

Category: Uncategorized

基本的なフラッター: Widget Tree、 Element Tree と Render Tree

このシリーズの前回の投稿を読んだ後、実際にどのようにwidgetを再構築する方法に疑問を抱いているかと思います。 各widgetには独自のビルド関数があり、頻繁に呼び出されます。 この再構築から完了までの間に、パフォーマンスの何パーセントを消費しましょうか? これらすべてに答えられるために、Element Tree, Widget Tree と Render Treeを理解する必要があります。そして、Flutterの build(){…}メソッドを実行する方法、画面上の情報を再構築または変更する方法も理解することも必要です。 本当に何が起こったのでしょうか? Flutterは、build(){…} メソッドが呼び出されるたびに、UI全体を再描画または再作成するわけではありません。 それは、詳しく話しましょう。 Flutterで作成されたアプリケーションのデフォルト構成は60FPS(Frames Per Second)です。 つまり、Flutterシステムは毎秒60回インターフェイスを再描画します。 これは、Flutterが1秒間に60回レイアウト全体を再計算しなければならない場合にのみ、非効率になります。 Flutterが初めて画面に何かを描画する場合、画面上のすべてのコンポーネントの位置、色、テキストなどを計算する必要があります。要するに、最初のインターフェイスを描画する時、Flutterは画面上のそれぞれのピクセルを編集しなければなりません。 次回の編集/描画では、何も変更されていない場合にUIを更新するために、Flutterは既存の古い情報を取得し、画面上に超高速かつ非常に効率的に描画します。 その為に、再描画の速度が問題になく、Flutterが更新のたびに画面上のすべてを再計算する必要がある場合にのみ、問題になります。 では、この記事で、Flutterがbuild(){…}メソッドが呼び出されるたびにすべてを再計算するかどうかという内容を詳細に理解しましょう! Widget Tree‌‌ 簡単に言えば、Widget Tree というのは、アプリケーションの構築に使用されているすべてのWidgetです。つまり、書いたコードからwidget treeが作成されます。 それは完全に管理できます。widgetを宣言して、それらを一緒にネストすることで要望のレイアウトを作成します。 build(){…}メソッドを呼び出す時に、FlutterでWidget Treeがビルドされます。 Flutterシステムは、この部分を独自に処理します。 画面に表示されるだけではありません。 代わりに、Flutterまでに次回画面に何を描画するかと指示します。 Widget treeは頻繁に再構築されます。 Element Tree‌‌ Element Tree はWidget Treeにバインドされ, 実際に表示されているオブジェクト/要素と設定される情報です。再構築することはめったにありません。 Element Tree は別の方法で管理され、build(){…} メソッドが呼び出されても再構築されません。 Widget Treeの各 Widgetで、FlutterはそのWidgetのelementを自動的に作成します。 FlutterがWidgetを初めて処理するとすぐに実行されます。 ここで、elementは、Flutterによってメモリ内で管理されるオブジェクトであると言えます。Widget TreeのWidgetに関連します。 Elementは、ターミナルインターフェイスパラメータがあるWidget(Widget Tree内)への参照を1つだけ保持します。 Render Tree‌‌ Render Tree は、画面に表示されるelement /オブジェクトを表します。 Render Tree も頻繁に再構築されません!

Read More

Flutterの基本:最初のアプリプログラミング(第二部)

第一部はこちら ウィジェットを作成する Flutterアプリのすべてがウィジェットです! したがって、Flutterで画面に表示される全ての要素がウィジェットである。material.dart packageによって提供されるウィジェットには2つのタイプがあり、そのタイプの上で自分のカスタムウィジェットを構築します。それらはStatefulウィジェットとStatelessウィジェットです。 このシリーズの今後の記事では、state、stateful widgets 、およびstateless widgetsについて詳しく説明します。 Flutter and Dartプラグインを設定する場合、IDEまたはエディターで独自のカスタムウィジェットが構築できます。Statelessまたはstatefulを入力するだけで、IDEがそれに応じて提案を行います。 以下の例では、MyAppという名前のstatelessウィジェットを作成します。ウィジェットには任意の名前を選択できます。 この例の通り、独自のカスタムstatelessウィジェットを作成するため、material package によって提供されるStatelessWidgetを拡張しています。@overrideは、material packageによっても提供されるdecoratorです。 ウィジェットはabstract classであり、ビルドメソッドをオーバーライドする必要があります。このメソッドには、Flutterが提供するBuildContextのコンテキストが必要です。このメソッド内で、設立又は表示が必要なウィジェットを返します。 そこで、この例では、Flutterのmaterial.dartパッケージによって提供される組み込みウィジェットでもあるMaterialAppを返します。このウィジェットは、コンストラクターで複数の引数を受け入れます。詳細については、Material App にカーソルを合わせるか、Command+クリック又はCtrl +MaterialAppウィジェットをクリックしてください。 MaterialAppの3つのパラメーター(タイトル、テーマ、ホーム)を定義する必要があります。タイトルは単に文字列を受け入れることです。 値として「First App Demo」を提供します。テーマは、Flutter material packageの組み込み型であるThemeDataデータ型の値が必要です。したがって、次の例のように初期化します。 ThemeDataは、app Default themeを設定するために複数の値を受け入れます。primarySwatchは、MaterialColorタイプの値を受け入れる必須パラメーターです。これも組み込みタイプであり、Flutterがアプリのテーマを構築するためのColors.amberを提供するものです。 次に、ウィジェットタイプを受け入れるようにホームを設定する必要があります。ここで提供したウィジェットが画面に表示されます。そして、次のようなコンテナで初期化します:「home:Container(),」。これはまもなくカスタムウィジェットに置き換えられます。ウィジェットは次のようになります。 Main関数 アプリケーションを実行するには、main関数が必要です。main関数は、(){…}の一般的な構文を使用するか、 ()=>の矢印関数として定義することで記述できます。両方の構文は以下のコードを見て見ましょう。 又は: 上記の両方が正常に実行します。それでも、単一の値を返す必要がある場合は、矢印関数の方が良いと思います。そして、F5またはRun | Debugを押下してアプリケーションを実行すると、空白の画面が表示されます。 Statefulウィジェットを作成する FlutterにはStatelessとStatefulの2種類のウィジェットがあります。そのうち、Statefulウィジェットとは状態を持つウィジェットです。今回はStatefulWidgetを作成する方法を学習しましょう! Statefulウィジェットを作成するには、statefulを入力してTabを押すで、IDE又はEditorのオートコンプリート機能を使用します。例えば、以下のようなDummyWidgetという名前のStatefulウィジェットを作成しています。 StatefulウィジェットはStateless ウィジェットに比べると、違う点があります。 例えば、Statefulウィジェットは内部データの変更に対応し、自体が再レンダリングで変更を反映します。一方、Stateless ウィジェットは自体が再レンダリングしません。そして、この課題については、今後の記事で詳しく説明します。 Statefulウィジェットを理解するには、ある種の内部データが必要です。ここでは、_isGreenという名前のboolean値を使用して、デフォルトでfalseに初期化します。変数の前に_を付けて、Dartでのプライベート変数にし、このクラス内でのみアクセスできるようにしています。 それとともに、Widget build(BuildContext context){…}methodから空のコンテナーを返す代わりに、他の結果を返します!その結果はmaterial packageで提供されるウィジェットであるScaffoldを返すことです。新しい/異なる画面を表示するたびに、Scaffoldを提供する必要があることに注意してください。そして、Scaffoldは、初期化の方法でいくつかのパラメーターを受け入れます。 ここでは、appBarとbodyを提供して、画面にコンテンツをご覧になります。DummyWidgetが次のように表示されます。 このStateful DummyWidgetには、デフォルトがfalseの_isGreenという名前のbool型のprivate変数があります。コンテナを返す代わりに、Scaffoldウィジェットを返ます。そして、appBarとbodyの2つのパラメータを提供しました。

Read More

基本的なフラッター:マルチスクリーンアプリケーションを作成します(第一部)

この記事では、Navigationを使用してFlutterでマルチスクリーンアプリケーションを構築し、routesを通して画面間でデータを渡す方法を調べます。 基本的なFlutterのシリーズのこの記事まで、主に単一画面のアプリを中心に説明してきました。 マルチスクリーンアプリケーションの構築を熱心に待っていれば、この記事が役に立ちます!  アプリケーションにマルチスクリーンを追加して、画面遷移する方法を見ていきます。 また、widget間でデータを渡す方法についても説明します。 このテーマについて詳しく見ていきましょう! App Demoによるガイダンス 以下では、作成するサンプルアプリケーションの概要です: ご存知のとおり、このアプリケーションには2つの画面があり、この画面から別の画面にデータを渡したい場合はどのように構築できるか見てみましょう!  The First Screen(最初の画面) 以下は、このアプリケーションで使用する最初の画面のsnapshot codeです。別のファイル(first_screen.dart)に別のWidgetを書き込み、後でmain.dartファイルにインポートします。これは、コードの量を減らし、メンテナンスを容易にし、パフォーマンスを最適化しできます。 FirstScreenがstateless widgetであることがわかります。 概要では、appBarとBodyセクションを含むScaffoldがあります。 Bodyセクションには、コラムWidget(Widgetがコラムでビューを表示する)があり、コラムの子Widgetは、それぞれSizedBox、Text、およびElevatedButtonです。Raised Buttonをクリックすると、ナビゲーターは2番目の画面を最初の画面の上部に2番目の画面の識別子名(named route)で遷移します。 これについては後でもっと説明します。 ナビゲートしたい画面をFlutterに認識させるために、その画面の名前に通して遷移します。 したがって、この画面を使用することを宣言するところでsecond_screen.dartをインポートする必要があります。 注意:ナビゲートする必要のある各画面(各scaffold widgetは個別の画面として見なされます)には、固有の識別子が必要です。 ここでは、両方の画面でstatic constとしてrouteNameを定義しました。 The second screen (2番目の画面)  別のsecond_screen.dartで宣言された2番目の画面には、次のコードが含まれています。 このWidgetのコード構造は基本的に最初の画面と同じですが、ボタンが1つ追加されます。 ここでは、ナビゲートする必要がある画面をrouteName定数でナビゲートできるように、first_screen.dartをインポートします。 2番目のボタンは TextButtonです。FlatButton がpop()メソッドで最初の画面に遷移するために使用されます。 pop()メソッドは、スタックからWidget/トップ画面を削除するだけです。 これについては、さらに詳しく説明します。 main.darrt ファイル ナビゲーションの設定はまだ完了していません。 また、main.dartファイルには、MaterialAppWidgetにあるすべての画面のルートを登録する必要があります。 main.dartファイルにfirst_screen.dartウィジェットとsecond_screen.dartウィジェットの両方をインポートしたことがわかります。 デフォルトのルートページでは:アプリが起動される時にinitialwidget/screenとしてFirstScreen()を使用しています。 また、アプリケーションの最上位のroutesについて説明したと気付いたこともあります。 マルチスクリーンの場合は、ここですべてのスクーンを登録する必要があります。 上記のようなroutesを宣言する必要がある理由 FlutterでNavigatorの動作は、対応する多くのルートのマップで名前付きルート名(route)を検索するようなものです。 名前が有効な場合、builder(){…}メソッドが連結されます。つまり、WidgetBuilderを使用して、Flutterアプリで画面ナビゲーション操作を実行するMaterialPageRouteを作成します。 route nameにstatic constを使用するのはなぜでしょうか? アプリの外部のrouteテーブルで名前を直接宣言してから、その値を使用して、ナビゲーションすることで、 route

Read More

Flutterの基本:最初のアプリプログラミング(第一部)

Flutterは、モバイルだけでなく、Web、組込システム、デスクトップアプリなどの他のプラットフォームでも開発が益々進んでいます。Flutterを学ぶ時間が現在限りです。! 最初のアプリの作成を開始する事より良いことは何ですか?それでは、すぐに始めましょう! 環境設定 この投稿シリーズでは、EditorとしてVisual Studio Codeを使用しています。どんなeditorでも使用できます。Flutter SDKがPCにインストールされていることを確認しましょう。また、Emulatorまたは任意のAndroidデバイスでアプリを実行出来るようにAndroid Studioをインストールする必要があります。macOSを使用している場合は、iOSシミュレーターまたは実際のiOSデバイスでFlutterアプリを実行するようにXCodeを設定することもできます。 我々のデモアプリ ここでは、Flutterとそのwidgetのいくつかにすばやく慣れるために、デモシングルページアプリケーション(単一画面のアプリ)を構築します。デモアプリは次のようになります、 これは、アプリバーとボタンにテキストを表示するために構築するとても簡単なアプリです。ボタンをクリックすると、背景色が変わります。 アプリの初期化 新しいアプリケーションを初期化するには、terminal/consoleでディレクトリパスを指定し、以下のコマンドを使用します、 または、Android StudioまたはVS Codeコマンドパレットから新しいFlutterプロジェクトを作成することもできます。 プロジェクトフォルダの構造 最初のアプリの作成を開始する前にプロジェクトフォルダの構造をざっと目を通しておきましょう。 フォルダー「android」 このフォルダーには、Androidアプリケーションのすべてのプロジェクトファイルがあります。ここで変更を加えたり、必要な権限とAndroidのネイティブコードを追加したりできます。 フォルダー「build」 このフォルダーには、アプリバンドル、apkファイル、その他の関連ファイルやフォルダーなど、コンパイルされたすべての出力が含まれます。 フォルダー「ios」 このフォルダーには、iOSアプリのすべてのネイティブコードがあります。androidフォルダーと同様に、ここで必要な権限を追加し、iOSのネイティブコードを追加できます。 フォルダー「lib」 libフォルダーに、main.dartファイルがあります。 このフォルダーに記述されているすべてのdartコードは、コンパイル時にネイティブプラットフォームコード(ネイティブAndroidとiOS)にコンパイルされます。 フォルダー「test」 このフォルダーには、Flutterアプリケーションのunit testを記述できます。 ファイル「.gitignore」 プロジェクトのバージョン管理システム(version control)としてGITを使用している場合は、このファイルに精通していると思います。 GITに制御させたくない、変更を追跡させたくないファイルとフォルダーは、このファイルで宣言されます。 ファイル「pubspec.lock」と「pubspec.yaml」 このファイルには、必要なすべてのパッケージ名、それのバージョン、内容へのリンク、ディペンデンシーズ、アプリ名、アプリのバージョン、アプリのディペンデンシーズなどが含まれています。 ファイル「README」 これは、アプリケーションに関するすべての基本情報と記述を含むマークダウンファイルです。 エミュレーター/実際のデバイスでアプリを実行します アプリを実行するには、既存のAndroidエミュレーターまたはiOSエミュレーターを作成または開いてみてましょう。ibフォルダーとmain.dartファイルを開き、F5を押してアプリケーションを実行します。 VSコードエディターにflashingとdartの拡張機能がインストールされている場合は、main.dartファイルのvoid main()関数にマウスオーバーするとRun | Debugオプションが表示されます。  アプリを実行すると、基本的なFlutterアプリが自動的に生成されます。 main.dartファイルは、Flutterアプリケーションのエントリポイントです。 いかなるFlutterアプリケーションの実行は、void main(){…}から始まります。 これから、すべてを削除して、アプリケーションを最初から始めましょう。 アプリケーションをビルドします。 main.dartファイルのコードを削除しました。 次のようにアプリの作成を再開しましょう。 パッケージのインポート まず、必要なパッケージをインポートする必要があります。このアプリケーションでは、Flutterに提供されるmaterialパッケージが必要です。すべてのウィジェットと関数は、このパッケージに基づいて構築されています。 次のコマンドでこのパッケージをインポートできます。 アプリケーションで他のパッケージを追加する必要がある場合、コマンドは上記と同じ、パッケージ名を変更するだけです。 ここまで第一部は終わりです。この記事の第二部でお会いしましょう!

Read More

基本的なFlutter:Dartについて理解する (第一部)

より複雑なロジックコードを書けるプログラミング言語であるDartの基本を調べましょう。 変数とデータ型 Dartは、静的にデータ型(static typed)を持つオブジェクトを向く言語です。初期化の時に値が割り当てられていない変数はデフォルトでnull値があります。変数を宣言する時、またはプログラミングの何時でも、変数にnull値を割り当てることもできます。  基本的なデータ型 int, double, bool, String はDartの基本的なデータ型です。変数の存続期間中は、最初に定義されたデータ型でのみ使用されます。異なるデータ型を割り当てようとすると、コンパイルエラーが発生します。 infinity値はdouble classのstaticプロパティであり、double.infinityを使用してアクセスできます。 Varキーワード  var型で宣言された変数に任意の値を割り当てることができ、Dartは初期化値からデータを自動的に推論します。 型推論(Type-inference)はDartの組み込み機能です。 Num データ型 numキーワードはdartの中にもあり、intとdoubleの両方を持つ変数を作成できます。 ユースケースは、変数がいつでもint型またはdouble型の値を保持できる場合です。 文字列 (String) 文字列は、Javascriptと同様に、一重引用符‘ ‘または二重引用符 ” “を使用して宣言できます。 一重引用符”’または二重引用符“でも1行を複数行のコードに分割することもできます。 動的データ型(dynamic) dynamicキーワードを使用してdynamic変数を明示的に宣言することができます。又は、データ型が明示的に宣言されていない場合にdartで自動的に割り当てることができます。 注意 常にdynamicデータ型を注意して使用し、できるだけ頻繁にデータ型を明示的に宣言してください。 そうしないと、コードにバグが発生する可能性があります。 注意:自分が何をしているかがよくわかっている場合だけにdynamicを使用します。 機能 (function) Dartはtyped languageです。つまり、Dartの中に(関数も含む)何でも型(type)があります。 以下のmain関数の例を参照しましょう。 Main関数 この関数の戻り型はvoidです。 Dartは、アプリの起動時に自動的にmain(){…}を呼び出します。 これは、このmain関数が呼び出されたときに実施される単純なforループです。 一般に、任意の関数に任意の名前を付けることができますが、mainはDartアプリの起動点であるため、特別な名前です。 注意 関数に名前を付けるには、camel-caseの規則に従う必要があります。つまり、yourFunctionName(){}です。 関数(function)の使い方 関数の機能を確定する 以上の説明の通りに、camel-caseで関数を定義し、名前を付けることができます。 関数から値を返す場合は、関数の戻り型を宣言する必要があります。 強行ではありませんが、実行しない場合、Dartはエラーを出さずに警告を表示するとともに実行します。 戻り型がある場合と戻り型がない場合の関数のこの例を見てみましょう。 これから、最初の関数addTwoNumbers(…){…}について考えてみましょう。 この関数には、明示的に宣言された戻り型と引数型はありません。 それで、以下のようにDartは語法を解析し、この関数を実施します。 Dartは、dynamic型を関数と引数に自動的に割り当てます。 この関数の引数としてどんなデータ型を渡すことができ、dartはそれを追加しようとします。 ただし、この関数宣言する方法はエラーが発生しやすくなります。理由はint型とbool型を追加できる時に、コンパイルエラーではなく、ランタイムエラーが発生します! 2番目の関数void addTwoIntegerNumbers(int num1, int

Read More