Vintage appMaker의 Tech Blog

[flutter] listView(Column)안에 list, Grid, pageView 넣기 본문

Source code or Tip/Flutter & Dart

[flutter] listView(Column)안에 list, Grid, pageView 넣기

VintageappMaker 2022. 8. 4. 12:14

 

 

 

ListView 속성의 Widget에서 List형태(List, Grid, PageView, ..)을 구현할 때, 종종 에러를 경험하게 된다. 이때에는 child 위치에 있는 Widget들의 속성에서 physics와 shrinkWrap 파라메터를 다음과 같이 설정해주어야 한다. 

physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,

그러면 List의 크기에 따라 동적으로 자연스럽게 스크롤 처리가 가능하다. 

 

다음은 전체소스이다. 

import 'dart:ui';

import 'package:flutter/material.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatelessWidget {
  const MainApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scrollBehavior: DeskScrollBehavior(),
      title: 'list(grid) in ScrollView',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MainPage(title: 'list(grid) in ScrollView'),
    );
  }
}

class MainPage extends StatefulWidget {
  const MainPage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  final _pageController = PageController(viewportFraction: 0.8);
  int _index = 0;

  Widget _buildPageView() {
    return Container(
      height: 100,
      child: PageView.builder(
          itemCount: 10,
          controller: _pageController,
          itemBuilder: (BuildContext context, int index) {
            return Transform.scale(
                scale: index == _index ? 1 : 0.98,
                child: Container(
                  color: (index % 2 == 0) ? Colors.red : Colors.yellow,
                  child: SizedBox(
                      width: 100, child: Center(child: Text("${_index}"))),
                ));
          },
          onPageChanged: (int index) => setState(() => _index = index)),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          _buildHeader("fixed header"),
          SizedBox(height: 30),
          Expanded(
            child: SingleChildScrollView(
              physics: AlwaysScrollableScrollPhysics(),
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    _buildHeader("GridSection", Colors.blue),
                    _buildGridView(),
                    _buildHeader("PageViewSection", Colors.blue),
                    _buildPageView(),
                    _buildHeader("ListSection", Colors.blue),
                    _buildListView(),
                  ]),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildHeader(String s, [Color c = Colors.red]) {
    return Container(
        width: double.infinity,
        height: 100,
        color: c,
        child: Center(
            child: Text(
          s,
          style: TextStyle(fontSize: 40, color: Colors.white),
        )));
  }

  Container _buildListView() {
    return Container(
      child: ListView.builder(
        physics: NeverScrollableScrollPhysics(),
        shrinkWrap: true,
        padding: const EdgeInsets.all(8),
        itemCount: 30,
        itemBuilder: (BuildContext context, int index) {
          return Center(
              child: Text(
            "${index}",
            style: TextStyle(fontSize: 30),
          ));
        },
      ),
    );
  }

  Container _buildGridView() {
    return Container(
      child: GridView.builder(
          physics: NeverScrollableScrollPhysics(),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            mainAxisSpacing: 5,
            crossAxisSpacing: 5,
          ),
          itemCount: 10,
          shrinkWrap: true,
          itemBuilder: (BuildContext context, int index) {
            var url = (index % 2 == 0)
                ? "https://gamingbolt.com/wp-content/uploads/2020/01/Soulcalibur-6-Haohmaru.jpg"
                : "https://static.wikia.nocookie.net/snk/images/7/76/Haohmarusamsho2019render.png/revision/latest?cb=20190405071050";
            return Container(child: Image.network(url));
          }),
    );
  }
}

// 웹과 desktop에서 모바일처럼 터치 스크롤 지원하기 위함
class DeskScrollBehavior extends MaterialScrollBehavior {
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}

 

Comments