เมื่อแป้นพิมพ์ปรากฏขึ้นวิดเจ็ต Flutter จะปรับขนาด วิธีการป้องกันนี้?


114

ฉันมีคอลัมน์วิดเจ็ตแบบขยายดังนี้:

 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วิดเจ็ตและฮาร์ดโค้ดที่มีความสูงสำหรับแต่ละวิดเจ็ตวิดเจ็ตจะไม่ปรับขนาด แต่ฉันได้รับข้อผิดพลาดลายสีดำและสีเหลืองเมื่อแป้นพิมพ์ปรากฏขึ้น (เนื่องจากมีพื้นที่ไม่เพียงพอ) นอกจากนี้ยังไม่ยืดหยุ่นสำหรับหน้าจอทุกขนาด

ฉันไม่แน่ใจว่านี่เป็นแอนดรอยด์เฉพาะหรือเฉพาะสำหรับ Flutter


ในตัว Scaffold ของคุณใช้ SingleChildScrollView
linhadiretalipe

คำตอบ:


287

คำตอบที่อัปเดต

resizeToAvoidBottomPaddingคือตอนนี้เลิกใช้

การแก้ปัญหาคือการอัปเดตการตั้งค่าคุณสมบัติการresizeToAvoidBottomInsetfalse


คำตอบเดิม

ในของคุณScaffoldตั้งค่าคุณสมบัติการresizeToAvoidBottomPaddingfalse


11
มีวิธีใดบ้างที่จะให้ผลคล้ายกับandroid:windowSoftInputMode="adjustPan"? ถ้าฉันเพิ่มลงresizeToAvoidBottomPaddingในโครงนั่งร้านมันก็จะปิด TextField
Epicality

3
ฉันไม่รู้เกี่ยวกับ Android แต่โดยทั่วไปแล้วการรวมเลย์เอาต์ของคุณไว้ใน ListView ในกรณีนี้เป็นวิธีปฏิบัติที่ดี
aziza

@aziza ฉันประสบปัญหาเดียวกัน แต่หลังจากที่โซลูชันของคุณใช้งานได้ดี แต่มีปัญหาอื่นโปรดตรวจสอบวิดีโอจากลิงก์รูปภาพกะพริบเมื่อแป้นพิมพ์ปรากฏขึ้น dropbox.com/s/lian92mnzz8kv9w/FlutterIssue1.mov?dl=0
Kishan Vyas

@KishanVyas ภาพเดียวกันกับฉันหายไป
Stuckedoverflow

@aziza Solid answer
Val

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

ตั้งค่าคุณสมบัติหลักเป็นเท็จ
VLXU

1
แต่การใช้งานNeverScrollableScrollPhysicsทำให้มันไม่ได้เลื่อนขึ้นด้วยแป้นพิมพ์ด้วย
hiwa doski

18

ตั้งค่าresizeToAvoidBottomInsetเป็นfalseแทนที่จะresizeToAvoidBottomPaddingเลิกใช้งาน

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

3
เป็นคำตอบเดียวกันกับ @Ojonugwa บางทีบรรณาธิการอาจอัปเดตคำตอบที่ยอมรับหลังจากที่ฉันโพสต์ของฉันแล้วความแตกต่างคือของฉันมีตัวอย่างหรือไม่
ArtiomLK

5

แนวทางของฉันคือใช้SingleChildScrollViewกับClampingScrollPhysicsฟิสิกส์

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

3

คำแนะนำของฉันคือใช้resizeToAvoidBottomInset: falseต่อไปเพื่อป้องกันไม่ให้วิดเจ็ตปรับขนาดหากแป้นพิมพ์ปรากฏขึ้นบนหน้าจอกะทันหัน ตัวอย่างเช่นหากผู้ใช้ใช้ Facebook Chat Head ขณะอยู่ในแอพของคุณ

เพื่อป้องกันไม่ให้แป้นพิมพ์ซ้อนทับวิดเจ็ตบนหน้าจอที่คุณต้องการฉันขอแนะนำวิธีการต่อไปนี้โดยที่ความสูงของการ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()
        ],
      ),
    ),
  ),
);

2

คุณสามารถพิจารณาใช้listviewได้ทั้งนี้ขึ้นอยู่กับกรณีการใช้งาน เพื่อให้แน่ใจว่าเนื้อหาจะเลื่อนเมื่อมีที่ว่างไม่เพียงพอ ตัวอย่างเช่นคุณสามารถดูไฟล์สาธิตฟิลด์ข้อความในแอปแกลเลอรี


4
แต่ยังไม่ทำให้ TextField ที่คุณเลือกปรากฏให้เห็นแป้นพิมพ์จะยังคงทับซ้อนกัน คุณต้องเลื่อนเอง ไม่เคยเป็นนักพัฒนา / ผู้ใช้ Android
Boy

1

สำหรับฉันเปลี่ยนคุณสมบัติรายการด้านล่างจากจริงเป็นเท็จ

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

ในไฟล์

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

ทำให้ Flutter ลากเนื้อหาของหน้าทั้งหมดขึ้นไปที่อินพุตโฟกัส

Flutter ลากเนื้อหาของหน้าทั้งหมดขึ้นไปที่อินพุตโฟกัส


สิ่งนี้จะใช้ได้เฉพาะกับ Android ตามที่ปรากฏ ...
Christian X

1

ฉันประสบปัญหาเดียวกันและเริ่มลองวิธีแก้ปัญหาแบบสุ่มเพื่อแก้ไขและทันใดนั้นสิ่งนี้ก็แก้ไขได้ ใส่คำอธิบายภาพที่นี่

ห่อคอนเทนเนอร์หลักภายใน SingleChildScrollView () และกำหนดความสูงของอุปกรณ์เช่น device_height = MediaQuery.of (บริบท) .size.height

สิ่งนี้จะทำให้เลื่อนทั้งหน้าได้ แต่จะไม่ปรับขนาดวิดเจ็ตใด ๆ


ทำงานได้อย่างสมบูรณ์แบบ! ขอบคุณ !!
Gihan Sandaru

ดีใจที่ช่วยได้!
Rudr Thakur
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.