[Flutter] 분리젯 위젯에서 값 넘겨주는 방법

코딩하는범이·2020년 11월 20일
0
post-thumbnail

Flutter 앱 개발을 하면서 느낀점은 하나의 페이지에 모든 코드를 넣기에 Dart라는 언어는 너무 길어지고 보기가 힘들어진다. 그래서 개발하다가 widget을 분리해서 main.dart 에는 분리된 위젯들로 구성을 시켜놨는데 api 통신을 위해 main.dart 에서 값을 받아야 하는 경우가 있다.

아래는 Widget으로 분리한 body의 모습이다.

main.dart

        .
        .	
        .
body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
        child: SingleChildScrollView(
          child: Column(
            children: [
              ColorSelectSlide(),
              Sample1(),
              Sample2()
                    .
                    .
                    .
            ],
          ),
        ),
      )

위 예제와 같이 나누어져 있다고 가정을 하고 ColorSelectSlide 라는 클래스에서 선택된 색상 값을 받아 오고자 한다.

받아 오기전 내가 겪었던 오류를 범하자면...
main.dart 에서 만든 변수를 ColorSelectSlide의 생성자에 Color 변수를 넣어서 setState를 이용해 값을 변경하려고 했지만 변경되지 않았다.

그래서 찾다보니 ValueChanged 라는 클래스를 이용해서 변경하는 방법을 찾아냈다.

colorSelectSlide.dart

class ColorSelectSlide extends StatefulWidget {

  final ValueChanged<Color> changedColor;

  ColorSelectSlide({Key key,this.changedColor}) : super(key:key);

  @override
  _ColorSelectSlideState createState() => _ColorSelectSlideState();

  //더미 데이터 컬러
  final List<Color> colors = [
    Color.fromRGBO(255, 108, 108, 1.0),
    Color.fromRGBO(255, 120, 78, 1.0),
    Color.fromRGBO(255, 184, 10, 1.0),
  ];

}

class _ColorSelectSlideState extends State<ColorSelectSlide> {


  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Text("색상",
                textAlign: TextAlign.left,
                style: TextStyle(fontWeight: FontWeight.bold))
          ],
        ),
        SizedBox(height: 7),
        Container(
            height: 70.0,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              padding: EdgeInsets.all(8),
              itemCount: widget.colors.length,
              itemBuilder: (context, index) {
                return InkWell(
                  onTap: () {
                    setState(() {
                      widget.changedColor(widget.colors[index]);
                    });
                  },
                child: CircleAvatar(
                  radius: 25,
                  backgroundColor: widget.colors[index],
                )
                );
              },
            ))
      ],
    );
  }

}

위와 같이 ValueChanged<Color> changedColor; 를 이용하게 되면 값을 ColorSelectSlide에서 변경하는게 아닌 Main에서 변경 할 수 있다.

main.dart

Color _color;
        .
        .	
        .
      (생략)
body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
        child: SingleChildScrollView(
          child: Column(
            children: [
              ColorSelectSlide(
                changedColor: (value) {
                  _color = value;
                  print(_color);
                },
              ),
              Sample1(),
              Sample2()
                    .
                    .
                    .
            ],
          ),
        ),
      )

색상을 탭 했을때 widget.changedColor(element.color); 함수가 호출되고 Main 에서 _color 변수에 넘어온 값을 넣는다.
print(_color); 를 통해 찍어보면 잘 찍히는 것을 볼 수있다.

다만 이런식으로 값을 넘겨주는 방법은 개발자가 쉽게 파악 하기가 쉽지 않기 때문에 Provider 패턴을 이용해서 값을 받는게 좋다.

끗!!

profile
기록 그리고 기억

0개의 댓글