Khi bàn phím xuất hiện, các widget Flutter sẽ thay đổi kích thước. Làm thế nào để ngăn chặn điều này?


101

Tôi có một Cột tiện ích con được mở rộng như thế này:

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

Nó trông như thế này:

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

convertFrom, bao gồm một Trường văn bản. Khi tôi nhấn vào trường văn bản này, bàn phím Android sẽ xuất hiện trên màn hình. Thao tác này thay đổi kích thước màn hình, vì vậy các tiện ích con sẽ thay đổi kích thước như sau:

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

Có cách nào để bàn phím "phủ" màn hình để Cột của tôi không thay đổi kích thước không? Nếu tôi không sử dụng Expandedwidget và mã hóa cứng chiều cao cho mỗi widget, các widget sẽ không thay đổi kích thước, nhưng tôi gặp lỗi sọc đen vàng khi bàn phím xuất hiện (vì không có đủ dung lượng). Điều này cũng không linh hoạt cho tất cả các kích thước màn hình.

Tôi không chắc đây là thiết bị dành riêng cho Android hay dành riêng cho Flutter.


Trong phần thân Scaffold của bạn, hãy sử dụng SingleChildScrollView.
linhadiretalipe

Câu trả lời:


263

Trong của bạn Scaffold, hãy đặt thuộc resizeToAvoidBottomInsettính thành false.

Property "resizeToAvoidBottomPadding" bị phản đối tại .... Trong bạn Scaffold, bộ resizeToAvoidBottomPaddingtài sản để false.


11
Có cách nào để tạo ra một hiệu ứng tương tự android:windowSoftInputMode="adjustPan"? Nếu tôi thêm resizeToAvoidBottomPaddingvào giàn giáo, nó sẽ bao phủ TextField.
Epicality

2
Tôi không biết về Android, nhưng nó thường là một thói quen tốt để quấn bố trí của bạn bên trong một ListView trong trường hợp này
Aziza

@aziza, tôi cũng gặp phải vấn đề tương tự nhưng sau khi giải pháp của bạn hoạt động tốt, nhưng có một vấn đề khác, vui lòng kiểm tra video từ liên kết Hình ảnh nhấp nháy khi bàn phím xuất hiện. dropbox.com/s/lian92mnzz8kv9w/FlutterIssue1.mov?dl=0
Kishan Vyas

@KishanVyas same with me image đã biến mất.
kẹt lại dòng chảy

@aziza Câu trả lời chắc chắn
Val

29

Hầu hết các câu trả lời khác đề nghị sử dụng resizeToAvoidBottomPadding=false. Theo kinh nghiệm của tôi, điều này cho phép bàn phím che các trường văn bản nếu chúng nằm bên dưới nơi bàn phím xuất hiện.

Giải pháp hiện tại của tôi là buộc cột của tôi có cùng chiều cao với màn hình, sau đó đặt nó vào vị trí SingleChildScrollViewđể Flutter tự động cuộn màn hình của tôi lên vừa đủ khi bàn phím được sử dụng.

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

Tôi sử dụng NeverScrollableScrollPhysicsđể người dùng không thể cuộn quanh mình.


3
Tôi đã thử theo cách của bạn mà không có NeverScrollableScrollPhysicsvà tất cả đều ổn, ngoại trừ người dùng có thể thử vuốt lên và xuống và họ có thể thấy ánh sáng của cuộn tròn. Khi tôi sử dụng NeverScrollableScrollPhysicsnó mang lại cho tôi hành vi giống nhưresizeToAvoidBottomInset
Sajad Jaward

Đặt thuộc tính chính thành false.
VLXU

16

Đặt resizeToAvoidBottomInsetthành falsethay vì resizeToAvoidBottomPaddingkhông được dùng nữa.

    return Scaffold(
      resizeToAvoidBottomInset : false,
      body: YourWidgets(),
    );

Câu trả lời này khác với câu trả lời được chấp nhận như thế nào?
Ojonugwa Jude Ochalifu

2
Chúng là câu trả lời giống nhau @Ojonugwa, có lẽ người biên tập đã cập nhật câu trả lời được chấp nhận sau khi tôi đăng câu trả lời của tôi nên bây giờ sự khác biệt là của tôi bao gồm một ví dụ?
ArtiomLK

4

Phương pháp 1: Xóa android:windowSoftInputMode="adjustResize"khỏi tệp AndroidManifest.xml (Nếu không, nó sẽ ghi đè mã rung) và thêm resizeToAvoidBottomPadding: falsevào Scaffold như bên dưới:

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

Phương pháp 2 (Không được khuyến nghị): Chỉ cần Thêm android:windowSoftInputMode="stateVisible"vào android AndroidManifest.xml trong hoạt động, nó sẽ chỉ hoạt động cho Android chứ không phải cho IOS như.

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

Lưu ý: Không đặt nó thànhandroid:windowSoftInputMode="adjustResize"


4

Tôi nghĩ nếu chúng tôi triển khai giải pháp của @ Aman, nó sẽ khiến ứng dụng của chúng tôi hoạt động xấu xí như khi bàn phím xuất hiện, nó sẽ không điều chỉnh khung nhìn của màn hình theo chiều cao có sẵn và nó sẽ làm cho các trường khác ẩn sau bàn phím. Vì vậy, tôi sẽ đề nghị sử dụng SingleChildScrollViewthay thế.

Gói mã của bạn với SingleChildScrollViewnhư được cung cấp bên dưới,

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

2

Tùy thuộc vào trường hợp sử dụng bạn cũng có thể xem xét sử dụng một listview . Điều đó sẽ đảm bảo rằng nội dung cuộn khi không có đủ chỗ. Ví dụ: bạn có thể xem bản trình diễn trường văn bản trong ứng dụng thư viện


4
Nhưng điều này vẫn không làm cho TextField bạn chọn hiển thị, bàn phím vẫn sẽ chồng lên nó. Bạn phải tự mình cuộn nó. Không quen với tư cách là nhà phát triển / người dùng Android
Boy

2

Biện pháp của tôi là sử dụng SingleChildScrollViewvới ClampingScrollPhysicsvật lý.

SingleChildScrollView(
  physics: ClampingScrollPhysics(),
  child: Container(),
)

1

Đối với tôi thay đổi thuộc tính mục dưới đây từ đúng thành sai

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

trong tập tin

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

đã làm cho Flutter kéo tất cả nội dung trang lên trên tiêu điểm đầu vào

Flutter kéo tất cả nội dung trang lên trên tiêu điểm đầu vào


0

Đề xuất của tôi là sử dụng resizeToAvoidBottomInset: false để ngăn các widget thay đổi kích thước nếu bàn phím đột nhiên xuất hiện trên màn hình. Ví dụ: nếu người dùng sử dụng phần đầu trò chuyện trên Facebook khi ở trong ứng dụng của bạn.

Để ngăn bàn phím chồng lên các widget, trên các màn hình mà bạn cần, tôi đề xuất cách tiếp cận sau, trong đó chiều cao được SingleChildScrollViewgiảm xuống chiều cao của không gian khả dụng. Trong trường hợp này, SingleChildScrollViewcũng cuộn đến tiện ích con tập trung.

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()
        ],
      ),
    ),
  ),
);
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.