Kích thước các yếu tố theo tỷ lệ phần trăm chiều rộng / chiều cao màn hình


153

Có cách nào đơn giản (không phải là LayoutBuilder) để định kích thước cho một phần tử so với kích thước màn hình (chiều rộng / chiều cao) không? Ví dụ: làm cách nào để đặt chiều rộng của CardView là 65% chiều rộng màn hình.

Nó không thể được thực hiện bên trong buildphương thức (rõ ràng) vì vậy nó sẽ phải được hoãn lại cho đến khi xây dựng bài. Có một nơi ưa thích để đặt logic như thế này?


Chỉ cần nói, điều này thường không tốt IMO, đó là công cụ thiết kế web. Trong các ứng dụng, bạn thường nên sử dụng pixel thiết bị để xác định kích thước và sử dụng Paddings để chèn các widget của mình, vì tỷ lệ khung hình của bạn hầu như luôn giống nhau (ngoại trừ máy tính bảng).
leodriesch

7
Sau 1,5 năm nữa, có vẻ như đây không phải là một ý tưởng tồi. Mỗi tháng có những chiếc điện thoại mới ra mắt với tỷ lệ khung hình weirder và weirder.
Farid

Câu trả lời:


156

FractionallySizedBoxcũng có thể hữu ích Bạn cũng có thể đọc chiều rộng màn hình trực tiếp ra MediaQuery.of(context).sizevà tạo một hộp có kích thước dựa trên đó

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

nếu bạn thực sự muốn kích thước như một phần của màn hình bất kể bố cục là gì.


202

Đây là một câu trả lời bổ sung cho thấy việc thực hiện một vài giải pháp được đề cập.

FractionallySizedBox

Nếu bạn có một widget duy nhất, bạn có thể sử dụng một FractionallySizedBoxwidget để chỉ định tỷ lệ phần trăm không gian có sẵn để điền vào. Ở đây, màu xanh lá cây Containerđược đặt để lấp đầy 70% chiều rộng có sẵn và 30% chiều cao có sẵn.

FractionallySizedBox

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

Mở rộng

Các Expandedwidget cho phép một widget lấp đầy không gian có sẵn, theo chiều ngang nếu nó nằm trong một hàng hoặc theo chiều dọc nếu nó nằm trong một cột. Bạn có thể sử dụng flextài sản với nhiều vật dụng để cung cấp cho chúng trọng lượng. Ở đây màu xanh Containerchiếm 70% chiều rộng và màu vàng Containerchiếm 30% chiều rộng.

Mở rộng

Nếu bạn muốn làm theo chiều dọc, sau đó chỉ cần thay thế Rowbằng Column.

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

Mã bổ sung

Đây là main.dartmã để bạn tham khảo.

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
Đó là cách bạn viết câu trả lời StackOverflow! Cảm ơn bạn! Giúp tôi với Dialogphong cách của mình :)
Aleksandar

116

Điều này có thể rõ ràng hơn một chút:

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

double yourWidth = width * 0.65;

Hy vọng điều này giải quyết vấn đề của bạn.


16

Bạn có thể xây dựng Cột / Hàng với trẻ em linh hoạt hoặc mở rộng có giá trị flex cộng với tỷ lệ phần trăm bạn muốn.

Bạn cũng có thể thấy tiện ích AspectRatio hữu ích.



9

Có nhiều cách để làm điều này

1. Sử dụng MediaQuery: Nó trả lại toàn màn hình cho thiết bị của bạn bao gồm thanh ứng dụng, thanh công cụ

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

nhập mô tả hình ảnh ở đây


2. Sử dụng Mở rộng: Bạn có thể đặt tỷ lệ chiều rộng / chiều cao

 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],
              ),
            )
          ],
        ),
    )

nhập mô tả hình ảnh ở đây



3. Những người khác thích Linh hoạtAspectRatioFractionallySizedBox


7

bạn có thể sử dụng MediaQuery với ngữ cảnh hiện tại của tiện ích con của bạn và nhận được chiều rộng hoặc chiều cao như thế này double width = MediaQuery.of(context).size.width double height = MediaQuery.of(context).size.height sau đó, bạn có thể nhân nó với tỷ lệ phần trăm bạn muốn


7

Đầu tiên có được kích thước của màn hình.

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

Sau này, bạn có thể lấy widthvà nhân nó với 0.550% chiều rộng màn hình.

double width50 = size.width * 0.5;

Nhưng vấn đề thường xuất hiện height, theo mặc định khi chúng ta sử dụng

double screenHeight = size.height;

Chiều cao chúng ta có được là chiều cao toàn cầu bao gồm StatusBar+ notch+ AppBarchiều cao. Vì vậy, để có được chiều cao bên trái của thiết bị, chúng ta cần trừ paddingchiều cao ( StatusBar+ notch) và AppBarchiều cao so với tổng chiều cao. Đây là cách chúng tôi làm điều đó.

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

Bây giờ chúng ta có thể sử dụng theo sau để có được 50% chiều cao màn hình của chúng tôi.

double height50 = leftHeight * 0.5

3

nếu bạn đang sử dụng GridView, bạn có thể sử dụng một cái gì đó như giải pháp của Ian Hickson.

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

2

Sử dụng Widget LayoutBuilder sẽ cung cấp cho bạn các ràng buộc mà bạn có thể sử dụng để có được chiều cao loại trừ AppBar và phần đệm. Sau đó, sử dụng SizedBox và cung cấp chiều rộng và chiều cao bằng cách sử dụng các ràng buộc từ LayoutBuilder

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.