🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

2回答

2337閲覧

FractionallySizedBoxで「ボタンの高さ=画面の高さの◯%」にしたい

Risney

総合スコア148

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2020/12/23 08:12

前提・実現したいこと

「FractionallySizedBox」というウィジェットで画面の40%という比率でボタンのサイズを決めたい。

・ボタンのサイズが画面の40%
・ボタンの上下に画面の30%の余白スペース

該当のソースコード

flutter

1import 'package:flutter/material.dart'; 2 3void main() { 4 runApp( 5 MaterialApp( 6 home: MyWidget(), 7 ), 8 ); 9} 10 11class MyWidget extends StatelessWidget { 12 @override 13 Widget build(BuildContext context) { 14 return Scaffold( 15 appBar: AppBar( 16 title: Text('【Flutter#51】FractionallySizedBox'), 17 ), 18 body: Column( 19 children: <Widget>[ 20 Flexible( //ボタン上のスペース 21 child: FractionallySizedBox( 22 heightFactor: 0.30, //縦の30%のサイズ 23 ), 24 ), 25 Container( 26 alignment: Alignment.center, 27 child: FractionallySizedBox( 28 heightFactor: 0.40, //縦の40%のサイズ 29 widthFactor: 0.50, //幅の50%のサイズ 30 child: RaisedButton( 31 child: Text('Tap this button.\nConsole「OK」'), 32 onPressed: _onPressed, 33 )), 34 ), 35 Flexible( //ボタン下のスペース 36 child: FractionallySizedBox( 37 heightFactor: 0.30, //縦の30%のサイズ 38 ), 39 ), 40 ], 41 ), 42 ); 43 } 44} 45 46void _onPressed() { 47 print('OK'); 48} 49

発生している問題・エラーメッセージ

・BoxConstraints(w = 187.5、h = Infinity)
つまり高さが無限なのに対して40%を指定しているからエラーが出ていると認識しています。
では高さを指定するには…?

・上下に30%の余白をいれているはずが…
なぜか、上寄りになってしまう。
下の余白としていれた「FractionallySizedBox」を外すと
上部の余白の30%は適用される

Performing hot restart... Syncing files to device iPhone SE (2nd generation)... Restarted application in 770ms. ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ The following assertion was thrown during performLayout(): BoxConstraints forces an infinite height. These invalid constraints were provided to RenderSemanticsAnnotations's layout() function by the following function, which probably computed the invalid constraints in question: RenderFractionallySizedOverflowBox.performLayout (package:flutter/src/rendering/shifted_box.dart:960:13) The offending constraints were: BoxConstraints(w=187.5, h=Infinity) The relevant error-causing widget was: FractionallySizedBox file:///Users/aiueo/Desktop/flutter_app/lib/main.dart:27:20

和訳
ホットリスタートを実行しています...
ファイルをデバイスiPhoneSE(第2世代)に同期しています...
770msでアプリケーションを再起動しました。

==╡ライブラリのレンダリングによって引き起こされた例外╞========================================= ================
次のアサーションがperformLayout()中にスローされました。
BoxConstraintsは、無限の高さを強制します。
これらの無効な制約は、RenderSemanticsAnnotationsのlayout()関数に提供されました。
次の関数。おそらく問題の無効な制約を計算しました。
RenderFractionallySizedOverflowBox.performLayout
(package:flutter / src / rendering / shifted_box.dart:960:13)
問題のある制約は次のとおりです。
BoxConstraints(w = 187.5、h = Infinity)

関連するエラーの原因となるウィジェットは次のとおりです。
FractionallySizedBox file:///Users/aiueo/Desktop/flutter_app/lib/main.dart:27:20

試したこと

①ボタンの中「heightFactor: 0.40,」を外す
これをするとエラーはなくなりますが、
「ボタンサイズを画面の高さの40%にしていする」という結果が得られません。

②「Column」を外し、ウィジェット をボタンのみにする。
ボタンのみだとボタンが想定したサイズになります。

その他

これよりもっと良い方法あるよ!とか、
そもそもその使い方を想定したウィジェットじゃない!などの
ご指摘等もお待ちしておりますので宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんな感じでしょうか?是非一度実行してみてください。

flutter

1import 'package:flutter/material.dart'; 2 3void main() { 4 runApp( 5 MaterialApp( 6 home: MyWidget(), 7 ), 8 ); 9} 10 11class MyWidget extends StatelessWidget { 12 @override 13 Widget build(BuildContext context) { 14 return Scaffold( 15 appBar: AppBar( 16 title: Text('【Flutter#51】FractionallySizedBox'), 17 ), 18 body: Column( 19 mainAxisAlignment: MainAxisAlignment.center, 20 children: <Widget>[ 21 Flexible( 22 flex: 3, 23 child: FractionallySizedBox( 24 heightFactor: 1, 25 ), 26 ), 27 Flexible( 28 flex: 4, 29 child: Center( 30 child: FractionallySizedBox( 31 heightFactor: 1.0, 32 widthFactor: 0.50, 33 child: RaisedButton( 34 child: Text('Tap this button.\nConsole「OK」'), 35 onPressed: _onPressed, 36 )), 37 ), 38 ), 39 Flexible( 40 flex: 3, 41 child: FractionallySizedBox( 42 heightFactor: 1, 43 ), 44 ), 45 ], 46 ), 47 ); 48 } 49} 50 51void _onPressed() { 52 print('OK'); 53} 54

FractionallySizedBoxをRowやColumnで使う場合は、仰る通り高さを指定やる必要があるのですが、今回はその役目を、Flexibleに担当してもらっています。
Flexibleは僕が説明するよりもflutterチームが作ってくれた動画をみた方が遥かに分かりやすいと思うので、そちらを載せておきます。
Flexibleの動画

FractionallySizedBoxのheightFactorは、あくまでも自分が利用可能なスペースのうちの何%を使うか指定するものなので、今回FractionallySizedBoxが使えるスペースは、Flexibleでかなり制限されたのちのスペースということになります。

flutter

1 ①Flexible( 2 //10分の3 3 flex: 3, 4 child: FractionallySizedBox( 5 //10分の3 6 heightFactor: 0.3, 7 ), 8 ), 9 ②Flexible( 10 //10分の4 11 flex: 4, 12 child:.... 13 ), 14 ③Flexible( 15 //10分の3 16 flex: 3, 17 child:.... 18 ),

例えば、①のようにしてしまと、
3/(3+3+4) [flexibleでのflexが全体10のうちの3という意味です]✖︎ 0.3 ←heightFactorで、①はbodyの高さのうちの9%の高さとなることが予想されます。
(多分そうなります。間違えていたらすみません!)

今回の実装は、FractionallySizedBoxの他に、
MediaQueryで画面サイズを取ってきたり、SpacerとExpandedを組み合わせるなどの方法が考えられると思います。
是非一度調べてみてください。

投稿2020/12/23 13:00

flutter_labo

総合スコア110

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Risney

2021/03/20 04:12

返答遅くなってしまい申し訳ありません。 とてもご丁寧にありがとうございます! まずは「flex: ,」でFractionallySizedBox自体にサイズを与えて、 その与えたサイズの中で調整するのが「heightFactor」ってイメージですね! とても説明がわかりやすく、 理解することができました。 他の方法も時間があるときに試したたいと思います。 ありがとうございました!
guest

0

taiso.itsukages様のやり方に習い、
以下の方法で実現できました!
ありがとうございました!

dart

1import 'package:flutter/material.dart'; 2 3void main() { 4 runApp( 5 MaterialApp( 6 home: MyWidget(), 7 ), 8 ); 9} 10 11class MyWidget extends StatelessWidget { 12 13 Widget build(BuildContext context) { 14 return Scaffold( 15 appBar: AppBar( 16 title: Text('【Flutter#51】FractionallySizedBox'), 17 ), 18 body: Column( 19 children: <Widget>[ //↓画面の縦サイズからAppBarの高さを引かれている前提 20 Flexible( //ボタン上のスペース 21 flex: 3, //画面の縦の3割(※必須) 22 child: FractionallySizedBox( 23 heightFactor: 1.0, //使える高さの100%(※必須) 24 ), 25 ), 26 Flexible( 27 flex: 4, //画面の縦の4割(※必須) 28 child: Container( 29 alignment: Alignment.center, 30 child: FractionallySizedBox( 31 heightFactor: 1.0, //使える高さの縦の100%(※必須) 32 widthFactor: 0.60, //使える幅の60% 33 child: RaisedButton( 34 child: Text('Tap this button.\nConsole「OK」'), 35 onPressed: _onPressed, 36 )), 37 ) 38 ), 39 Flexible( //ボタン下のスペース 40 flex: 3, //画面の縦の3割(※必須) 41 child: FractionallySizedBox( 42 heightFactor: 1.0, //使える高さの縦の100%(※必須) 43 ), 44 ), 45 ], 46 ), 47 ); 48 } 49} 50 51void _onPressed() { 52 print('OK'); 53} 54 55

投稿2021/03/20 04:14

Risney

総合スコア148

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問