キーボードが表示されると、Flutterウィジェットのサイズが変更されます。これを防ぐ方法は?


113

私はこのような拡張ウィジェットの列を持っています:

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

次のようになります。

ここに画像の説明を入力してください

convertFrom、TextFieldが含まれます。このテキストフィールドをタップすると、Androidキーボードが画面に表示されます。これにより画面サイズが変更されるため、ウィジェットのサイズは次のようになります。

ここに画像の説明を入力してください

列のサイズが変更されないように、キーボードで画面を「オーバーレイ」する方法はありますか?Expandedウィジェットを使用せず、各ウィジェットの高さをハードコーディングすると、ウィジェットのサイズは変更されませんが、キーボードが表示されたときに黒と黄色の縞模様のエラーが発生します(十分なスペースがないため)。これは、すべての画面サイズに柔軟に対応できるわけではありません。

これがAndroid固有なのかFlutter固有なのかわかりません。


Scaffold本体で、SingleChildScrollViewを使用します。
linhadiretalipe

回答:


285

更新された回答

resizeToAvoidBottomPadding現在は非推奨です

更新された解決策は、resizeToAvoidBottomInsetプロパティをに設定することfalseです。


元の回答

ScaffoldresizeToAvoidBottomPaddingプロパティをに設定しますfalse


11
と同様の効果を生み出す方法はありますandroid:windowSoftInputMode="adjustPan"か?resizeToAvoidBottomPadding足場に追加すると、TextFieldをカバーすることになります。
エピカリティ2018年

3
androidについてはわかりませんが、この場合は、レイアウトをListView内にラップすることをお
勧めします

@aziza、私は同じ問題に苦しんでいましたが、あなたの解決後はうまくいきましたが、別の問題がありますリンクからのビデオを確認してくださいキーボードが表示されたときに画像が点滅しました。dropbox.com/s/lian92mnzz8kv9w/FlutterIssue1.mov?dl=0
Kishan Vyas

@KishanVyas私と同じ画像がなくなりました。
スタックオーバーフロー2018

@azizaソリッド答え
ヴァル

35

他のほとんどの回答は、の使用を提案していresizeToAvoidBottomPadding=falseます。私の経験では、これにより、キーボードが表示される場所の下にある場合、キーボードがテキストフィールドを隠すことができます。

私の現在の解決策は、列を画面と同じ高さに強制SingleChildScrollViewし、キーボードを使用したときにFlutterが画面を自動的に上にスクロールするように配置することです。

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

NeverScrollableScrollPhysicsユーザーが自分でスクロールできないようにするために使用します。


4
私はあなたのやり方をNeverScrollableScrollPhysics試してみましたが、ユーザーが上下にスワイプしてオーバースクロールの輝きを見ることができることを除いて、すべてうまく見えます。私がNeverScrollableScrollPhysicsそれを使うとき、それは私に同じ振る舞いを与えますresizeToAvoidBottomInset
Sajad Jaward 2020年

プライマリプロパティをfalseに設定します。
VLXU

1
しかし、使用NeverScrollableScrollPhysicsすると、キーボードでも上にスクロールされないようになります。
hiwadoski20年

18

非推奨の代わりにに設定resizeToAvoidBottomInsetします。falseresizeToAvoidBottomPadding

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

3
それらは同じ答えです@Ojonugwa、多分私が私の投稿後に編集者が受け入れられた答えを更新したので、今の違いは私のものに例が含まれているということですか?
ArtiomLK

5

私のアプローチはSingleChildScrollViewClampingScrollPhysics物理学で使用することです。

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

4

方法1:android:windowSoftInputMode="adjustResize" AndroidManifest.xmlファイルから削除し(そうでない場合はフラッターコードをオーバーライドします)、resizeToAvoidBottomPadding: false以下のようにScaffoldを追加します。

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

方法2(非推奨):android:windowSoftInputMode="stateVisible"アクティビティにandroid AndroidManifest.xmlを追加するだけで、Androidでのみ機能し、IOSでは機能しません。

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

注:に設定しないでくださいandroid:windowSoftInputMode="adjustResize"


4

@Amanのソリューションを実装すると、キーボードが表示されたときのようにアプリが醜く動作し、使用可能な高さに従って画面のビューポートが調整されず、他のフィールドがキーボードの後ろに隠れてしまうと思います。したがって、SingleChildScrollView代わりに使用することをお勧めします。

SingleChildScrollView以下のようにコードをラップします。

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

拡張されたウィジェットには、singlechildscrollviewによって与えられた無限のスペースが含まれるため、これによりすぐに大量のエラーがスローされることに注意してください
Christian X

2

ユースケースによっては、リストビューの使用を検討することもできます。これにより、十分なスペースがない場合にコンテンツが確実にスクロールします。例として、ギャラリーアプリのテキストフィールドデモを見ることができます


4
ただし、これでも、選択したTextFieldが表示されるようにはならず、キーボードは引き続き表示されます。自分でスクロールする必要があります。Android開発者/ユーザーとしては慣れていません
Boy

2

私の提案はresizeToAvoidBottomInset: false、キーボードが突然画面に表示された場合にウィジェットのサイズが変更されないようにするためにとにかく使用することです。たとえば、ユーザーがアプリ内でFacebookチャットヘッドを使用している場合です。

キーボードがウィジェットをオーバーレイしないようにするために、必要な画面で、次のアプローチをお勧めします。ここで、は高さをSingleChildScrollView使用可能なスペースの高さに減らします。この場合、SingleChildScrollViewフォーカスされたウィジェットにもスクロールします。

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

1

私にとって、以下のアイテムプロパティをtrueからfalseに変更します

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

ファイル内

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

Flutterが入力フォーカスですべてのページコンテンツを上にドラッグするようにしました

入力フォーカスですべてのページコンテンツを上向きにフラッタードラッグします


それは...表示されますので、これは唯一のアンドロイドのために働くだろう
クリスチャンXを

1

私は同じ問題に直面していました、そして私はそれを修正するためにランダムな解決策を試し始めました、そして突然これはそれを修正しました。 ここに画像の説明を入力してください

メインの親コンテナをSingleChildScrollView()内でラップし、デバイスの高さを指定します。つまり、device_height = MediaQuery.of(context).size.heightです。

これにより、ページ全体がスクロール可能になりますが、ウィジェットのサイズは変更されません。


完璧に機能しています!ありがとう!
ギハンサンダル

お役に立てて嬉しいです !
Rudr Thakur47
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.