Elemen ukuran untuk persentase lebar / tinggi layar

154

Apakah ada cara sederhana (non-LayoutBuilder) untuk mengukur elemen relatif terhadap ukuran layar (lebar / tinggi)? Sebagai contoh: bagaimana cara mengatur lebar CardView menjadi 65% dari lebar layar.

Itu tidak dapat dilakukan di dalam buildmetode (jelas) sehingga harus ditunda sampai posting dibangun. Apakah ada tempat yang disukai untuk menempatkan logika seperti ini?

Luke
sumber
Hanya mengatakan, ini umumnya bukan praktik yang baik IMO, itu hal-hal desain web. Dalam aplikasi, Anda biasanya harus menggunakan piksel perangkat untuk menentukan ukuran, dan menggunakan Paddings untuk menyisipkan widget Anda, karena rasio aspek Anda hampir selalu sama (kecuali untuk tablet).
leodriesch
7
Setelah 1,5 tahun, sepertinya ini bukan ide yang buruk. Setiap bulan ada ponsel baru yang keluar dengan rasio aspek lebih aneh dan lebih aneh.
Farid

Jawaban:

156

FractionallySizedBoxsemoga bermanfaat juga. Anda juga dapat membaca lebar layar langsung dari MediaQuery.of(context).sizedan membuat kotak berukuran berdasarkan itu

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

jika Anda benar-benar ingin ukuran sebagai sebagian kecil dari layar terlepas dari apa tata letaknya.

Ian Hickson
sumber
203

Ini adalah jawaban tambahan yang menunjukkan implementasi beberapa solusi yang disebutkan.

Kotak pecahan

Jika Anda memiliki satu widget, Anda dapat menggunakan FractionallySizedBoxwidget untuk menentukan persentase ruang yang tersedia untuk diisi. Di sini hijau Containerdiatur untuk mengisi 70% dari lebar yang tersedia dan 30% dari tinggi yang tersedia.

Kotak pecahan

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

Diperluas

The Expandedwidget memungkinkan widget untuk mengisi ruang yang tersedia, horizontal jika berturut-turut, atau vertikal jika berada dalam kolom. Anda dapat menggunakan flexproperti dengan beberapa widget untuk memberi mereka bobot. Di sini hijau Containermengambil 70% dari lebar dan kuning Containermengambil 30% dari lebar.

Diperluas

Jika Anda ingin melakukannya secara vertikal, maka ganti saja Rowdengan Column.

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

Kode tambahan

Ini main.dartkode untuk referensi Anda.

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 ...
}
Suragch
sumber
4
Itulah cara Anda menulis jawaban StackOverflow! Terima kasih! Membantu saya dengan Dialogpenataan rambut saya :)
Aleksandar
116

Ini mungkin sedikit lebih jelas:

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

double yourWidth = width * 0.65;

Semoga ini menyelesaikan masalah Anda.

Keshav Aditya RP
sumber
16

Anda dapat membuat Kolom / Baris dengan anak Fleksibel atau Diperluas yang memiliki nilai fleksibel yang menambahkan hingga persentase yang Anda inginkan.

Anda juga dapat menemukan widget AspectRatio berguna.

Collin Jackson
sumber
9
MediaQuery.of(context).size.width
Nitin Mehta
sumber
9

Ada banyak cara untuk melakukan ini

1. Menggunakan MediaQuery: Ini mengembalikan layar penuh perangkat Anda termasuk appbar, toolbar

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

masukkan deskripsi gambar di sini


2. Menggunakan Expanded: Anda dapat mengatur rasio lebar / tinggi

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

masukkan deskripsi gambar di sini



3. Lainnya Suka Fleksibel dan AspectRatio dan FractionallySizedBox

Sanjayrajsinh
sumber
7

Anda dapat menggunakan MediaQuery dengan konteks widget Anda saat ini dan mendapatkan lebar atau tinggi seperti ini double width = MediaQuery.of(context).size.width double height = MediaQuery.of(context).size.height setelah itu, Anda dapat mengalikannya dengan persentase yang Anda inginkan

parth jansari
sumber
7

Pertama, dapatkan ukuran layar.

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

Setelah ini, Anda bisa mendapatkan widthdan mengalikannya dengan 0.5untuk mendapatkan 50% dari lebar layar.

double width50 = size.width * 0.5;

Tapi masalah biasanya muncul height, secara default saat kita gunakan

double screenHeight = size.height;

Ketinggian yang kita dapatkan adalah ketinggian global yang mencakup ketinggian StatusBar+ notch+ AppBar. Jadi, untuk mendapatkan ketinggian kiri perangkat, kita perlu mengurangi paddingtinggi ( StatusBar+ notch) dan AppBartinggi dari tinggi total. Inilah cara kami melakukannya.

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

Sekarang kita bisa menggunakan berikut ini untuk mendapatkan tinggi layar 50%.

double height50 = leftHeight * 0.5
CopsOnRoad
sumber
3

jika Anda menggunakan GridView Anda dapat menggunakan sesuatu seperti solusi Ian Hickson.

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

Gunakan Widget LayoutBuilder yang akan memberi Anda batasan yang bisa Anda gunakan untuk mendapatkan ketinggian yang tidak termasuk AppBar dan padding. Kemudian gunakan SizedBox dan berikan lebar dan tinggi menggunakan batasan dari LayoutBuilder

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...
Nicolas
sumber