커뮤니티
포인트
쿠폰
내 강의실
국비 신청 내역
증명서
계정
로그아웃
학습 질문
개발 일지
나의 활동
답변 완료
GridView 위젯 사용시 Expanded 위젯으로 감싸도 스크롤이 안될 때가 있는데 원인이 뭔가요?
[왕초보] 플러터(Flutter)로 시작하는 앱개발 종합반 v0
2주차
북마크
이*석
댓글
5
추천
0
조회수
14
조회수
14
답변 완료

* 겪고 있는 문제 상황을 최대한 자세하게 작성해주세요.

* 문제 해결을 위해 어떤 시도를 해보았는지 구체적으로 함께 알려주세요.


첫번째 화면을 만들고 있습니다.

예시답안에서는 GridView 위젯을 Expanded 위젯으로 감싸서 스크롤 문제를 해결했는데요,

어디서 잘못된건지 저는 그게 안됐습니다.


한창 헤메다가, 상단의 Column에도 또 Expanded를 씌워보니 해결이 되었는데요,

왜 Expanded를 중첩시키는건 되고,

예시답안에도 있는방식인 GridView에만 Expanded를 씌우는건 안되는건지 이해가 안갔습니다.


제 코드에서는 어떤부분에 문제가 있어서 Expanded 하나만으로는 안되었던건지 확인하고싶습니다.


감사합니다.








// 첫번째 페이지
class FirstTab extends StatelessWidget {
  const FirstTab({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    const songs = [
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
    ];


    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 8),
        child: Column(
          children: [
            const Row(

              // 라이브러리
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Expanded(flex: 1, child: Icon(Icons.settings, size: 35)),
                Expanded(
                  flex: 5,
                  child: Text('라이브러리', textAlign: TextAlign.center),
                ),
                Expanded(flex: 1, child: Text(''))
              ],
            ),
            Expanded(  // 여기에 Expanded가 있어야만 아래의 GridView가 작동했습니다.
              child: Padding(  //혹시나 싶어 이 padding도 없애봤지만, 윗줄의 Expanded가 없으면 GridView가 작동하지 않았습니다.
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: Column(
                  children: [

                    // Shazam
                    Row(
                      children: [
                        Container(
                          height: 35,
                          width: 35,
                          alignment: Alignment.center,
                          child: Image.network(
                            "https://i.ibb.co/hxNbZ8p/shazam.png",
                            height: 30,
                            width: 30,
                          ),
                        ),
                        const Text('Shazam',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ],
                    ),
                    const Divider(),
                    // Shazam
                    const Row(
                      children: [
                        Icon(Icons.person, size: 35),
                        Text('아티스트',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ],
                    ),
                    const Divider(),

                    // 회원님을 위한 재생 목록
                    const Row(
                      children: [
                        Icon(Icons.music_note, size: 35),
                        Text('회원님을 위한 재생 목록',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ],
                    ),

                    // 최근 Shazam
                    const Padding(
                      padding: EdgeInsets.symmetric(vertical: 15),
                      child: Row(children: [
                        Text('최근 Shazam',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ]),
                    ),


                    // GridView
                    Expanded(
                      child: GridView.builder(
                          itemCount: 6,
                          gridDelegate:
                              const SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 2,
                            childAspectRatio: 2 / 3,
                            crossAxisSpacing: 5,
                            mainAxisSpacing: 5,
                          ),
                          itemBuilder: (context, index) {
                            return Card(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Image.network(
                                    'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
                                    fit: BoxFit.fill,
                                    height: 180,
                                    width: 190,
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.all(4),
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        const Text(
                                          '가을밤에 든 생각',
                                          style: TextStyle(
                                              fontSize: 15,
                                              fontWeight: FontWeight.bold),
                                        ),
                                        const Text(
                                          '잔나비',
                                          style: TextStyle(color: Colors.grey),
                                        ),
                                        const SizedBox(
                                          height: 30,
                                        ),
                                        Image.network(
                                          "https://i.ibb.co/KG9m5QS/applemusic.png",
                                          width: 60,
                                        )
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            );
                          }),
                    )
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}




혹시나 싶어 전체 코드도 올립니다.


import 'package:flutter/material.dart';


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


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


  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Shazam',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}


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


  @override
  State<HomePage> createState() => _HomePageState();
}


class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      initialIndex: 1,
      length: 3,
      child: Builder(builder: (context) {
        DefaultTabController.of(context).addListener(() {
          setState(() {});
        });


        return Scaffold(
          body: Stack(
            children: [
              const TabBarView(
                children: [
                  FirstTab(),
                  SecondTab(),
                  ThirdTab(),
                ],
              ),
              SafeArea(
                child: Padding(
                  padding:
                      const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
                  child: Column(
                    children: [
                      Container(
                        alignment: Alignment.topCenter,
                        child: TabPageSelector(
                          color: DefaultTabController.of(context).index == 1
                              ? Colors.blue[300]
                              : Colors.grey[400],
                          selectedColor:
                              DefaultTabController.of(context).index == 1
                                  ? Colors.white
                                  : Colors.blue,
                          indicatorSize: 8,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
      }),
    );
  }
}


// 첫번째 페이지
class FirstTab extends StatelessWidget {
  const FirstTab({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    const songs = [
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
      {
        'imageUrl': 'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
        'title': '가을밤에 든 생각',
        'artist': '잔나비',
      },
    ];


    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 8),
        child: Column(
          children: [
            const Row(
              // 라이브러리
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Expanded(flex: 1, child: Icon(Icons.settings, size: 35)),
                Expanded(
                  flex: 5,
                  child: Text('라이브러리', textAlign: TextAlign.center),
                ),
                Expanded(flex: 1, child: Text(''))
              ],
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: Column(
                  children: [
                    // Shazam
                    Row(
                      children: [
                        Container(
                          height: 35,
                          width: 35,
                          alignment: Alignment.center,
                          child: Image.network(
                            "https://i.ibb.co/hxNbZ8p/shazam.png",
                            height: 30,
                            width: 30,
                          ),
                        ),
                        const Text('Shazam',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ],
                    ),
                    const Divider(),
                    // Shazam
                    const Row(
                      children: [
                        Icon(Icons.person, size: 35),
                        Text('아티스트',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ],
                    ),
                    const Divider(),
                    // 회원님을 위한 재생 목록
                    const Row(
                      children: [
                        Icon(Icons.music_note, size: 35),
                        Text('회원님을 위한 재생 목록',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ],
                    ),
                    // 최근 Shazam
                    const Padding(
                      padding: EdgeInsets.symmetric(vertical: 15),
                      child: Row(children: [
                        Text('최근 Shazam',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 17))
                      ]),
                    ),


                    // GridView
                    Expanded(
                      child: GridView.builder(
                          itemCount: 6,
                          gridDelegate:
                              const SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 2,
                            childAspectRatio: 2 / 3,
                            crossAxisSpacing: 5,
                            mainAxisSpacing: 5,
                          ),
                          itemBuilder: (context, index) {
                            return Card(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Image.network(
                                    'https://i.ytimg.com/vi/jAO0KXRdz_4/hqdefault.jpg',
                                    fit: BoxFit.fill,
                                    height: 180,
                                    width: 190,
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.all(4),
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,
                                      children: [
                                        const Text(
                                          '가을밤에 든 생각',
                                          style: TextStyle(
                                              fontSize: 15,
                                              fontWeight: FontWeight.bold),
                                        ),
                                        const Text(
                                          '잔나비',
                                          style: TextStyle(color: Colors.grey),
                                        ),
                                        const SizedBox(
                                          height: 30,
                                        ),
                                        Image.network(
                                          "https://i.ibb.co/KG9m5QS/applemusic.png",
                                          width: 60,
                                        )
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            );
                          }),
                    )
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}


// 두번째 페이지
class SecondTab extends StatelessWidget {
  const SecondTab({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [Colors.blue[300]!, Colors.blue[900]!],
        ),
      ),
      child: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
          child: Column(
            children: [
              const Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Column(
                    children: [
                      Icon(Icons.person, color: Colors.white),
                      Text('라이브러리', style: TextStyle(color: Colors.white))
                    ],
                  ), //라이브러리
                  Column(
                    children: [
                      Icon(Icons.show_chart, color: Colors.white),
                      Text('차트', style: TextStyle(color: Colors.white))
                    ],
                  ), //차트
                ],
              ),
              Expanded(
                flex: 1,
                child: Container(
                  alignment: Alignment.bottomCenter,
                  child: const Text(
                    'Shazam하려면 탭하세요',
                    style: TextStyle(color: Colors.white, fontSize: 23),
                  ),
                ),
              ), // Shazam하려면 탭하세요
              Expanded(
                flex: 2,
                child: Container(
                  alignment: Alignment.center,
                  height: 200,
                  width: 200,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.blue[300],
                  ),
                  child: IconButton(
                    onPressed: () {},
                    icon: Image.network(
                      "https://i.ibb.co/hxNbZ8p/shazam.png",
                      color: Colors.white,
                      width: 130,
                      height: 130,
                    ),
                  ),
                ),
              ), // 큰 shazam 아이콘
              Expanded(
                flex: 2,
                child: Container(
                  alignment: Alignment.topCenter,
                  width: 100,
                  height: 100,
                  child: IconButton(
                    iconSize: 50,
                    color: Colors.white,
                    style:
                        IconButton.styleFrom(backgroundColor: Colors.blue[300]),
                    onPressed: () {},
                    icon: const Icon(Icons.search),
                  ),
                ),
              ), // search 아이콘
            ],
          ),
        ),
      ),
    );
  }
}


// 세번째 페이지
class ThirdTab extends StatelessWidget {
  const ThirdTab({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    const chartData = {
      'korea': [
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
      ],
      'global': [
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
      ],
      'newyork': [
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
        {
          'imageUrl': 'https://i.ibb.co/xf2HpfG/dynamite.jpg',
          'name': 'Dynamite',
          'artist': 'BTS',
        },
      ],
    };


    return SafeArea(
      child: ListView(
        children: [
          const Text(
            '차트',
            style: TextStyle(fontSize: 20),
          ),
          Container(
            color: Colors.purple[900],
            height: 200,
            width: double.infinity,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.8,
                  child: ElevatedButton(
                      onPressed: () {}, child: const Text('국가 및 도시별 차트')),
                ),
                const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                    '전 세계',
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ],
            ),
          ),
          Container(color: Colors.grey, height: 10),
          HorizontalAlbumView(
              subTitle: '대한민국 차트', nationalData: chartData['korea']),
          Container(color: Colors.grey, height: 10),
          HorizontalAlbumView(
              subTitle: '글로벌 차트', nationalData: chartData['global']),
          Container(color: Colors.grey, height: 10),
          HorizontalAlbumView(
              subTitle: '뉴욕 차트', nationalData: chartData['newyork']),
        ],
      ),
    );
  }
}


class HorizontalAlbumView extends StatelessWidget {
  const HorizontalAlbumView({
    super.key,
    required this.subTitle,
    required this.nationalData,
  });


  final String subTitle;
  final nationalData;


  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: SizedBox(
        height: 250,
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  subTitle,
                  style: const TextStyle(fontSize: 18),
                ),
                Text('모두 보기', style: TextStyle(color: Colors.blue[300])),
              ],
            ),
            Expanded(
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: nationalData.length,
                itemBuilder: (context, index) {
                  final data = nationalData[index];
                  final imageUrl = data['imageUrl'];
                  final name = data['name'];
                  final artist = data['artist'];


                  return Padding(
                    padding: const EdgeInsets.only(right: 8, top: 8, bottom: 8),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Image.network(
                          imageUrl!,
                          height: 150,
                          width: 150,
                        ),
                        Text(name!,
                            style:
                                const TextStyle(fontWeight: FontWeight.bold)),
                        Text(artist!,
                            style: TextStyle(color: Colors.grey[900])),
                      ],
                    ),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}


취소
 공유
취소
댓글 0
댓글 알림
나의얼굴