inflearn logo
강의

Course

Instructor

Flutter Beginner - Http Communication, State Management

화면새로고침 질문.

1491

chorokdosi

8 asked

0

커뮤니티 앱을 만들고 있습니다. 그런데 막히는 부분이 있어서 질문드립니다.

글작성 버튼 클릭 후 화면이동 후 목록화면에서 화면을 그릴때 새로운 데이터(DB)가 있으면 바로 그려서 보여줘야하는데 그러지못하고있습니다.

상태관리를 하면 될거같은데 어떤식으로 해야할지모르겠습니다.

 RefreshIndicator(
  onRefresh: () async {
    setState(() => communityViewModel.onEvent(CommunityEvent.community_query()));
    await Future.delayed(Duration(seconds: 3));
  },

스크롤을 내렸을때 새로운데이터를 가져오는 것은 이런식으로 코드작성하니 새로운 데이터를 가져옵니다.

android Flutter 웹앱 ios

Answer 1

0

survivalcoding

화면을 이전 화면으로 돌아갈 때 Navigator.push 와 pop 을 사용하여 어떤 값을 전달할 수 있습니다.

글 작성 완료와 같은 의미의 데이터를 돌려준 후에 그 값에 따라서 데이터를 다시 읽어오시면 됩니다.

다음 링크를 참고해 보세요.

https://docs.flutter.dev/cookbook/navigation/returning-data

0

chorokdosi

글목록페이지와 글작성페이지가 BottomNavigationBar로 화면 이동 중에 있습니다. 그러면 글작성페이지에서 버튼클릭시에 값을 넣어서 넘겨줘야 할까요?

0

survivalcoding

그럼 그냥 글목록페이지의 initState() 에서 목록을 가져와야 할 것 같습니다

0

chorokdosi

initState()에서 communityViewModel.onEvent(CommunityEvent.community_query())를 호출하면 에러가 발생합니다.

dependOnInheritedWidgetOfExactType<_InheritedProviderScope<CommunityViewModel?>>() or dependOnInheritedElement() was called before _HomeCommunityPageState.initState() completed.

역시 저렇게 호출하면 안될거같은데 어떻게 불러와야할까요?

0

survivalcoding

initState() 에서 ViewModel 을 부를때 context를 사용한다면 Future.microtask 같이 약간의 딜레이가 필요합니다.

image

0

chorokdosi

아하 그렇군요 참고해서 시도 했는데 여전히 오류가 발생합니다.

시도1 .

Future.microtask(() => communityViewModel.onEvent(CommunityEvent.community_query())
);

시도 2.

Future.microtask(() => context.read<CommunityViewModel>().notifyListeners()
);

시도3

Future.microtask(() => Provider.of<CommunityViewModel>(context, listen:  false).notifyListeners()
);

 시도4

Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
);

이런식으로 적는게 아닌건가요?

0

survivalcoding

혹시 communityViewModel 은 Provider로 관리되고 있는 것이 아닌가요? Provider라는 가정하에 설명드렸습니다.

0

chorokdosi

communityViewModel 클래스 내용은 강사님 유튜브참고해서 만들었습니다. 그러면 제 communityViewModel 클래스는 Provider가 관리중이 아닌건가요?

ChangeNotifierProvider.value(
  value: CommunityViewModel(CommunityRepositoryImpl(CommunityApi()))
),

 

0

survivalcoding

핸드폰으로 볼 때 시도 2까지 보였는데 시도 4까지 있었네요. 시도4가 맞습니다.

0

survivalcoding

생각해보니 BottomNavigationBar 생성할 때 이미 화면 2개를 생성해서 연결한 상태일테니 initState() 에서 새로고침하는 것이 의미가 없어보입니다.

화면이 보일 때 새로고침을 해야할 것 같은데 onResume 상태를 알아야 할 것 같습니다. 다음을 참고하시면 화면 보일때를 알 수 있을겁니다.

https://stackoverflow.com/questions/44331725/onresume-and-onpause-for-widgets-on-flutter

https://blog.naver.com/chandong83/222106016536

0

chorokdosi

감사합니다. 혹시 이렇게 사용하는게 맞나요?

@override
void initState() {
  print('home initState');
  _animationController = new AnimationController(vsync: this)
  ..repeat(min: 0.0, max: 1.0, period: Duration(seconds: 1))
  ..addListener(() {
    print('animation');
    Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
    );
  });
  //WidgetsBinding.instance.addObserver(this);
  super.initState();
}

Run에 계쏙 출력되는데 문제있는거 아닌가요? 새로고침은 됩니다.

0

survivalcoding

이 코드는 1초마다 새로고침을 수행하는 코드입니다.

네트워크를 사용하거나 한다면 문제가 있는 코드이겠지요.

0

chorokdosi

아하 그러면 사용하면 안되겠네요? WidgetsBindingObserver사용해야하는건가요?

0

survivalcoding

네. 이 방법이 유일할 것 같습니다.

0

chorokdosi

  @override
  void initState() {
    print('home initState');
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  void dispose() {
    print('home dispose');
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  print('home didChangeAppLifecycleState');
  super.didChangeAppLifecycleState(state);

  switch (state) {
    case AppLifecycleState.resumed:
      Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
      );
      print('resumed');
      break;
    case AppLifecycleState.inactive:
      Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
      );
      print('inactive');
      break;
    case AppLifecycleState.paused:
      Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
      );
      print('paused');
      break;
    case AppLifecycleState.detached:
      Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
      );
      print('detached');
      break;
  }
}

paused에만 호출하면 될거같은데 이렇게 사용하는거 맞나요? 일단 didChangeAppLifecycleState가 글작성후 왔을때 실행이 안되네요.

0

survivalcoding

잘 작성된 것 같은데요.

paused는 화면이 안보여질 때이고, resumed 는 보여질 때 이므로 resumed 에만 호출하면 됩니다.

참고로 Future.microtask 는 initState() 에서만 사용하면 되므로 삭제해도 됩니다.

이론적으로는 화면 왔다갔다 할 때 각 라이프사이클마다 print 가 동작되어야 합니다.

0

chorokdosi

@override
void initState() {
  print('home initState');
  Future.microtask(() => context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query())
  );
  WidgetsBinding.instance.addObserver(this);
  super.initState();
}

@override
void dispose() {
  print('home dispose');
  WidgetsBinding.instance.removeObserver(this);
  super.dispose();
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  print('home didChangeAppLifecycleState');
  super.didChangeAppLifecycleState(state);
  switch (state) {
    case AppLifecycleState.resumed:
      print('resumed');
      break;
  }
}

코드 수정했습니다. 그런데 글작성후 아무런 변화가 없습니다. 하단탭바로 이동시에만 새로고침이 됩니다.

0

survivalcoding

지금은 resumed 에 로딩하는 코드가 없는데 새로고침이 되나요? initState() 에는 있을 필요가 없고 라이프사이클 쪽으로 코드가 와야 될 것 같은데요.

그리고 이 방법은 BottomNavigationBar 에서 탭 이동시에 새로고침을 하게 하는 방법입니다.

글 작성후는 어떤 상황인지 저는 전혀 인지하고 있지 않아서 답변이 어렵습니다.

0

chorokdosi

resumed 로딩하는 코디가 따로 있나요? 지금상태에서는 글작성 후 didChangeAppLifecycleState 호출이 안되더라고요

void initState() {
  print('home initState');
  WidgetsBinding.instance.addObserver(this);
  super.initState();
}

@override
void dispose() {
  print('home dispose');
  WidgetsBinding.instance.removeObserver(this);
  super.dispose();
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  print('home didChangeAppLifecycleState');
  super.didChangeAppLifecycleState(state);
  switch (state) {
    case AppLifecycleState.resumed:
      context.read<CommunityViewModel>().onEvent(CommunityEvent.community_query());
      print('resumed');
      break;
  }
}

글작성페이지에서 글작성버튼클릭하면 BottomNavigationBar있는 클래스로 이동하게 했습니다.

이동된페이지에는 예전데이터만 보이고 있습니다.

BottomNavigationBar있는 클래스에서 글목록페이지 list에서 1번이라 바로 보이는 화면으로 되어있습니다.

0

survivalcoding

장면이 정확히 이해는 안 되지만, 어쨌든 이 코드는 이 화면이 보이는 순간마다 새로고침을 하는 로직입니다.

ListenableBuilder가 안되요..material import 했는데도 자동완성이 안뜨고 빨간줄이 뜨네요 ..

0

150

2

pubspec.yaml 파일에서 Pub get이 안됩니다.

0

889

1

[네이티브연동 관련 질문]

0

334

1

네이티브코드 연동할때 네이티브 디버깅은 어떻게 하나요?

0

477

1

CartBloc 대체 코드 올립니다.

0

455

2

강사님처럼 코드가 화면 범위 밖으로 나갔을 때 자동으로 줄바꿈은 어떻게 하나요?

0

969

1

ShowSnackBar Undefined 오류

0

419

1

null 관련 오류

0

318

1

flutter 멀티이미지업로드 질문

0

686

1

fluuter php mysql 글작성

0

435

2

플러터 서버에 이미지 저장하기

0

880

1

오류 질문입니다.

0

258

1

강의를 보다 listview 기능에 의문이 생겨 질문드립니다.

0

748

1

inheritedFromWidgetOfExactType 가 없습니다.

0

231

1

The operator '<' can't be unconditionally invoked because the receiver can be 'null'.

0

1114

1

해결이 어려운 부분이 있습니다 ㅠㅠ

0

1243

2

네이티브코드 연동 AS 21.11.11 update 영상 중

0

213

1

특정 함수로의 객체 전달 방법 문의 드립니다.

0

466

1

플러터 최적의 폴더 구조를 잡고 싶습니다.

0

1029

1

mainActive.kt 오류

0

318

1

xcode 오류가 납니다.

0

360

1

dart 2.12 이상 버전에서 json object null safety 처리는 어떻게 하나요?

0

631

1

json to dart

0

177

1

no sound null safety 오류

0

199

1