Saat papan tombol muncul, ukuran widget Flutter berubah. Bagaimana cara mencegahnya?

101

Saya memiliki Kolom widget yang Diperluas seperti ini:

 return new Container(
      child: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          new Expanded(
            flex: 1,
            child: convertFrom,
          ),
          new Expanded(
            flex: 1,
            child: convertTo,
          ),
          new Expanded(
            flex: 1,
            child: description,
          ),
        ],
      ),
    );

Ini terlihat seperti ini:

masukkan deskripsi gambar di sini

convertFrom, termasuk TextField. Saat saya mengetuk bidang teks ini, papan ketik Android muncul di layar. Ini mengubah ukuran layar, jadi widget berubah ukuran seperti ini:

masukkan deskripsi gambar di sini

Adakah cara agar keyboard "menghamparkan" layar sehingga ukuran Kolom saya tidak berubah? Jika saya tidak menggunakan Expandedwidget dan hardcode a height untuk setiap widget, widget tidak berubah ukurannya, tetapi saya mendapatkan kesalahan bergaris hitam-kuning saat keyboard muncul (karena tidak ada cukup ruang). Ini juga tidak fleksibel untuk semua ukuran layar.

Saya tidak yakin apakah ini khusus Android atau khusus Flutter.

Mary
sumber
Dalam tubuh Scaffold Anda, gunakan SingleChildScrollView.
linhadiretalipe

Jawaban:

263

Di Anda Scaffold, setel resizeToAvoidBottomInsetproperti ke false.

Properti "resizeToAvoidBottomPadding" sekarang tidak digunakan lagi .... Di Scaffold, setel resizeToAvoidBottomPaddingproperti ke false.

aziza
sumber
11
Adakah cara untuk menghasilkan efek serupa android:windowSoftInputMode="adjustPan"? Jika saya menambahkan resizeToAvoidBottomPaddingke perancah itu akhirnya menutupi BidangTeks.
Epicality
2
Saya tidak tahu tentang android, tetapi umumnya praktik yang baik untuk membungkus tata letak Anda di dalam ListView dalam kasus ini
aziza
@aziza, saya mengalami masalah yang sama tetapi setelah solusi Anda berfungsi dengan baik, tetapi ada masalah lain, silakan periksa video dari tautan Gambar berkedip saat keyboard muncul. dropbox.com/s/lian92mnzz8kv9w/FlutterIssue1.mov?dl=0
Kishan Vyas
@KishanVyas sama dengan saya gambar hilang.
stuckedoverflow
@aziza Jawaban solid
Val
27

Sebagian besar jawaban lain menyarankan penggunaan resizeToAvoidBottomPadding=false. Dalam pengalaman saya, ini memungkinkan keyboard untuk menutupi bidang teks jika mereka berada di bawah tempat keyboard akan muncul.

Solusi saya saat ini adalah memaksa kolom saya memiliki tinggi yang sama dengan layar, lalu menempatkannya SingleChildScrollViewsedemikian rupa sehingga Flutter secara otomatis menggulung layar saya ke atas cukup saat keyboard digunakan.

Widget build(BuildContext context) {
  return Scaffold(
    body: SingleChildScrollView(
      physics: NeverScrollableScrollPhysics(),
      child: ConstrainedBox(
        constraints: BoxConstraints(
          minWidth: MediaQuery.of(context).size.width,
          minHeight: MediaQuery.of(context).size.height,
        ),
        child: IntrinsicHeight(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              // CONTENT HERE
            ],
          ),
        ),
      ),
    ),
  );
}

Saya menggunakan NeverScrollableScrollPhysicsagar pengguna tidak dapat menggulir sendiri.

Duncan Jones
sumber
2
Saya mencoba cara Anda tanpa NeverScrollableScrollPhysicsdan semua terlihat baik-baik saja kecuali pengguna dapat mencoba untuk menggesek ke atas dan ke bawah dan mereka dapat melihat cahaya overscroll. Ketika saya menggunakannya, NeverScrollableScrollPhysicsitu memberi saya perilaku yang sama sepertiresizeToAvoidBottomInset
Sajad Jaward
Setel properti utama ke false.
VLXU
16

Setel resizeToAvoidBottomInsetke falsealih-alih resizeToAvoidBottomPaddingyang tidak digunakan lagi.

    return Scaffold(
      resizeToAvoidBottomInset : false,
      body: YourWidgets(),
    );
ArtiomLK
sumber
Bagaimana jawaban ini berbeda dari yang diterima?
Ojonugwa Jude Ochalifu
2
Mereka adalah jawaban yang sama @Ojonugwa, mungkin editor memperbarui jawaban yang diterima setelah saya memposting milik saya jadi sekarang perbedaannya adalah milik saya menyertakan contoh?
ArtiomLK
4

Metode 1: Hapus android:windowSoftInputMode="adjustResize"dari file AndroidManifest.xml (Jika tidak, kode flutter akan diganti) dan tambahkan resizeToAvoidBottomPadding: falseScaffold seperti di bawah ini:

Scaffold(
      resizeToAvoidBottomPadding: false,
      appBar: AppBar()
)

Metode 2 (Tidak Direkomendasikan): Cukup Tambahkan android:windowSoftInputMode="stateVisible"di Android AndroidManifest.xml dalam aktivitas itu hanya akan bekerja untuk Android dan Bukan untuk iOS seperti.

<activity
       ...
        android:windowSoftInputMode="stateVisible">

Catatan: Jangan setel keandroid:windowSoftInputMode="adjustResize"

yatin deokar
sumber
4

Menurut saya, jika kita menerapkan solusi @ Aman, itu akan membuat aplikasi kita berperilaku jelek seperti ketika keyboard muncul, itu tidak akan menyesuaikan viewport layar kita sesuai ketinggian yang tersedia dan itu akan membuat bidang lain bersembunyi di balik keyboard. Jadi saya akan menyarankan penggunaan SingleChildScrollViewsebagai gantinya.

Bungkus kode Anda dengan SingleChildScrollViewseperti yang diberikan di bawah ini,

 return new Container(
  child: SingleChildScrollView(
    child: new Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[
      new Expanded(
        flex: 1,
        child: convertFrom,
      ),
      new Expanded(
        flex: 1,
        child: convertTo,
      ),
      new Expanded(
        flex: 1,
        child: description,
      ),
    ],
  ),
 ),
);
Deepak Jha
sumber
2

Tergantung pada kasus penggunaan Anda juga bisa mempertimbangkan menggunakan ListView . Itu akan memastikan bahwa konten bergulir ketika tidak ada cukup ruang. Sebagai contoh, Anda dapat melihat demo textfield di aplikasi galeri

aptik
sumber
4
Namun ini tetap tidak membuat BidangTeks yang Anda pilih menjadi terlihat, keyboard masih akan tumpang tindih. Anda harus menggulirnya sendiri. Tidak digunakan sebagai pengembang / pengguna Android
Boy
2

Pendekatan saya adalah dengan menggunakan SingleChildScrollViewdengan ClampingScrollPhysicsfisika.

SingleChildScrollView(
  physics: ClampingScrollPhysics(),
  child: Container(),
)
Sarang
sumber
1

Bagi saya mengubah properti item di bawah ini dari true menjadi false

<item name="android:windowFullscreen">false</item>

dalam file

android/app/src/main/res/values/styles.xml

telah membuat Flutter menyeret semua konten halaman ke atas pada fokus masukan

Flutter seret semua konten halaman ke atas pada fokus input

javeedishaq
sumber
0

Saran saya adalah resizeToAvoidBottomInset: falsetetap menggunakannya untuk mencegah widget berubah ukuran jika keyboard tiba-tiba muncul di layar. Misalnya, jika pengguna menggunakan kepala obrolan Facebook saat berada di aplikasi Anda.

Untuk mencegah keyboard dari overlay widget, pada layar di mana Anda membutuhkannya, saya menyarankan pendekatan berikut, di mana ketinggian SingleChildScrollViewdikurangi menjadi ketinggian ruang yang tersedia. Dalam hal ini, SingleChildScrollViewgulir juga ke widget yang difokuskan.

final double screenHeight = MediaQuery.of(context).size.height;
final double keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
return Scaffold(
  resizeToAvoidBottomInset: false,
  body: SizedBox(
    height: screenHeight - keyboardHeight,
    child: SingleChildScrollView(
      child: Column(
        children: [
          const SizedBox(height: 200),
          for (var i = 0; i < 10; i++) const TextField()
        ],
      ),
    ),
  ),
);
birca123
sumber