Wenn die Tastatur angezeigt wird, wird die Größe der Flutter-Widgets geändert. Wie kann man das verhindern?

101

Ich habe eine Spalte mit erweiterten Widgets wie folgt:

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

Es sieht aus wie das:

Geben Sie hier die Bildbeschreibung ein

convertFrom, enthält ein TextField. Wenn ich auf dieses Textfeld tippe, wird die Android-Tastatur auf dem Bildschirm angezeigt. Dadurch wird die Bildschirmgröße geändert, sodass die Größe der Widgets wie folgt geändert wird:

Geben Sie hier die Bildbeschreibung ein

Gibt es eine Möglichkeit, dass die Tastatur den Bildschirm "überlagert", damit die Größe meiner Spalte nicht geändert wird? Wenn ich keine ExpandedWidgets verwende und für jedes Widget eine Höhe fest codiere, wird die Größe der Widgets nicht geändert, aber ich erhalte den schwarz-gelb gestreiften Fehler, wenn die Tastatur angezeigt wird (weil nicht genügend Speicherplatz vorhanden ist). Dies ist auch nicht für alle Bildschirmgrößen flexibel.

Ich bin mir nicht sicher, ob dies Android- oder Flutter-spezifisch ist.

Maria
quelle
Verwenden Sie in Ihrem Gerüstkörper eine SingleChildScrollView.
Linhadiretalipe

Antworten:

263

ScaffoldSetzen Sie in Ihrer resizeToAvoidBottomInsetEigenschaft auf false.

Die Eigenschaft "resizeToAvoidBottomPadding" ist jetzt veraltet.Scaffold Setzen Sie in Ihrer resizeToAvoidBottomPaddingEigenschaft die Eigenschaft auf false.

Aziza
quelle
11
Gibt es eine Möglichkeit, einen ähnlichen Effekt zu erzielen android:windowSoftInputMode="adjustPan"? Wenn ich resizeToAvoidBottomPaddingdas Gerüst hinzufüge , bedeckt es das TextField.
Epicality
2
Ich weiß nicht über Android, aber es ist im Allgemeinen eine gute Praxis, Ihr Layout in eine ListView in diesem Fall zu
verpacken
@aziza, ich hatte das gleiche Problem, aber nach Ihrer Lösung funktioniert es einwandfrei, aber es gibt ein anderes Problem. Überprüfen Sie das Video vom Link. Das Bild blinkte, als die Tastatur angezeigt wurde. dropbox.com/s/lian92mnzz8kv9w/FlutterIssue1.mov?dl=0
Kishan Vyas
@ KishanVyas gleich mit mir Bild ist weg.
Stuckedoverflow
@ Aziza Solide Antwort
Val
29

Die meisten anderen Antworten schlagen vor, zu verwenden resizeToAvoidBottomPadding=false. Nach meiner Erfahrung kann die Tastatur Textfelder verdecken, wenn sie sich unter der Stelle befinden, an der die Tastatur erscheinen würde.

Meine derzeitige Lösung besteht darin, zu erzwingen, dass meine Spalte dieselbe Höhe wie der Bildschirm hat, und sie dann SingleChildScrollViewso zu platzieren, dass Flutter meinen Bildschirm bei Verwendung der Tastatur automatisch gerade so weit nach oben rollt.

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

Ich benutze, NeverScrollableScrollPhysicsdamit der Benutzer nicht um sich selbst scrollen kann.

Duncan Jones
quelle
3
Ich habe deinen Weg ohne versucht NeverScrollableScrollPhysicsund alles sieht gut aus, außer dass der Benutzer versuchen kann, nach oben und unten zu wischen, und er kann das Overscroll-Leuchten sehen. Wenn ich das benutze, NeverScrollableScrollPhysicshabe ich das gleiche Verhalten wieresizeToAvoidBottomInset
Sajad Jaward
Setzen Sie die primäre Eigenschaft auf false.
VLXU
16

Stellen Sie resizeToAvoidBottomInsetan falseStelle von resizeToAvoidBottomPaddingdenen ist veraltet.

    return Scaffold(
      resizeToAvoidBottomInset : false,
      body: YourWidgets(),
    );
ArtiomLK
quelle
Wie unterscheidet sich diese Antwort von der akzeptierten?
Ojonugwa Jude Ochalifu
2
Es sind die gleichen Antworten @Ojonugwa. Vielleicht hat der Herausgeber die akzeptierte Antwort aktualisiert, nachdem ich meine gepostet habe. Der Unterschied besteht nun darin, dass meine ein Beispiel enthält.
ArtiomLK
4

Methode 1:android:windowSoftInputMode="adjustResize" Aus der Datei AndroidManifest.xml entfernen (andernfalls wird der Flattercode überschrieben) und resizeToAvoidBottomPadding: falsewie folgt in Scaffold hinzugefügt :

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

Methode 2 (nicht empfohlen): Fügen Sie einfach android:windowSoftInputMode="stateVisible"in Android AndroidManifest.xml in Aktivität hinzu, es funktioniert nur für Android und nicht für IOS wie.

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

Hinweis: Stellen Sie es nicht auf einandroid:windowSoftInputMode="adjustResize"

Yatin Deokar
quelle
4

Nun, ich denke, wenn wir die Lösung von @ Aman implementieren, verhält sich unsere App hässlich, wenn die Tastatur angezeigt wird. Dadurch wird das Ansichtsfenster des Bildschirms nicht an die verfügbare Höhe angepasst und andere Felder werden hinter der Tastatur ausgeblendet. Daher würde ich SingleChildScrollViewstattdessen die Verwendung vorschlagen .

Wickeln Sie Ihren Code SingleChildScrollViewwie folgt ein:

 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
quelle
2

Abhängig vom Anwendungsfall können Sie auch eine Listenansicht verwenden . Dies würde sicherstellen, dass der Inhalt gescrollt wird, wenn nicht genügend Platz vorhanden ist. Als Beispiel können Sie sich die Textfeld- Demo in der Galerie-App ansehen

aptik
quelle
4
Dadurch wird das von Ihnen ausgewählte TextField jedoch immer noch nicht sichtbar. Die Tastatur überlappt es weiterhin. Sie müssen es selbst scrollen. Nicht gewohnt als Android-Entwickler / Benutzer
Boy
2

Mein Ansatz ist es, SingleChildScrollViewmit der ClampingScrollPhysicsPhysik zu verwenden.

SingleChildScrollView(
  physics: ClampingScrollPhysics(),
  child: Container(),
)
Den
quelle
1

Für mich ändere ich die Item-Eigenschaft von true nach false

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

im Ordner

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

hat Flutter veranlasst, den gesamten Seiteninhalt im Eingabefokus nach oben zu ziehen

Flattern Ziehen Sie den gesamten Seiteninhalt im Eingabefokus nach oben

javeedishaq
quelle
0

Mein Vorschlag ist, es resizeToAvoidBottomInset: falsetrotzdem zu verwenden, um zu verhindern, dass Widgets die Größe ändern, wenn die Tastatur plötzlich auf dem Bildschirm angezeigt wird. Zum Beispiel, wenn ein Benutzer in Ihrer App Facebook-Chatköpfe verwendet.

Um zu verhindern, dass die Tastatur Widgets überlagert, schlage ich auf Bildschirmen, auf denen Sie sie benötigen, den folgenden Ansatz vor: Die Höhe wird SingleChildScrollViewauf die Höhe des verfügbaren Speicherplatzes reduziert. Scrollt in diesem Fall SingleChildScrollViewauch zum fokussierten Widget.

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
quelle