日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

ios開發Flutter構建todo?list應用_IOS

作者:Jimmy ? 更新時間: 2022-11-17 編程語言

正文

今天,我們將使用 Flutter 構建一個動態的 todo list 的應用。

開發完成的效果如下:

我們直接進入正題。

基礎 Flutter 應用腳手架

# create new project
flutter create flutter_todo_app
# navigate to project
cd flutter_todo_app
# run flutter
flutter run

我們清除文件 lib/main.dart,從頭開始開發。

main.dart 這個文件是 Flutter 應用的入口文件。在這篇文章中,我將僅僅使用這個文件來開發。

首先,我們先導入 material 包。

import 'package:flutter/material.dart';

下一步,我們得有一個主要的方法。在這個例子中,它將返回 TodoApp 實例。

void main() => runApp(
  new TodoApp(),
);

這個 TodoApp 應該是一個 statelessWidget。這將會是我們列表的骨架

class TodoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Todo list',
      home: new TodoList(),
    );
  }
}

正如你所見,我返回了一個 MaterialApp 實例,它具有一個 title 屬性和一個 home 功能。這個 home 函數返回一個 TodoList 實例。這個 TodoList 類才是我們控制的列表項。

class TodoList extends StatefulWidget {
  @override
  _TodoListState createState() => new _TodoListState();
}

等等,這是什么?所有的掛件都會調用一個狀態去知道將要發生什么和渲染什么。在這個例子中,我們調用了 _TodoListState。這將包含應用中的列表及其運行邏輯。

class _TodoListState extends State<TodoList> {
  final TextEditingController _textFieldController = TextEditingController();
  final List<Todo> _todos = <Todo>[];
  @override
  Widget build(BuildContext context) {
	  // Widget template comes here
  }
  // Other functions
}

接下來,創建列表變量。

final List<Todo> _todos = <Todo>[];

也許你已經注意到了,我們定義了這個列表的類型是 Todo,但 Flutter 怎么知道 Todo 長是什么樣呢?

Flutter 并不會知道,所以我們得創建一個類來定義。如下:

class Todo {
  Todo({required this.name, required this.checked});
  final String name;
  bool checked;
}

這跟 typescript 中的類型定義很像。我們告訴 flutter 一個 todo 項應該包含什么,什么字段是必須的。在我們的案例中,我們有名字和 checked 兩個狀態屬性。

回到 _TodoListState 中,我們開始讓我們的掛件展示點東西。

@override
Widget build(BuildContext context) {
	return new Scaffold(
	  appBar: new AppBar(
	    title: new Text('Todo list'),
	  ),
	  body: ListView(
	    padding: EdgeInsets.symmetric(vertical: 8.0),
	    children: _todos.map((Todo todo) {
	      return TodoItem(
	        todo: todo,
	        onTodoChanged: _handleTodoChange,
	      );
	    }).toList(),
	  ),
	  floatingActionButton: FloatingActionButton(
	      onPressed: () => _displayDialog(),
	      tooltip: 'Add Item',
	      child: Icon(Icons.add)),
	);
}

讓我們看看上面發生了什么。我們返回了應用的一個腳手架,在腳手架上,我們添加了一個包含標題的 appBar 的屬性。我們定義了 body 屬性,這將存放 ListView 組件。

在上面代碼片段中,通過 map 方法返回每個元素的 TodoItem。

然后,在應用的底部,我們定義了一個按鈕。當按鈕被點擊時候,將調用 _displayDialog 方法。

到目前為止,我們還需要完成下面的代碼片段:

  • 創建 TodoItem
  • 定義一個 _displayDialog 函數
  • 定義一個 _handleTodoChange 函數

讓我們一個一個來解決。

創建 TodoItem

TodoItem 是我們列表項的單獨體現。

class TodoItem extends StatelessWidget {
  TodoItem({
    required this.todo,
    required this.onTodoChanged,
  }) : super(key: ObjectKey(todo));
  final Todo todo;
  final onTodoChanged;
  TextStyle? _getTextStyle(bool checked) {
    if (!checked) return null;
    return TextStyle(
      color: Colors.black54,
      decoration: TextDecoration.lineThrough,
    );
  }
  @override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {
        onTodoChanged(todo);
      },
      leading: CircleAvatar(
        child: Text(todo.name[0]),
      ),
      title: Text(todo.name, style: _getTextStyle(todo.checked)),
    );
  }
}

正如你所見,我們傳遞一個 todoonTodoChanged 進來。

然后我們定義了一個 TextStyle 去處理列表項是否被勾選。

然后我們使用 ListTile 掛件來展示內容和添加點擊事件。

展示 Dialog 去添加列表項

點擊應用的右下角的按鈕,將會調起 _displayDialog 方法。

這將調起一個帶有文本框的對話框。當點擊確認的時候,將以文本框的內容基礎添加一個新的列表項。

_TodoListState 中創建 _displayDialog

Future<void> _displayDialog() async {
	return showDialog<void>(
	  context: context,
	  barrierDismissible: false, // user must tap button!
	  builder: (BuildContext context) {
	    return AlertDialog(
	      title: const Text('Add a new todo item'),
	      content: TextField(
	        controller: _textFieldController,
	        decoration: const InputDecoration(hintText: 'Type your new todo'),
	      ),
	      actions: <Widget>[
	        TextButton(
	          child: const Text('Add'),
	          onPressed: () {
	            Navigator.of(context).pop();
	            _addTodoItem(_textFieldController.text);
	          },
	        ),
	      ],
	    );
	  },
	);
}

Flutter 中的 Future 表明在將來的某個時候將返回潛在的值或者錯誤信息。在我們的案例中,將會返回用戶輸入的值。

對話框中有一個動作,就是當我們點擊按鈕的時候,將會關閉對話框并且調用 _addTodoItem 函數。

我們看看 _addTodoItem 函數長什么樣:

void _addTodoItem(String name) {
	setState(() {
	  _todos.add(Todo(name: name, checked: false));
	});
	_textFieldController.clear();
}

這函數比你想象中的簡單,是吧。

列表項添加狀態

最后一部分是,我們應該為列表項進行標記。我們需要一個處理函數 _handleTodoChange

void _handleTodoChange(Todo todo) {
	setState(() {
	  todo.checked = !todo.checked;
	});
}

這里我們只是改變了其列表項的狀態。

完整的代碼如下:

// lib/main.dart
import 'package:flutter/material.dart';
class Todo {
  Todo({required this.name, required this.checked});
  final String name;
  bool checked;
}
class TodoItem extends StatelessWidget {
  TodoItem({
    required this.todo,
    required this.onTodoChanged,
  }) : super(key: ObjectKey(todo));
  final Todo todo;
  final onTodoChanged;
  TextStyle? _getTextStyle(bool checked) {
    if (!checked) return null;
    return TextStyle(
      color: Colors.black54,
      decoration: TextDecoration.lineThrough,
    );
  }
  @override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {
        onTodoChanged(todo);
      },
      leading: CircleAvatar(
        child: Text(todo.name[0]),
      ),
      title: Text(todo.name, style: _getTextStyle(todo.checked)),
    );
  }
}
class TodoList extends StatefulWidget {
  @override
  _TodoListState createState() => new _TodoListState();
}
class _TodoListState extends State<TodoList> {
  final TextEditingController _textFieldController = TextEditingController();
  final List<Todo> _todos = <Todo>[];
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Todo list'),
      ),
      body: ListView(
        padding: EdgeInsets.symmetric(vertical: 8.0),
        children: _todos.map((Todo todo) {
          return TodoItem(
            todo: todo,
            onTodoChanged: _handleTodoChange,
          );
        }).toList(),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: () => _displayDialog(),
          tooltip: 'Add Item',
          child: Icon(Icons.add)),
    );
  }
  void _handleTodoChange(Todo todo) {
    setState(() {
      todo.checked = !todo.checked;
    });
  }
  void _addTodoItem(String name) {
    setState(() {
      _todos.add(Todo(name: name, checked: false));
    });
    _textFieldController.clear();
  }
  Future<void> _displayDialog() async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Add a new todo item'),
          content: TextField(
            controller: _textFieldController,
            decoration: const InputDecoration(hintText: 'Type your new todo'),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('Add'),
              onPressed: () {
                Navigator.of(context).pop();
                _addTodoItem(_textFieldController.text);
              },
            ),
          ],
        );
      },
    );
  }
}
class TodoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Todo list',
      home: new TodoList(),
    );
  }
}
void main() => runApp(new TodoApp());

本文采用的是意譯的方式。原文鏈接 - Build a todo list app with Flutter

原文鏈接:https://juejin.cn/post/7147496701065068574

欄目分類
最近更新