flutter

bloc todo

paulaner80 2019. 4. 19. 12:06
반응형
import 'package:flutter/material.dart';
import "dart:async";
import "dart:convert";
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TodoProvider(
todoBloc: TodoBloc(API()),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: "flutter demo",
theme: ThemeData(primarySwatch: Colors.blue),
home: TodoPage()));
}
}

class TodoBloc {
final API api;

StreamController<List<Todo>> ctrl = StreamController();

Stream<List<Todo>> get results => ctrl.stream;

TodoBloc(this.api);

void dispose() {
ctrl.close();
}

void getTodo() {
api.getTodo().then((todos) {
ctrl.add(todos);
});
}
}

class TodoPage extends StatefulWidget {
@override
TodoPageState createState() => TodoPageState();
}

class TodoPageState extends State<TodoPage> {
@override
Widget build(BuildContext context) {
final todoBloc = TodoProvider.of(context);

return Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Center(
child: Column(
children: <Widget>[
Text("Stream Builder with Bloc"),
RaisedButton(
color: Colors.lightBlueAccent[200],
child: Text(
"Load Data",
style: TextStyle(color: Colors.white),
),
onPressed: todoBloc.getTodo,
),
Flexible(
//https://docs.flutter.io/flutter/widgets/StreamBuilder-class.html
child: StreamBuilder(
stream: todoBloc.results,
/*
build method
@override
Widget build (
BuildContext context,
AsyncSnapshot<T> currentSummary
)
override

Returns a Widget based on the currentSummary.

*/
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text("No data");
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) =>
_buildListTile(snapshot, index),
);
}
}),
)
],
),
));
}

//리스트뷰에 들어갈 타일을 만든다.
Widget _buildListTile(AsyncSnapshot snapshot, int index) {
var id = snapshot.data[index].id;
var title = snapshot.data[index].title;
bool completed = snapshot.data[index].completed;

print("111 snapshot.data[index] : ${snapshot.data[index]}");
print("111 complete : $completed");

//한개의 고정높이의 row single fixed-heigh row
//텍스트와 그 텍스트의 leading 혹은 trailing에 아이콘을 가짐
// title : The primary content of the list tile
// subtitle : Additional content displayed below title
// leading : A widget to display before the title;\
// tailing : A widget to display after the title
// 한개에서 3개의 텍스트 라인을 가짐.
//https://medium.com/@studymongolian/a-complete-guide-to-flutters-listtile-597a20a3d449
//https://docs.flutter.io/flutter/material/ListTile-class.html
return ListTile(
leading: Text('$id'),
title: Text('$title'),
subtitle: Text("completed",
style: TextStyle(color: completed ? Colors.lightBlue : Colors.red)),
);
}
}

//bloc는 항상 provider를 통해서 사용합니다.
class TodoProvider extends InheritedWidget {
final TodoBloc todoBloc;

static TodoBloc of(BuildContext context) {
return (context.inheritFromWidgetOfExactType(TodoProvider) as TodoProvider)
.todoBloc;
}

@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return true;
}

TodoProvider({Key key, TodoBloc todoBloc, Widget child})
:
// Assign value to b if b is null; otherwise, b stays the same
//b ??= value;
this.todoBloc = todoBloc ?? TodoBloc(API()),
super(child: child, key: key);
}

class API {
final http.Client _client = http.Client();

static const String _url = "https://jsonplaceholder.typicode.com/todos";

Future<List<Todo>> getTodo() async {
List<Todo> list = [];

await _client
.get(Uri.parse(_url))
.then((res) => res.body)
.then(json.decode)
.then(
(todos) => todos.forEach((todo) => list.add(Todo.fromJson(todo))));

return list;
}
}

class Todo {
int userId;
int id;
String title;
bool completed;

Todo(this.userId, this.id, this.title, this.completed);

Todo.fromJson(Map json)
: userId = json["userId"],
id = json["id"],
title = json["title"],
completed = json["completed"];

@override
String toString() {
return 'completed : $completed';
}
}






https://software-creator.tistory.com/13