องค์ประกอบการปรับขนาดเป็นเปอร์เซ็นต์ของความกว้าง / ความสูงของหน้าจอ


153

มีวิธีง่าย ๆ (ไม่ใช่ LayoutBuilder) ในการกำหนดขนาดขององค์ประกอบที่สัมพันธ์กับขนาดหน้าจอ (ความกว้าง / ความสูง) หรือไม่? ตัวอย่างเช่น: ฉันจะตั้งค่าความกว้างของ CardView เป็น 65% ของความกว้างหน้าจอได้อย่างไร

ไม่สามารถทำได้ภายในbuildวิธีการ (ชัด) ดังนั้นจะต้องรอการตัดบัญชีจนกว่าจะสร้างโพสต์ มีสถานที่ที่ต้องการวางตรรกะเช่นนี้หรือไม่?


เพียงพูดโดยทั่วไปนี่ไม่ใช่วิธีปฏิบัติที่ดีของ IMO นั่นคือการออกแบบเว็บ ในแอพโดยทั่วไปคุณควรใช้พิกเซลอุปกรณ์เพื่อกำหนดขนาดและใช้ Paddings เพื่อแทรกวิดเจ็ตของคุณเนื่องจากอัตราส่วนกว้างยาวเกือบเท่าเดิม (ยกเว้นแท็บเล็ต)
leodriesch

7
หลังจากนั้นอีก 1.5 ปีดูเหมือนว่านี่ไม่ใช่ความคิดที่เลวร้าย ทุกเดือนจะมีโทรศัพท์ใหม่ออกมาพร้อมอัตราส่วน weirder และ weirder
Farid

คำตอบ:


156

FractionallySizedBoxอาจมีประโยชน์ นอกจากนี้คุณยังสามารถอ่านความกว้างของหน้าจอโดยตรงจากMediaQuery.of(context).sizeและสร้างกล่องขนาดขึ้นอยู่กับที่

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

ถ้าคุณต้องการปรับขนาดเป็นเศษส่วนของหน้าจอจริง ๆ โดยไม่คำนึงว่าเค้าโครงคืออะไร


202

นี่เป็นคำตอบเพิ่มเติมที่แสดงการใช้งานโซลูชันที่กล่าวถึงสองสามข้อ

FractionallySizedBox

หากคุณมีวิดเจ็ตเดียวคุณสามารถใช้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สไตล์ของฉัน:)
อเล็กซานดาร์

116

นี่อาจจะชัดเจนกว่านี้เล็กน้อย:

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

double yourWidth = width * 0.65;

หวังว่านี่จะช่วยแก้ปัญหาของคุณได้


16

คุณสามารถสร้างคอลัมน์ / แถวที่มีลูกที่ยืดหยุ่นหรือขยายได้ซึ่งมีค่าความยืดหยุ่นที่เพิ่มขึ้นตามเปอร์เซ็นต์ที่คุณต้องการ

คุณอาจพบว่าเครื่องมือAspectRatioมีประโยชน์



9

มีหลายวิธีในการทำเช่นนี้

1. การใช้ MediaQuery: ส่งคืนแบบเต็มหน้าจอของอุปกรณ์ของคุณรวมถึงแถบแอปแถบเครื่องมือ

 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. อื่น ๆ เช่นเดียวกับ ที่มีความยืดหยุ่นและ AspectRatioและFractionallySizedBox


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

ใช้วิดเจ็ต LayoutBuilder ที่จะให้ข้อ จำกัด ที่คุณสามารถใช้เพื่อรับความสูงที่ไม่รวม AppBar และ padding จากนั้นใช้ 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.