วิวพอร์ตแนวตั้งได้รับความสูงที่ไม่ถูกผูกไว้


133

นี่คือรหัสของฉัน:

  @override
  Widget build(BuildContext context) {
    return new Material(
      color: Colors.deepPurpleAccent,
      child: new Column(
       mainAxisAlignment: MainAxisAlignment.center,
          children:<Widget>[new GridView.count(crossAxisCount: _column,children: new List.generate(_row*_column, (index) {
            return new Center(
                child: new CellWidget()
            );
          }),)]
      )
    );
  }

ข้อยกเว้นดังนี้:

I/flutter ( 9925): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 9925): The following assertion was thrown during performResize():
I/flutter ( 9925): Vertical viewport was given unbounded height.
I/flutter ( 9925): Viewports expand in the scrolling direction to fill their container.In this case, a vertical
I/flutter ( 9925): viewport was given an unlimited amount of vertical space in which to expand. This situation
I/flutter ( 9925): typically happens when a scrollable widget is nested inside another scrollable widget.
I/flutter ( 9925): If this widget is always nested in a scrollable widget there is no need to use a viewport because
I/flutter ( 9925): there will always be enough vertical space for the children. In this case, consider using a Column
I/flutter ( 9925): instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
I/flutter ( 9925): the height of the viewport to the sum of the heights of its children.
I/flutter ( 9925): 
I/flutter ( 9925): When the exception was thrown, this was the stack:
I/flutter ( 9925): #0      RenderViewport.performResize.<anonymous closure> (package:flutter/src/rendering/viewport.dart:827:15)
I/flutter ( 9925): #1      RenderViewport.performResize (package:flutter/src/rendering/viewport.dart:880:6)
I/flutter ( 9925): #2      RenderObject.layout (package:flutter/src/rendering/object.dart:1555:9)

คุณยังสามารถใช้คอนเทนเนอร์แบบธรรมดาแทนคอลัมน์ได้ (ส่วนใหญ่เป็นวิดเจ็ตลูกมากกว่าหนึ่งตัว)
นโปเลียน

การสร้างวิดเจ็ต (บริบท BuildContext) {return new Material (color: Colors.deepPurpleAccent, child: new Container (alignment: Alignment.center, child: new GridView.count (crossAxisCount: _column, children: new List.generate (_row * _column, (ดัชนี) {กลับศูนย์ใหม่ (ลูก: เซลล์ใหม่ใหม่ ());})))); - รหัสนี้ยังไม่ช่วย @Napolean
pallav bohara

ลองเพิ่ม mainAxisSize เป็น max ใต้ ​​Column แล้วดูว่าช่วยได้ไหม
pblead26

ดูสิ่งนี้ถ้ามันได้ผลเพราะฉันคิดว่ามันควรจะทำ: stackoverflow.com/a/61708887/10563627
Paresh Mangukiya

คำตอบ:


264

การเพิ่มสองบรรทัดนี้

ListView.builder(
    scrollDirection: Axis.vertical,
    shrinkWrap: true,
...

8
ขอขอบคุณคำแนะนำเล็ก ๆ น้อย ๆ ที่คุณสามารถล้อมรอบ ListView โดย Flexible เพื่อให้เลื่อนได้
Shady Mohamed Sherif

3
นี่คือเอกสารสำหรับshrinkWrap api.flutter.dev/flutter/widgets/ScrollView/shrinkWrap.html
Omer Celik

165

สิ่งนี้มักเกิดขึ้นเมื่อคุณพยายามใช้ a ListView/ GridViewinside a Columnมีหลายวิธีในการแก้ปัญหาฉันมีรายชื่ออยู่ไม่กี่ที่นี่

  1. ห่อListViewในExpanded

    Column(
      children: <Widget>[
        Expanded( // wrap in Expanded
          child: ListView(...),
        ),
      ],
    )
    
  2. ห่อListViewในSizedBoxและให้ล้อมรอบheight

    Column(
      children: <Widget>[
        SizedBox(
          height: 400, // fixed height
          child: ListView(...),
        ),
      ],
    )
    
  3. ใช้shrinkWrap: trueในListView.

    Column(
      children: <Widget>[
        ListView(
          shrinkWrap: true, // use this
        ),
      ],
    )
    

5
ลองสิ่งนี้ด้วยมุมมองรายการแนวตั้งที่มีมุมมองรายการแนวนอน วิธีการขนาดเท่านั้นที่จะใช้งานได้ แต่มีการกำหนดความสูงเกินไป ต้องทำอย่างไรอีก
แฟร็

1
shrinkWrap: trueทำงาน
Ali80

1
นี่คือคำตอบ
vishalknishad

นี่คือสิ่งที่ฉันกำลังมองหา มีโอกาสเพิ่มข้อดีข้อเสียของแต่ละทางเลือกได้หรือไม่?
emragins

สิ่งนี้ช่วยฉันได้มาก ขอบคุณ @CopsOnRoad
Kobby Discount

34

ดังนั้นทุกคนจึงโพสต์คำตอบ แต่ไม่มีใครสนใจที่จะอธิบายว่าทำไมฉันจะคัดลอกเอกสารเกี่ยวกับshrinkWrap:

ขอบเขตของมุมมองการเลื่อนใน [scrollDirection] ควรถูกกำหนดโดยเนื้อหาที่กำลังดูอยู่หรือไม่

หากมุมมองแบบเลื่อนไม่หดตัวมุมมองแบบเลื่อนจะขยายเป็นขนาดสูงสุดที่อนุญาตใน [scrollDirection] หากมุมมองการเลื่อนมีข้อ จำกัด ที่ไม่ถูกผูกไว้ใน [scrollDirection] ดังนั้น [shrinkWrap] จะต้องเป็นจริง

การย่อขนาดเนื้อหาของมุมมองการเลื่อนมีราคาแพงกว่าการขยายเป็นขนาดสูงสุดที่อนุญาตอย่างมากเนื่องจากเนื้อหาสามารถขยายและหดตัวระหว่างการเลื่อนซึ่งหมายความว่าขนาดของมุมมองการเลื่อนจะต้องได้รับการคำนวณใหม่ทุกครั้งที่ตำแหน่งการเลื่อนเปลี่ยนไป

ค่าเริ่มfalseต้นเป็น

ดังนั้นการใช้คำศัพท์ของเอกสารสิ่งที่เกิดขึ้นที่นี่คือเราListViewอยู่ในสถานการณ์ของข้อ จำกัด ที่ไม่มีขอบเขต (ในทิศทางที่เรากำลังเลื่อน) ดังนั้นListViewจะบ่นว่า:

... วิวพอร์ตแนวตั้งได้รับพื้นที่แนวตั้งไม่ จำกัด จำนวนที่จะขยาย

เพียงแค่ตั้งค่าshrinkWrapเป็นtrueจะทำให้แน่ใจว่าขนาดที่กำหนดโดยเนื้อหา โค้ดตัวอย่างเพื่อแสดง:

// ...
  ListView(
    // Says to the `ListView` that it must wrap its
    // height (if it's vertical) and width (if it's horizontal).
    shrinkWrap: true,
  ),
// ...

นั่นคือสิ่งที่เกิดขึ้นกับรหัสของคุณอย่างไรก็ตามข้อเสนอแนะของ @ Rémiดีที่สุดสำหรับกรณีนี้โดยใช้Alignแทนไฟล์Column.


28

วางมุมมองกริดไว้ในวิดเจ็ตแบบยืดหยุ่นหรือแบบขยาย

return new Material(
    color: Colors.deepPurpleAccent,
    child: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children:<Widget>[
         Flexible(
          child:  GridView.count(crossAxisCount: _column,children: new List.generate(_row*_column, (index) {
          return new Center(
             child: new CellWidget(),
          );
        }),))]
    )
);

1
ขยายและเพิ่มshrinkWrap: trueใน GridView
Wilmer

14

โดยทั่วไปสถานการณ์นี้จะเกิดขึ้นเมื่อวิดเจ็ตแบบเลื่อนได้ซ้อนอยู่ภายในวิดเจ็ตที่เลื่อนได้อื่น

ในกรณีของฉันฉันใช้ GridView ภายในคอลัมน์และข้อผิดพลาดนั้นเกิดขึ้น

วิดเจ็ต GridView มีshrinkWrapคุณสมบัติ / พารามิเตอร์ที่ตั้งชื่อเพื่อตั้งค่าว่าtrueปัญหาของฉันได้รับการแก้ไขแล้ว

GridView.count(
  shrinkWrap: true,
  // rest of code
)

10

อย่าใช้Columnสำหรับการจัดตำแหน่งลูกคนเดียว ใช้Alignแทน

    new Align(
      alignment: Alignment.topCenter,
      child: new GridView(),
    )

แม้ว่าจะแก้ไขข้อผิดพลาดของฉันแล้ว แต่ก็ยังไม่สามารถวาง GridView ในแนวตั้งได้ ก็แสดงเหมือนเดิม ลองใช้แฟล็กทั้งหมดสำหรับ Alignment * ฉันขาดอะไรไป?
pallav bohara

7

แม้ว่าshrinkWrapจะทำสิ่งนั้น แต่คุณไม่สามารถเลื่อนเข้าListViewมาได้

หากคุณต้องการฟังก์ชันการเลื่อนคุณสามารถเพิ่มphysicsคุณสมบัติ:

ListView.builder(
    scrollDirection: Axis.vertical,
    shrinkWrap: true,
    physics: ScrollPhysics(),
...

5

คำตอบนี้อ้างอิงจากทางเหนือของ @CopsOnRoad

สิ่งนี้เกิดขึ้นเนื่องจากListView/GridViewวิดเจ็ตไม่มีพาเรนต์ที่จะรับขนาดดังนั้นความสูงจึงไม่สิ้นสุดและเนื่องจากการกระพือไม่ทราบความสูงของ ListView และไม่สามารถแสดงผลได้

  1. แนวทางที่หนึ่ง: ความสูงคงที่

    ห่อด้วยContainerหรือSizedBoxเพื่อเขียนความสูงตาย

    Column(
      children: <Widget>[
        SizedBox(
         height: 400, // fixed height
        child: ListView(...),
       ),
     ],
    )
    

ไม่เป็นไร แต่ถ้าต้องปรับความสูงก็จะใช้ไม่ได้ถ้าคุณเขียน

  1. แนวทางที่สอง: shrinkWrap: true

    ลองshrinkWrap: trueด้วยphysics: ScrollPhysics()สำหรับการเลื่อน

    shrinkWrap: truewrap_contentเป็นบิตเช่นในหุ่นยนต์

    ListView.builder(
       scrollDirection: Axis.vertical,
       shrinkWrap: true,
       physics: ScrollPhysics()
    ...
    

อย่างไรก็ตามหลังจากรวบรวมแล้วคุณจะพบคำเตือนสีเหลืองยาว ๆ ที่ด้านล่างของหน้า

เลยยังไม่ได้

  1. แนวทางที่สาม: ขยายหรือยืดหยุ่น

    Flexible เป็นรูปแบบที่ยืดหยุ่นในการกระพือปีกเทียบเท่ากับ LinearLayout ใน Android

    มีหนึ่งรายการในflexแอตทริบิวต์Flexible The ซึ่งเท่ากับ layout_weight จะใช้พื้นที่ที่เหลือทั้งหมด

    ดังนั้นเราสามารถรวม ListView ด้วย Flexible

    Column(
      children: <Widget>[
        Expanded( 
          child: ListView(...),
        ),
      ],
    )
    

คำตอบนี้อ้างอิง: วิวพอร์ตแนวตั้งได้รับความสูงที่ไม่ถูกผูกไว้


ทั้งหมดนี้ครอบคลุมอยู่ในโซลูชันของฉัน Paresh แล้ว ฉันหวังว่าคุณจะเพิ่มสิ่งใหม่ ๆ
CopsOnRoad

ใช่ฉันรู้ แต่ฉันได้พยายามอธิบายวิธีแก้ปัญหานั้นแล้วแม้ว่าฉันคิดว่าฉันควรพูดถึงคุณเป็นเครดิต
Paresh Mangukiya

1

ทดสอบสิ่งนี้สำหรับมุมมองรายการที่สอง

ListView.builder(
            physics: NeverScrollableScrollPhysics(),

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