5 글 보임 - 1 에서 5 까지 (총 5 중에서)
-
글쓴이글
-
2022년 10월 4일 09:51 #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('사진가져오기')) ], ) ], ); } }
2022년 10월 4일 11:45 #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변수라서 함수인 경우는 메뉴얼을 또 모르겠습니다.
2022년 10월 4일 13:09 #49043
산딸기참가자watch를 read로 고치니까 화면은 나옵니다....-_-;;;; 근데 시험해보면 임시방편이었고 watch에서read로 바꿨을때 처음만 되고 다시 렌더링해보면onTap이 안먹힙니다..onTap: (i) { context.watch<Store1>().tab = i; },.-_-;;; 근본적인 해결책이 뭐일까요...-_-;;;
2022년 10월 4일 14:55 #49066
codingapple키 마스터initState안에서 뭐라고 하면 거기 안에선 read만 씁시다 provider 안의 값 수정은 등호말고 수정함수 만들어서 씁시다
-
글쓴이글
5 글 보임 - 1 에서 5 까지 (총 5 중에서)
- 답변은 로그인 후 가능합니다.