Klavye göründüğünde, Flutter widget'ları yeniden boyutlandırılır. Bunu nasıl önleyebilirim?


101

Bunun gibi bir Genişletilmiş widget Sütunum var:

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

Şöyle görünüyor:

görüntü açıklamasını buraya girin

convertFrom, bir TextField içerir. Bu metin alanına dokunduğumda ekranda Android klavye beliriyor. Bu, ekran boyutunu değiştirir, böylece widget'lar şu şekilde yeniden boyutlandırılır:

görüntü açıklamasını buraya girin

Sütunumun yeniden boyutlandırılmaması için klavyenin ekranı "kaplamasının" bir yolu var mı? ExpandedWidget kullanmazsam ve her widget için bir yüksekliği sabit kodlamazsam, widget'lar yeniden boyutlandırılmaz ancak klavye göründüğünde siyah ve sarı çizgili hata alıyorum (çünkü yeterli alan yok). Bu aynı zamanda tüm ekran boyutları için esnek değildir.

Bunun Android'e mi yoksa Flutter'a mı özgü olduğundan emin değilim.


Scaffold vücudunuzda bir SingleChildScrollView kullanın.
linhadiretalipe

Yanıtlar:


263

Gözlerinde farklı Scaffold, set resizeToAvoidBottomInsetözelliği ile false.

"ResizeToAvoidBottomPadding" Mülkiyet .... artık önerilmemektedir sizin de Scaffoldset resizeToAvoidBottomPaddingmülk false.


11
İle benzer bir etki yaratmanın bir yolu var mı android:windowSoftInputMode="adjustPan"? Ben eklerseniz resizeToAvoidBottomPaddingdarağacına o TextField kapsayan biter.
Epicality

2
Android hakkında bir bilgim yok, ancak bu durumda düzeninizi bir ListView içine almak genellikle iyi bir uygulamadır
aziza

@aziza, ben de aynı sorundan muzdariptim, ancak çözümünüzden sonra iyi çalışıyor, ancak başka bir sorun var, lütfen bağlantıdan videoyu kontrol edin Klavye göründüğünde görüntü yanıp sönüyordu. dropbox.com/s/lian92mnzz8kv9w/FlutterIssue1.mov?dl=0
Kishan Vyas

@KishanVyas benimle aynı görüntü gitti.
sıkışmışoverflow

@aziza Katı cevap
Val

29

Diğer cevapların çoğu kullanmanızı önerir resizeToAvoidBottomPadding=false. Deneyimlerime göre bu, klavyenin görüneceği yerin altındaysa klavyenin metin alanlarını örtmesine izin veriyor.

Mevcut çözümüm, SingleChildScrollViewsütunumu ekranla aynı yükseklikte olmaya zorlamak, ardından onu bir içine yerleştirmek, böylece Flutter, klavye kullanıldığında ekranımı otomatik olarak yeterince yukarı kaydırır.

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

Kullandığım NeverScrollableScrollPhysicskullanıcı kendilerini etrafında kaydırma böylece.


3
Yolunuzu olmadan denedim NeverScrollableScrollPhysicsve her şey yolunda görünüyor, ancak kullanıcı yukarı ve aşağı kaydırmayı deneyebilir ve aşırı kaydırma parıltısını görebilirler. Bunu kullandığımda NeverScrollableScrollPhysicsbana aynı davranışı veriyorresizeToAvoidBottomInset
Sajad Jaward

Birincil özelliği false olarak ayarlayın.
VLXU


4

Yöntem 1:android:windowSoftInputMode="adjustResize" AndroidManifest.xml dosyasından kaldırın (Aksi takdirde flutter kodunu geçersiz kılar) ve resizeToAvoidBottomPadding: falseaşağıdaki gibi Scaffold'a ekleyin :

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

Yöntem 2 (Önerilmez):android:windowSoftInputMode="stateVisible" Aktivitede sadece android AndroidManifest.xml'de ekleyin , yalnızca Android için çalışacak ve IOS için Değil gibi çalışacaktır.

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

Not: Ayarlamayınandroid:windowSoftInputMode="adjustResize"


4

Eğer @ Aman'ın çözümünü uygularsak, uygulamamızın klavye göründüğünde çirkin davranmasına neden olacağını, ekran görünümümüzü mevcut yüksekliğe göre ayarlamayacağını ve diğer alanları klavyenin arkasına gizleyeceğini düşünüyorum. Bu yüzden SingleChildScrollViewbunun yerine kullanmanızı öneririm .

Kodunuzu SingleChildScrollViewaşağıda verilen şekilde sarın ,

 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

Kullanım durumuna bağlı olarak bir liste görünümü kullanmayı da düşünebilirsiniz . Bu, yeterli yer olmadığında içeriğin kaydırılmasını sağlar. Örnek olarak, galeri uygulamasındaki metin alanı demosuna bakabilirsiniz.


4
Ancak bu, seçtiğiniz TextField'ı yine de görünür kılmaz, klavye yine de bunun üzerine gelecektir. Kendin kaydırmalısın. Android geliştiricisi / kullanıcısı olarak alışkın değil
Boy

2

Benim yaklaşımım fizik SingleChildScrollViewile kullanmaktır ClampingScrollPhysics.

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

1

Benim için aşağıdaki öğe özelliğini doğrudan yanlışa değiştiriyorum

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

dosyada

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

Flutter'ın tüm sayfa içeriğini giriş odağında yukarı doğru sürüklemesini sağladı

Flutter, tüm sayfa içeriğini giriş odağında yukarı doğru sürükleyin


0

Benim önerim, resizeToAvoidBottomInset: falseklavye ekranda aniden belirirse, widget'ların yeniden boyutlandırılmasını önlemek için yine de kullanmaktır . Örneğin, bir kullanıcı uygulamanızda Facebook sohbet başlıklarını kullanıyorsa.

Klavyenin, ihtiyaç duyduğunuz ekranlarda widget'ları kaplamasını önlemek için, aşağıdaki yaklaşımı öneriyorum, burada SingleChildScrollViewyüksekliğin mevcut alanın yüksekliğine indirildiği yer. Bu durumda, SingleChildScrollViewodaklanan parçacığa da kaydırır.

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()
        ],
      ),
    ),
  ),
);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.