Flutter - #20. SliverGrid

Pearl Lee·2021년 6월 20일
0

Flutter Widget

목록 보기
20/50

내가 보려고 쓰는 Flutter 일기 내가 본다고는 했지만 지적은 환영이어요
참고1 : https://api.flutter.dev/flutter/widgets/SliverGrid-class.html
참고2 : https://medium.com/flutter/slivers-demystified-6ff68ab0296f






SliverGrid

오늘 배워볼 것은 지난 시간에 이어서, SliverGrid
2차원 상에 자식 요소들을 나열하며, GridView와 생성자도 비슷한 듯하다. SliverList와 유사하게 children 속성에 자식 요소들을 나열하거나, delegate속성에 자식 요소 나열 정보를 넣어도 된다. 바로 코드로 들어가보자.











코드 예시로 알아보자

SliverGrid, SliverGridDelegateWithFixedCrossAxisCount, SliverGridDelegateWithMaxCrossAxisExtent




역시나 CustomScrollView 에서 돌려봤던 코드이다. Sliver2 부분을 추가해서 돌려보았다. SliverGrid를 쓸때는, gridDelegate 속성을 반드시 설정해주어야 한다. 자식 요소의 크기와 위치를 조절하는 속성이다.

Sliver 2 처럼 자식요소를 하나하나 나열해도 되고, SliverChildBuilderDelegate를 써서 생성해주어도 된다. 자식 요소가 많아진다면 아무래도 builder를 쓰는게 편하지 않을까?

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

/// This is the main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: MyStatefulWidget(),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Test CustomScrollView - SliverGrid'),
      ),
      //요기부터 시작
      body: CustomScrollView(
        slivers: <Widget>[
          //Sliver 1
          const SliverAppBar(
            pinned: true,
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('SliverAppBar'),
              background: FlutterLogo(),
            ),
          ),
          
          
          //Sliver 2
          SliverGrid(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3
            ),
            delegate: SliverChildListDelegate([
              Container(color: Colors.red, height: 150.0),
              Container(color: Colors.purple, height: 150.0),
              Container(color: Colors.green, height: 150.0),
              Container(color: Colors.cyan, height: 150.0),
              Container(color: Colors.indigo, height: 150.0),
              Container(color: Colors.black, height: 150.0),
            ],)
          ),
          
          
          //Sliver 3
          SliverGrid(
            gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 200.0,
            ),
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  color: Colors.teal[100 * (index % 9)],
                  child: Text(
                    'Grid Item ${index+1}',
                    style: TextStyle(fontSize: 20),
                  ),
                );
              },
              childCount: 10,
            ),
          )
        ],
      ),
    );
  }
}

Sliver 2에 설정한 SliverGridDelegateWithFixedCrossAxisCount 는, 열 개수 몇 개로 할건지 설정하는 거고, SliverGridDelegateWithMaxCrossAxisExtent 는 열 너비 max값을 설정하는 것이다. 간단해용

위 코드에서 Sliver 2, 3을 각각 실행시켜 보았다.

Sliver 2Sliver 3
100300













그런데 난 자식들이 다닥다닥 붙어있는 건 싫다

gridDelegate

mainAxisSpacing, crossAxisSpacing

gridDelegate 속성을 이용해 자식들을 떨어뜨려 보자. 위 Sliver 3 코드를 아래와 같이 바꾼다.

SliverGrid(
            gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 200.0,
              mainAxisSpacing: 10.0,
              crossAxisSpacing: 10.0,
              childAspectRatio: 4.0,
            ),
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  color: Colors.teal[100 * (index % 9)],
                  child: Text(
                    'Grid Item ${index+1}',
                    style: TextStyle(fontSize: 20),
                  ),
                );
              },
              childCount: 10,
            ),
          )

mainAxisSpacing은 행 간 거리이고, crossAxisSpacing은 열 간 거리이다. 우선 이 두가지부터 테스트해보자.

mainAxisSpacing: 20.0, crossAxisSpacing: 10.0mainAxisSpacing: 10.0, crossAxisSpacing: 20.0mainAxisSpacing: 20.0, crossAxisSpacing: 20.0
100300300

위와 같이 간격이 넓어진 것을 알 수 있다.







childAspectRatio

childAspectRatio 는 설명을 어떻게 해석해야 할지.. 모르겠다

고로 실행화면을 바로 보자.

childAspectRatio: 1.0childAspectRatio: 2.0childAspectRatio: 4.0
100300300

값이 커질수록 자식 요소들의 높이가 줄어드는 것을 알 수 있다. 너비:높이의 비율을 조정하는 것이다. 1일 경우 너비와 높이가 같고, 2이면 높이는 너비의 절반이 되며, 4일 경우 높이는 너비의 1/4값이 된다.

위 값들은 SliverGridDelegateWithFixedCrossAxisCount 에 넣어도 똑같이 동작한다.

오늘의 일기는 여기까지!

profile
안 되면 되게 하라

0개의 댓글