Flutter 단기집중과정 - 2단계
이전 예제에서 버튼을 활성화하기 전에 앱이 API와 통신해야 하기 때문에 시작 시 버튼을 비활성화하고 싶다고 가정해 보겠습니다. 이를 달성하려면 몇 가지 단계가 필요합니다.
1/
Button
Widget
의 활성화 상태는 onPressed
속성에 설정된 작업이 있는지 여부에 따라 결정됩니다. 현재 한 세트가 있습니다. RaisedButton(
child: Text("A Button"),
onPressed: () => print("Pressed"),
),
변경해 보겠습니다.
RaisedButton(
child: Text("A Button"),
onPressed: buttonEnabled ? () => print("Pressed") : null,
),
buttonEnabled
는 현재 존재하지 않는 변수입니다. 그럼 이것을 어떻게 전달할까요? Builder 클래스(유형이 아닌 개념)를 통해, 이 경우 a FutureBuilder
.2/
RaisedButton
를 이 다른 FutureBuilder
Widget
안에 감쌉니다. FutureBuilder<bool>(
future: null,
builder: (context, AsyncSnapshot<bool> snapshot) {
final buttonEnabled = snapshot.hasData && snapshot.data;
return RaisedButton(
child: Text("A Button"),
onPressed: buttonEnabled ? () => print("Pressed") : null,
);
}
),
아직
Future<bool>
가 없으므로 future: null
는 비워 두었지만 나머지는 설명하겠습니다. UI를 구축하기 위해 FutureBuilder
의 builder
함수는 future가 완료되기 전에 (최소한) 한 번 호출되고 완료되면 호출됩니다. 완료 여부와 완료된 경우 결과가 스냅샷으로 전달됩니다. 이 스냅샷을 기반으로 버튼을 활성화하거나 비활성화합니다.빌더를 생각하는 좋은 방법은 다음과 같습니다.
표시할 위젯이나 위젯에 설정할 속성을 결정하려면 약간의 로직이 필요합니다. 따라서 조건을 넣을 빌더가 필요합니다.
또는 더 간단하게:
if 문이 필요하므로 빌더가 필요합니다.
이제
Future
가 들을 수 있는 FutureBuilder
를 만들겠습니다.3/이렇게 하려면
Widget
를 상태가 있는 것으로 변경해야 합니다. 현재 상태에 대해 알 필요가 없는 StatelessWidget
를 위한 Widget
입니다. Future
를 도입하고 있고 Future
가 한 번만 실행되기를 원하므로 Widget
가 상태를 가져야 합니다.Android Studio의 alt+enter를 통해
MyApp
가 아닌 확장StatefulWidget
으로 StatelessWidget
를 변경합니다.예리한 눈을 가진 사람은 텍스트 측면에서 크게 변경된 사항이 없음을 알 수 있습니다. 우리의
build
함수는 새로운 내부 클래스로 이동했고 MyApp
는 이제 이 내부 클래스의 인스턴스를 생성합니다.4/이제
Future
를 _MyAppState
의 속성으로 추가하고 _MyAppState
의 initState
메서드에서 생성해 보겠습니다.class _MyAppState extends State<MyApp> {
Future<bool> future;
@override
void initState() {
super.initState();
future = Future.delayed(Duration(seconds: 2), () => true);
}
@override
Widget build(BuildContext context) {
5/이제
FutureBuilder
에 연결합니다. FutureBuilder<bool>(
future: future,
builder: (context, AsyncSnapshot<bool> snapshot) {
앱 실행:
다른 빌더
FutureBuilder
처럼 자주 사용되는 것처럼 StreamBuilder
가 있습니다(실제로 제 경우에는 훨씬 더 자주 사용됨). 이는 여러 번 변경될 수 있는 데이터 스트림을 수신한다는 점을 제외하면 매우 유사합니다. 예를 들어 진행률 표시기 또는 목록 내용의 가시성.좋은 방법은 화면의 모든 상태를 데이터 클래스에 유지하고 비즈니스 로직이 이 상태를 업데이트하고 스트림을 통해 업데이트를 전송하도록 하는 것입니다. UI(
Widget
s)는 StreamBuilder
를 사용하여 이를 수신하고 이 상태에 있는 모든 것을 반영하도록 UI를 업데이트할 수 있습니다.이 예에서는 다음과 같이 Android Studio의 기본 Flutter 프로젝트를 조정하여 스트림을 사용하고 버튼을 누를 때마다 비동기 코드를 수행합니다.
상태를 유지하는 간단한 클래스를 정의해 보겠습니다.
class MyHomePageState {
final int counter;
final bool showSpinner;
MyHomePageState(this.counter, this.showSpinner);
}
이제 비즈니스 로직을 수행하려면 일반 Dart 클래스(즉, Flutter 코드가 아님)가 필요합니다.
class Logic {
// private stream controller that will manage our stream
final _streamController = StreamController<MyHomePageState>();
// expose the stream publicly
Stream<MyHomePageState> get homePageState => _streamController.stream;
MyHomePageState _currentState;
Logic() {
_updateState(MyHomePageState(0, false));
}
// update the state and broadcast it via the stream controller
void _updateState(MyHomePageState newState) {
_currentState = newState;
_streamController.sink.add(_currentState);
}
// increment the counter after waiting 1 second, to simulate a network call for example.
Future<void> incrementCounter() async {
_updateState(MyHomePageState(_currentState.counter, true));
await Future.delayed(Duration(seconds: 1));
_updateState(MyHomePageState(_currentState.counter + 1, false));
}
}
이제 UI는 바보처럼 작동하고 이벤트를 보내고(버튼 탭) 표시할 항목(스트림의 콘텐츠)을 수신하여 이 클래스
Logic
를 사용합니다.class MyHomePage extends StatelessWidget {
final Logic logic = Logic();
Widget build(BuildContext context) {
return StreamBuilder<MyHomePageState>(
stream: logic.homePageState,
builder: (context, AsyncSnapshot<MyHomePageState> snapshot) {
print("snapshot: ${snapshot?.data ?? "null"} ");
final asyncInProgress = snapshot.data?.showSpinner ?? true;
return Scaffold(
appBar: AppBar(title: Text("Stream Example")),
body: Center(
child: asyncInProgress
? CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'${snapshot.data.counter}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: asyncInProgress ? null : logic.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
},
);
}
}
플로팅 작업 버튼은 진행률 스피너가 표시되지 않는 경우에만 활성화되므로 비동기 작업이 완료될 때까지 다시 누를 수 없습니다.
이 짧은 시리즈의 마지막 부분에서는 모든 앱에 적용할 수 있는 간단한 패턴인 탐색을 다룹니다.
Reference
이 문제에 관하여(Flutter 단기집중과정 - 2단계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/nmwilk/flutter-crash-course-step-2-2n5i텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)