Flutter의 GridView에서 위젯의 사용자 지정 높이를 설정하는 방법은 무엇입니까?


87

Container GridView의 높이를 지정한 후에도 내 코드는 사각형 위젯을 생성합니다.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> widgetList = ['A', 'B', 'C'];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(
        child: new GridView.count(
          crossAxisCount: 2,
          controller: new ScrollController(keepScrollOffset: false),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          children: widgetList.map((String value) {
            return new Container(
              height: 250.0,
              color: Colors.green,
              margin: new EdgeInsets.all(1.0),
              child: new Center(
                child: new Text(
                  value,
                  style: new TextStyle(fontSize: 50.0,color: Colors.white),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

위 코드의 출력은 왼쪽과 같습니다. 오른쪽에 표시된대로 사용자 지정 높이 위젯이있는 GridView를 얻으려면 어떻게해야합니까?

산출 필수 출력


답변:


160

핵심은 childAspectRatio. 이 값은에서 레이아웃을 결정하는 데 사용됩니다 GridView. 원하는 화면을 얻으려면 ( itemWidth/ itemHeight) 로 설정해야합니다 . 해결책은 다음과 같습니다.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> widgetList = ['A', 'B', 'C'];

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;

    /*24 is for notification bar on Android*/
    final double itemHeight = (size.height - kToolbarHeight - 24) / 2;
    final double itemWidth = size.width / 2;

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(
        child: new GridView.count(
          crossAxisCount: 2,
          childAspectRatio: (itemWidth / itemHeight),
          controller: new ScrollController(keepScrollOffset: false),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          children: widgetList.map((String value) {
            return new Container(
              color: Colors.green,
              margin: new EdgeInsets.all(1.0),
              child: new Center(
                child: new Text(
                  value,
                  style: new TextStyle(
                    fontSize: 50.0,
                    color: Colors.white,
                  ),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

대답 해줘서 고마워요. 나에게 시간 저장
Dhruvam 샤르마

/ - : 당신이 카운트 방식으로 일을하는지하지 않는 한의 GridView는 재산 childAspectRatio이 없습니다
올리버 딕슨

1
당신이 사용하는 경우 @OliverDixon GridView.builderSliverGridDelegateWithFixedCrossAxisCount한 다음 childAspectRatio온입니다gridDelegate
Fifer 양

1
이 높이를 동적으로 만드는 방법?
Dani

15

며칠 전 인터넷에서 이미지를로드 할 때 높이를 동적으로 변경하는 방법을 찾기 위해 여기에 왔으며 childAspectRatioGridView의 모든 위젯에 적용되기 때문에 사용할 수 없습니다 (각각에 대해 동일한 높이).

이 답변은 각각의 모든 위젯 콘텐츠에 따라 다른 높이를 원하는 사람에게 도움이 될 수 있습니다.

Romain Rastel의 Flutter Staggered GridView 라는 패키지를 찾았습니다 . 이 패키지를 사용하여 우리는 여기에서 예제를 확인하는 많은 일을 할 수 있습니다.

우리가 원하는 것을 얻기 위해 우리가 사용할 수 StaggeredGridView.count()있는 속성 staggeredTiles:과 그 값에 대해 모든 위젯을 매핑하고 적용 할 수 있습니다 StaggeredTile.fit(2).

예제 코드 :

StaggeredGridView.count(
    crossAxisCount: 4, // I only need two card horizontally
    padding: const EdgeInsets.all(2.0),
    children: yourList.map<Widget>((item) {
      //Do you need to go somewhere when you tap on this card, wrap using InkWell and add your route
      return new Card(
        child: Column(
          children: <Widget>[
             Image.network(item.yourImage),
             Text(yourList.yourText),//may be the structure of your data is different
          ],
        ),
      );
    }).toList(),

    //Here is the place that we are getting flexible/ dynamic card for various images
    staggeredTiles: yourList.map<StaggeredTile>((_) => StaggeredTile.fit(2))
        .toList(),
    mainAxisSpacing: 3.0,
    crossAxisSpacing: 4.0, // add some space
  ),
);

여기 에서 전체 예제 (복사, 붙여 넣기 및 실행)를 찾을 수 있습니다 .


8

crossAxisCount, crossAxisSpacing화면 너비가 결정 width하고 childAspectRatio결정 height합니다.

나는 그들 사이의 관계를 알아 내기 위해 약간의 계산을했다.

var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var height = width / _aspectRatio;

전체 예 :

double _crossAxisSpacing = 8, _mainAxisSpacing = 12, _aspectRatio = 2;
int _crossAxisCount = 2;

@override
Widget build(BuildContext context) {
  double screenWidth = MediaQuery.of(context).size.width;

  var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
  var height = width / _aspectRatio;

  return Scaffold(
    body: GridView.builder(
      itemCount: 10,
      itemBuilder: (context, index) => Container(color: Colors.blue[((index) % 9) * 100]),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: _crossAxisCount,
        crossAxisSpacing: _crossAxisSpacing,
        mainAxisSpacing: _mainAxisSpacing,
        childAspectRatio: _aspectRatio,
      ),
    ),
  );
}

5

여기에 이미지 설명 입력

그것은 나를 위해 일하고 있습니다.

예제 코드 :

var _crossAxisSpacing = 8;
var _screenWidth = MediaQuery.of(context).size.width;
var _crossAxisCount = 2;
var _width = ( _screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var cellHeight = 60;
var _aspectRatio = _width /cellHeight;

GridView :

         GridView.builder(
                          padding: EdgeInsets.only(
                              left: 5.0, right: 5.0, top: 10, bottom: 10),
                          shrinkWrap: false,
                          itemCount: searchList.length,
                          gridDelegate:
                              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: _crossAxisCount,childAspectRatio: _aspectRatio),
                          itemBuilder: (context, index) {
                            final item = searchList[index];
                            return Card(
                              child: ListTile(
                                title: Text(item.name,maxLines: 1,overflow: TextOverflow.ellipsis),
                                trailing: Container(
                                  width: 15,
                                  height: 15,
                                  decoration: BoxDecoration(
                                      color: item.isActive == true
                                          ? Theme.of(context).primaryColor
                                          : Colors.red,
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(50))),
                                ),
                                onTap: () {

                                },
                              ),
                              elevation: 0.5,
                            );
                          },
                        ) 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.