要素のサイズを画面の幅/高さの割合に合わせる


153

画面サイズ(幅/高さ)を基準に要素のサイズを変更する簡単な(LayoutBuilder以外の)方法はありますか?たとえば、CardViewの幅を画面の幅の65%に設定するにはどうすればよいですか。

buildメソッド内では(明らかに)実行できないため、ビルド後まで延期する必要があります。このようなロジックを配置するのに適した場所はありますか?


ただ言っておくと、これは一般的に良いプラクティスIMOではありません。それはWebデザインに関するものです。アプリでは、アスペクト比はほぼ同じであるため(タブレットを除く)、通常はデバイスピクセルを使用してサイズを定義し、パディングを使用してウィジェットを挿入する必要があります。
leodriesch

7
さらに1.5年後、結局これはそれほど悪い考えではないようです。毎月、奇妙な奇妙なアスペクト比で新しい電話が出ています。
ファリッド

回答:


156

FractionallySizedBoxも役に立つかもしれません。画面の幅を直接読み取って、MediaQuery.of(context).sizeそれに基づいてサイズのボックスを作成することもできます

MediaQuery.of(context).size.width * 0.65

レイアウトとは関係なく、本当に画面の一部としてサイズを設定したい場合。


202

これは、言及されたソリューションのいくつかの実装を示す補足的な回答です。

FractionallySizedBox

ウィジェットが1つしかない場合は、ウィジェットを使用してFractionallySizedBox、使用可能なスペースの割合を指定して埋めることができます。ここで、グリーンContainerは、利用可能な幅の70%と利用可能な高さの30%を満たすように設定されています。

FractionallySizedBox

Widget myWidget() {
  return FractionallySizedBox(
    widthFactor: 0.7,
    heightFactor: 0.3,
    child: Container(
      color: Colors.green,
    ),
  );
}

拡張

Expandedウィジェットを使用すると、ウィジェットは使用可能なスペースを埋めることができます。ウィジェットが行にある場合は水平に、列にある場合は垂直に配置できます。flex複数のウィジェットでプロパティを使用して、ウィジェットに重みを付けることができます。ここでは、グリーンContainerは幅の70%を占め、イエローContainerは幅の30%を占めています。

拡張

あなたが垂直方向にそれをしたい場合は、単に置き換えるRowColumn

Widget myWidget() {
  return Row(
    children: <Widget>[
      Expanded(
        flex: 7,
        child: Container(
          color: Colors.green,
        ),
      ),
      Expanded(
        flex: 3,
        child: Container(
          color: Colors.yellow,
        ),
      ),
    ],
  );
}

補足コード

ここmain.dartにあなたの参照のためのコードがあります。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("FractionallySizedBox"),
        ),
        body: myWidget(),
      ),
    );
  }
}

// replace with example code above
Widget myWidget() {
  return ...
}

4
それがStackOverflowの答えを書く方法です!ありがとうございました!私のDialogスタイリングを手伝ってくれました:)
Aleksandar

116

これはもう少し明確かもしれません:

double width = MediaQuery.of(context).size.width;

double yourWidth = width * 0.65;

これで問題が解決したと思います。




9

これを行うには多くの方法があります

1. MediaQueryの使用: appbar、toolbarを含むデバイスの全画面を返します

 Container(
        width: MediaQuery.of(context).size.width * 0.50,
        height: MediaQuery.of(context).size.height*0.50, 
        color: Colors.blueAccent[400],
 )

ここに画像の説明を入力してください


2. Expandedの使用:幅/高さを比率で設定できます

 Container(
        height: MediaQuery.of(context).size.height * 0.50,
        child: Row(
          children: <Widget>[
            Expanded(
              flex: 70,
              child: Container(
                color: Colors.lightBlue[400],
              ),
            ),
            Expanded(
              flex: 30,
              child: Container(
                color: Colors.deepPurple[800],
              ),
            )
          ],
        ),
    )

ここに画像の説明を入力してください



3. FlexibleAspectRatioFractionallySizedBoxなどの その他の機能


7

ウィジェットの現在のコンテキストでMediaQueryを使用し、 double width = MediaQuery.of(context).size.width double height = MediaQuery.of(context).size.height その後このように幅または高さを取得し、必要な パーセンテージを掛けることができます


7

最初に画面のサイズを取得します。

Size size = MediaQuery.of(context).size;

この後、それを取得widthして乗算すると0.5、画面幅の50%を取得できます。

double width50 = size.width * 0.5;

しかしheight、一般的に問題が発生します。デフォルトでは、

double screenHeight = size.height;

取得される高さは、StatusBar+ notch+ AppBar高さを含むグローバルな高さです。したがって、デバイスの左側の高さを取得するには、全高からpadding高さ(StatusBar+ notch)とAppBar高さを引く必要があります。これが私たちのやり方です。

double abovePadding = MediaQuery.of(context).padding.top;
double appBarHeight = appBar.preferredSize.height;
double leftHeight = screenHeight - abovePadding - appBarHeight;

これで、以下を使用して画面の高さを50%取得できます。

double height50 = leftHeight * 0.5

3

GridViewを使用している場合は、Ian Hicksonのソリューションのようなものを使用できます。

crossAxisCount: MediaQuery.of(context).size.width <= 400.0 ? 3 : MediaQuery.of(context).size.width >= 1000.0 ? 5 : 4

2

AppBarとパディングを除く高さを取得するために使用できる制約を与えるLayoutBuilderウィジェットを使用します。次に、SizedBoxを使用し、LayoutBuilderの制約を使用して幅と高さを指定します

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.