[flutter/dart] 슬라이드 컨테이너 만들기

yevvon·2024년 6월 9일
0

flutter

목록 보기
10/12

여러개의 목록을 n개의 목록으로 쪼개 슬라이드 하면 다음 장으로 넘어가는 컨테이너를 만들어보도록 하겠습니다.

final PageController _pageController = PageController();
int _currentPageIndex = 0;

먼저 페이지 컨트롤러와 현재 페이지를 알 수 있는 변수가 필요합니다.

  @override
  void initState() {
    super.initState();
    _pageController.addListener(() {
      setState(() {
        _currentPageIndex = _pageController.page!.round();
      });
    });
  }

초기화 해주세요

  Widget _buildPageIndicator() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(5, (index) {
        return Container(
          width: 8.0,
          height: 8.0,
          margin: EdgeInsets.symmetric(horizontal: 4.0),
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: index == _currentPageIndex ? Colors.black : Colors.white,
          ),
        );
      }),
    );
  }

전체 페이지 수와 현재 페이지를 알려주는 인디케이터입니다.

이렇게 생겼습니다

 PageView.builder(
                  controller: _pageController,
                  itemCount: 5,
                  itemBuilder: (context, pageIndex) {
                    return ListView.builder(
                      itemCount: 5,
                      itemBuilder: (context, itemIndex) {
                        final index = pageIndex * 5 + itemIndex;
                        if (index <10) {
                          return GestureDetector(
                            onTap: () {},
                            child: Container(
                              child: Column(
                                crossAxisAlignment:
                                CrossAxisAlignment.start,
                                children: [
                                  Padding(
                                    padding: EdgeInsets.fromLTRB(15, 10, 3, 0),
                                    child: 
                                    Text(
                                      '제목',
                                      style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 15,
                                      ),
                                    ),
                                  ),
                                  SizedBox(height: 4),
                                  Container(
                                    padding: EdgeInsets.symmetric(
                                        horizontal: 10),
                                    child: Divider(
                                      color: Colors.grey,
                                      height: 1,
                                    ),
                                  ),
                                  Container(
                                    width: double.infinity,
                                    height: 37.5,
                                    padding: EdgeInsets.fromLTRB(
                                        17, 5, 10, 0),
                                    child: Text(
                                      '내용',
                                      style: TextStyle(fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                  ),
                                  Container(
                                    padding: EdgeInsets.symmetric(
                                        horizontal: 8),
                                    child: Divider(
                                      color: Colors.white,
                                      height: 2,
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          );
                        } else {
                          return SizedBox(); // 아이템이 부족한 경우 빈 SizedBox 반환
                        }
                      },
                    );
                  },
                ),

GestureDetector는 사용자 동작을 감지하는 위젯입니다.

저는 itemCount를 5로 하여 한페이지에 5개씩 보이도록 해주었습니다.


제목과 내용 부분은 divider을 이용하여 ui를 만들어주었습니다.

최종ui입니다. 안에 내용은 통신하시거나 배열 인덱스 값으로 구분해주시면 다른 제목과 내용이 들어갈 것입니다.

전체코드

import 'package:flutter/material.dart';

void main() async {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: myApp(),
    );
  }
}

class myApp extends StatefulWidget {
  @override
  State<myApp> createState() => _myAppState();
}

class _myAppState extends State<myApp> {
  final PageController _pageController = PageController();
  int _currentPageIndex = 0;


  @override
  void initState() {
    super.initState();
    _pageController.addListener(() {
      setState(() {
        _currentPageIndex = _pageController.page!.round();
      });
    });
  }

  Widget _buildPageIndicator() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(5, (index) {
        return Container(
          width: 8.0,
          height: 8.0,
          margin: EdgeInsets.symmetric(horizontal: 4.0),
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: index == _currentPageIndex ? Colors.black : Colors.white,
          ),
        );
      }),
    );
  }

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

    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(
        title: Text("MyApp"),
      ),
      body: Container(
        width: sizeX * 0.8,
        height: 450,
        padding: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SizedBox(
              height: 20,
            ),
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  color: Color(0xFFE8E8E8),
                  borderRadius: BorderRadius.circular(7),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black12,
                      spreadRadius: 2,
                      offset: Offset(3, 3),
                    ),
                  ],
                ),
                child: PageView.builder(
                  controller: _pageController,
                  itemCount: 5,
                  itemBuilder: (context, pageIndex) {
                    return ListView.builder(
                      itemCount: 5,
                      itemBuilder: (context, itemIndex) {
                        final index = pageIndex * 5 + itemIndex;
                        if (index <10) {
                          return GestureDetector(
                            onTap: () {},
                            child: Container(
                              child: Column(
                                crossAxisAlignment:
                                CrossAxisAlignment.start,
                                children: [
                                  Padding(
                                    padding: EdgeInsets.fromLTRB(15, 10, 3, 0),
                                    child:
                                    Text(
                                      '제목',
                                      style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 15,
                                      ),
                                    ),
                                  ),
                                  SizedBox(height: 4),
                                  Container(
                                    padding: EdgeInsets.symmetric(
                                        horizontal: 10),
                                    child: Divider(
                                      color: Colors.grey,
                                      height: 1,
                                    ),
                                  ),
                                  Container(
                                    width: double.infinity,
                                    height: 37.5,
                                    padding: EdgeInsets.fromLTRB(
                                        17, 5, 10, 0),
                                    child: Text(
                                      '내용',
                                      style: TextStyle(fontSize: 13),
                                      overflow: TextOverflow.ellipsis,
                                    ),
                                  ),
                                  Container(
                                    padding: EdgeInsets.symmetric(
                                        horizontal: 8),
                                    child: Divider(
                                      color: Colors.white,
                                      height: 2,
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          );
                        } else {
                          return SizedBox(); // 아이템이 부족한 경우 빈 SizedBox 반환
                        }
                      },
                    );
                  },
                ),
              ),
            ),
            SizedBox(
              height: 10,
            ),
            _buildPageIndicator(),
          ],
        ),
      ),
    );
  }
}

0개의 댓글

관련 채용 정보