• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 Flutter 게시판 provider로 바꿨더니 에러가 뜹니다

provider로 바꿨더니 에러가 뜹니다

5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 글쓴이
  • #48947

    산딸기
    참가자
    initState() 문제인듯합니다.
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    import 'package:image_picker/image_picker.dart';
    import 'dart:io';
    import 'package:provider/provider.dart';
     
    void main() {
      runApp(ChangeNotifierProvider(
          create: (c) => Store1(),
         child: MaterialApp(
        theme:ThemeData(
          textButtonTheme: TextButtonThemeData(
            style:TextButton.styleFrom(
              backgroundColor: Colors.grey
            )
          ),
          appBarTheme:AppBarTheme(
            color:Colors.white,
            elevation: 1,
            titleTextStyle:TextStyle(color:Colors.black,fontSize: 25),
            actionsIconTheme: IconThemeData(color:Colors.black),
          ),
          textTheme:TextTheme(
           bodyText2:TextStyle(color:Colors.red)
        )
        ),
          home: MyApp()
        )
      )
      );
    }
     
    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
      @override
      State<MyApp> createState() => _MyAppState();
    }class _MyAppState extends State<MyApp> {
      @override
      void initState() {
        super.initState();
        context.watch<Store1>().getData();
      }
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text('instagram'),
              actions:[
                IconButton(
                  icon:Icon(Icons.add_box_outlined),
                  onPressed: ()async{
                      var picker = ImagePicker();
                      var image = await picker.pickImage(source: ImageSource.gallery);
                      if (image != null) {
                        context.watch<Store1>().userImage = File(image.path);
                      }
                    Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => Upload(
                      )));},
                  iconSize: 30,
                )
              ]
            ),
          body: [Home(),Profile()][context.watch<Store1>().tab],
          bottomNavigationBar:BottomNavigationBar(
            showSelectedLabels: false,
            showUnselectedLabels: false,
            onTap: (i) {
              context.watch<Store1>().tab = i;
            },
            items: [
              BottomNavigationBarItem(icon:Icon(Icons.home_outlined),label:'홈'),
              BottomNavigationBarItem(icon:Icon(Icons.shopping_bag_outlined),label:'샵')
            ],
          ),
        );
      }
    }
    class Store1 extends ChangeNotifier {
      var data=[];
      var name = 'john kim';
      var follower = 0;
      var friend = false;
      var profileImage =[];
      var tab=0;
      var userImage;
      var userContent;
      setUserContent(a){
        userContent = a;
        notifyListeners();
      }
      addMyData(){
        var myData = {
          'id': data.length,
          'image': userImage,
          'likes': 5,
          'date': 'July 25',
          'content': userContent,
          'liked': false,
          'user': 'John Kim'
        };
        data.insert(0, myData);
        notifyListeners();
      }
      getData() async {
        var result = await http
            .get(Uri.parse('https://codingapple1.github.io/app/data.json'));
        
        var result2 = jsonDecode(result.body);
        profileImage = result2;
        
        notifyListeners();
      }
      addFollower() {
        if (friend == false) {
          follower++;
          friend = true;
        } else {
          follower--;
          friend = false;
        }
        notifyListeners(); 
      }
    }
    class Home extends StatefulWidget {
      const Home({Key? key}) : super(key: key);
      @override
      State<Home> createState() => _HomeState();
    }
    class _HomeState extends State<Home> {
      @override
      Widget build(BuildContext context) {
          if(context.watch<Store1>().data.isNotEmpty){
            return ListView.builder(itemCount:context.watch<Store1>().data.length, itemBuilder: (c, i){
            return Column(
              children: [
                context.watch<Store1>().data[i]['image'].runtimeType == String
                    ? Image.network(context.watch<Store1>().data[i]['image'])
                    : Image.file(context.watch<Store1>().data[i]['image']),
                Container(
                  constraints: BoxConstraints(maxWidth: 600),
                  padding: EdgeInsets.all(20),
                  width: double.infinity,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text('좋아요${context.watch<Store1>().data[i]['likes']}'),
                      Text(context.watch<Store1>().data[i]['date']),
                      Text(context.watch<Store1>().data[i]['content']),
                    ],
                  ),
                )
              ],
            );
          });
          }else {return Text('로딩중임');}
      }
    }
    class Upload extends StatelessWidget {
      const Upload({Key? key}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            resizeToAvoidBottomInset: false,
            appBar: AppBar( actions: [
              IconButton(onPressed: (){context.watch<Store1>().addMyData();}, icon: Icon(Icons.send))
            ]),
            body: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Image.file(context.watch<Store1>().userImage),
                Text('이미지업로드화면'),
                TextField(onChanged: (text){ context.watch<Store1>().setUserContent(text); }),
                IconButton(
                    onPressed: (){Navigator.pop(context);},
                    icon: Icon(Icons.close)
                ),
              ],
            )
        );
      }
    }
    void tmpFunction() {
      print('Function Called.');
    }
    class Profile extends StatelessWidget {
      const Profile({Key? key}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title:Text(context.watch<Store1>().name) ),
          body:CustomScrollView(
            slivers: [
              SliverToBoxAdapter(
                  child: ProfileHeader()),
              SliverGrid(
                  delegate: SliverChildBuilderDelegate(
                        (c,i) =>GestureDetector(
                                onTap: tmpFunction,
                                child: Image.network(context.watch<Store1>().profileImage[i])
                        ),
                      childCount: context.watch<Store1>().profileImage.length,
                  ),
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2 ))
            ],
          )
        );
      }
    }
     
    class ProfileHeader extends StatelessWidget {
      const ProfileHeader({Key? key}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return
          Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            CircleAvatar(radius: 80,backgroundColor: Colors.grey),
            Text('이름',style:TextStyle(fontSize: 30)),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Text('포스트',style:TextStyle(fontSize: 20) ),
                Text('팔로워 ${context.watch<Store1>().follower}명'),
                Text('팔로우',style:TextStyle(fontSize: 20)),
                ElevatedButton(
                    onPressed: () {
                      context.read<Store1>().getData();
                    },
                    child: Text('사진가져오기'))
              ],
            )
          ],
        );
      }
    }
    
    #49025

    산딸기
    참가자
    Provider를 initState안에 넣었을 때 예외가 발생합니다. 어떻게 해야하나요?
    이 예외는 다시 호출되지 않는 생명 주기(life-cycle)에서 provider를 감지하려고 하기 때문에 발생합니다.
    때문에 build와 같은 다른 생명 주기에서 사용하거나, 업데이트에 관련 없음을 명시해주어야합니다.
    때문에 아래와 같이 작성하는 대신,
    initState() {
      super.initState();
      print(context.watch<Foo>().value);
    }
    이렇게 작성할 수 있습니다.
    Value value;
    Widget build(BuildContext context) {
      final value = context.watch<Foo>.value;
      if (value != this.value) {
        this.value = value;
        print(value);
      }
    }
    이는 값이 변경될 때마다(그리고 변경될 때만) 'value가 출력됩니다.
    또는 다음과 같이 작성할 수 있습니다.
    initState() {
      super.initState();
      print(context.read<Foo>().value);
    }
    이는 value를 한번 출력하고 업데이트를 무시합니다.
    ---------------------------
    watch를 read로 바꾸니 if문의else인 '로딩중임'만 뜹니다. 플러터 provider 공식문서를 읽어도 잘 모르겠습니다....ㅠㅠㅠ
    검색하면 다 옛날 문법이라 모르겠고, 메뉴얼에 명시된건 state변수라서 함수인 경우는 메뉴얼을 또 모르겠습니다.
    
    
     
     
    #49042

    산딸기
    참가자
    코딩실수엿네여.... 홈페이지는 되는데 이젠 샵페이지가 안나옵니다...헐;;;
     
    #49043

    산딸기
    참가자
    watch를 read로 고치니까 화면은 나옵니다....-_-;;;; 근데 시험해보면 임시방편이었고 watch에서read로 바꿨을때 처음만 되고 다시 렌더링해보면onTap이 안먹힙니다..onTap: (i) {
              context.watch<Store1>().tab = i;
            },.-_-;;; 근본적인 해결책이 뭐일까요...-_-;;;
    
    #49066

    codingapple
    키 마스터
    initState안에서 뭐라고 하면 거기 안에선 read만 씁시다
    provider 안의 값 수정은 등호말고 수정함수 만들어서 씁시다
5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠