ABOUT ME

-

  • [ Flutter ] ListView Auto Scroll Controller
    Application/Flutter 2024. 12. 15. 13:24
    반응형

    값을 선택하는 스크롤이 있는 영역에서 특정 값을 파라미터로 보냈을때 해당 값으로 자동으로 스크롤이 되도록 처리


    ListView Scroll

    https://yumedev.tistory.com/27

     

    [ Flutter ] Horizontal Scroll ListView, Global Key

    OnBoarding에서 초기 설정을 처리하기 위해서요일과 금액을 세팅해야 화면을 넘어가게 처리 그 과정에서 요일 선택에서 datePicker를 사용할까 하다가 요일만 필요하기에 새로운 방법을 고민하다가S

    yumedev.tistory.com

    이전에 만들었던 스크롤을 다시 사용하다보니 값 전달을 할때 스크롤이 그대로 유지 되는 경우가 발생

    값이 1일때와 10 이상의 값이 들어왔을때 스크롤이 안되어 있어서 들어온 값을 기준으로 스크롤이 되게 처리

     

    재사용을 하다보니 해당 기능 위젯으로 분리하여 사용

     

    사용자가 선택한 날짜를 파라미터로 받아서 사용 안받는 경우도 고려하여 ? 를 추가하여 처리

     

    scroll을 control 하기 위해서 controller를 ListView에 추가

     child: ListView.builder(
              controller: _scrollController,
              scrollDirection: Axis.horizontal,
              itemCount: list.length,

     

    위젯이 처음 실행될때 선택된 값은 전달된 값을 가져오고 없다면 1로 세팅

     

    WidgetsBinding.instance.addPostFrameCallback은 화면을 렌더링 한 후에 해당 동작을 실행 시켜준다.

    따라서 로딩이 된후에 선택된 값으로 스크롤이 되는 동작을 추가하여 선택된 값으로 스크롤이 되도록 처리하는 로직을 추가

     

    jumpTo는 스크롤 위치로 즉시 이동시켜준다.

    따라서 index * 26.0을 통해 해당 index * 26 px 위치로 이동시켜준다.

    late String selectedValue;
      late ScrollController _scrollController;
    
      @override
      void initState() {
        super.initState();
    
        selectedValue = widget.incomeDate ?? "1";
    
        _scrollController = ScrollController();
    
        WidgetsBinding.instance.addPostFrameCallback((_) {
          final index = list.indexOf(selectedValue);
          if (index != -1) {
            _scrollController.jumpTo(index * 26.0);
          }
        });
      }

     

    이제 17값을 파라미터로 전달하면 해당 위젯이 나올때 해당 위치로 스크롤이 되는 것을 확인 할 수 있다.

     

    jumpTo를 할때 px값은 각 container의 width값과 margin값을 고려하였고, 선택한 값이 가운데에 위치할 수 있도록 고려하여

    index * 26px로 정하였다.

     

    [ 전체 코드 ]

    import 'package:flutter/material.dart';
    import 'package:sumgo/config/colors.dart';
    
    class SelectDateWidget extends StatefulWidget {
      final String? incomeDate;
    
      const SelectDateWidget({this.incomeDate, super.key});
    
      @override
      State<SelectDateWidget> createState() => _SelectDateWidgetState();
    }
    
    class _SelectDateWidgetState extends State<SelectDateWidget> {
      final List<String> list =
          List.generate(31, (index) => (index + 1).toString());
    
      late String selectedValue;
      late ScrollController _scrollController;
    
      @override
      void initState() {
        super.initState();
    
        selectedValue = widget.incomeDate ?? "1";
    
        _scrollController = ScrollController();
    
        WidgetsBinding.instance.addPostFrameCallback((_) {
          final index = list.indexOf(selectedValue);
          if (index != -1) {
            _scrollController.jumpTo(index * 26.0);
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: scrollDate(),
        );
      }
    
      Container scrollDate() {
        return Container(
          height: 32.0,
          child: ListView.builder(
              controller: _scrollController,
              scrollDirection: Axis.horizontal,
              itemCount: list.length,
              itemBuilder: (context, index) {
                return GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedValue = list[index];
                    });
                  },
                  child: Container(
                    margin: EdgeInsets.fromLTRB(6.0, 0, 0, 0),
                    width: 32.0,
                    child: Container(
                      decoration: BoxDecoration(
                          color: list[index].toString() == selectedValue
                              ? mint
                              : boxColor,
                          borderRadius: BorderRadius.circular(50),
                          border: Border.all(color: mint, width: 0.5)),
                      child: Center(
                          child: Text(
                        list[index].toString(),
                        style: TextStyle(
                            color: list[index].toString() == selectedValue
                                ? Colors.white
                                : textColor,
                            fontSize: 13.0),
                      )),
                    ),
                  ),
                );
              }),
        );
      }
    }

     

    728x90
    반응형

    'Application > Flutter' 카테고리의 다른 글

    [ Flutter ] BottomModal CallBack Function  (0) 2024.12.22
    [ Flutter ] App Icon Generate  (0) 2024.12.22
    [ Flutter ] Text Rich  (0) 2024.12.14
    [ Flutter ] Bottom Modal Keyboard Avoider  (0) 2024.12.08
    [ Flutter ] Blurry Text  (0) 2024.11.17