欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ios開(kāi)發(fā)Flutter構(gòu)建todo?list應(yīng)用

 更新時(shí)間:2022年09月27日 17:18:40   作者:Jimmy  
這篇文章主要為大家介紹了ios開(kāi)發(fā)Flutter構(gòu)建todo?list應(yīng)用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

今天,我們將使用 Flutter 構(gòu)建一個(gè)動(dòng)態(tài)的 todo list 的應(yīng)用。

開(kāi)發(fā)完成的效果如下:

我們直接進(jìn)入正題。

基礎(chǔ) Flutter 應(yīng)用腳手架

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

我們清除文件 lib/main.dart,從頭開(kāi)始開(kāi)發(fā)。

main.dart 這個(gè)文件是 Flutter 應(yīng)用的入口文件。在這篇文章中,我將僅僅使用這個(gè)文件來(lái)開(kāi)發(fā)。

首先,我們先導(dǎo)入 material 包。

import 'package:flutter/material.dart';

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

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

這個(gè) TodoApp 應(yīng)該是一個(gè) statelessWidget。這將會(huì)是我們列表的骨架

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

正如你所見(jiàn),我返回了一個(gè) MaterialApp 實(shí)例,它具有一個(gè) title 屬性和一個(gè) home 功能。這個(gè) home 函數(shù)返回一個(gè) TodoList 實(shí)例。這個(gè) TodoList 類才是我們控制的列表項(xiàng)。

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

等等,這是什么?所有的掛件都會(huì)調(diào)用一個(gè)狀態(tài)去知道將要發(fā)生什么和渲染什么。在這個(gè)例子中,我們調(diào)用了 _TodoListState。這將包含應(yīng)用中的列表及其運(yùn)行邏輯。

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
}

接下來(lái),創(chuàng)建列表變量。

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

也許你已經(jīng)注意到了,我們定義了這個(gè)列表的類型是 Todo,但 Flutter 怎么知道 Todo 長(zhǎng)是什么樣呢?

Flutter 并不會(huì)知道,所以我們得創(chuàng)建一個(gè)類來(lái)定義。如下:

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

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

回到 _TodoListState 中,我們開(kāi)始讓我們的掛件展示點(diǎn)東西。

@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)),
	);
}

讓我們看看上面發(fā)生了什么。我們返回了應(yīng)用的一個(gè)腳手架,在腳手架上,我們添加了一個(gè)包含標(biāo)題的 appBar 的屬性。我們定義了 body 屬性,這將存放 ListView 組件。

在上面代碼片段中,通過(guò) map 方法返回每個(gè)元素的 TodoItem。

然后,在應(yīng)用的底部,我們定義了一個(gè)按鈕。當(dāng)按鈕被點(diǎn)擊時(shí)候,將調(diào)用 _displayDialog 方法。

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

  • 創(chuàng)建 TodoItem
  • 定義一個(gè) _displayDialog 函數(shù)
  • 定義一個(gè) _handleTodoChange 函數(shù)

讓我們一個(gè)一個(gè)來(lái)解決。

創(chuàng)建 TodoItem

TodoItem 是我們列表項(xiàng)的單獨(dú)體現(xiàn)。

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)),
    );
  }
}

正如你所見(jiàn),我們傳遞一個(gè) todoonTodoChanged 進(jìn)來(lái)。

然后我們定義了一個(gè) TextStyle 去處理列表項(xiàng)是否被勾選。

然后我們使用 ListTile 掛件來(lái)展示內(nèi)容和添加點(diǎn)擊事件。

展示 Dialog 去添加列表項(xiàng)

點(diǎn)擊應(yīng)用的右下角的按鈕,將會(huì)調(diào)起 _displayDialog 方法。

這將調(diào)起一個(gè)帶有文本框的對(duì)話框。當(dāng)點(diǎn)擊確認(rèn)的時(shí)候,將以文本框的內(nèi)容基礎(chǔ)添加一個(gè)新的列表項(xiàng)。

_TodoListState 中創(chuàng)建 _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 表明在將來(lái)的某個(gè)時(shí)候?qū)⒎祷貪撛诘闹祷蛘咤e(cuò)誤信息。在我們的案例中,將會(huì)返回用戶輸入的值。

對(duì)話框中有一個(gè)動(dòng)作,就是當(dāng)我們點(diǎn)擊按鈕的時(shí)候,將會(huì)關(guān)閉對(duì)話框并且調(diào)用 _addTodoItem 函數(shù)。

我們看看 _addTodoItem 函數(shù)長(zhǎng)什么樣:

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

這函數(shù)比你想象中的簡(jiǎn)單,是吧。

列表項(xiàng)添加狀態(tài)

最后一部分是,我們應(yīng)該為列表項(xiàng)進(jìn)行標(biāo)記。我們需要一個(gè)處理函數(shù) _handleTodoChange

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

這里我們只是改變了其列表項(xiàng)的狀態(tài)。

完整的代碼如下:

// 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

以上就是ios開(kāi)發(fā)Flutter構(gòu)建todo list應(yīng)用的詳細(xì)內(nèi)容,更多關(guān)于ios開(kāi)發(fā)Flutter構(gòu)建todo list的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • iOS CoreData 增刪改查詳解

    iOS CoreData 增刪改查詳解

    這篇文章主要為大家詳細(xì)介紹了iOS CoreData 增刪改查的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • iOS中使用UItableviewcell實(shí)現(xiàn)團(tuán)購(gòu)和微博界面的示例

    iOS中使用UItableviewcell實(shí)現(xiàn)團(tuán)購(gòu)和微博界面的示例

    這篇文章主要介紹了iOS中使用UItableviewcell實(shí)現(xiàn)團(tuán)購(gòu)和微博界面的示例,開(kāi)發(fā)語(yǔ)言基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2016-01-01
  • 詳解iOS之關(guān)于double/float數(shù)據(jù)計(jì)算精度問(wèn)題

    詳解iOS之關(guān)于double/float數(shù)據(jù)計(jì)算精度問(wèn)題

    本篇文章主要介紹了iOS之關(guān)于double/float數(shù)據(jù)計(jì)算精度問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • iOS自帶原生二維碼掃描的實(shí)現(xiàn)

    iOS自帶原生二維碼掃描的實(shí)現(xiàn)

    最近項(xiàng)目中需要做一個(gè)二維碼掃描,雖然有很多二維碼掃描的第三方可以用,但是考慮到項(xiàng)目中的需要,所以我放棄了使用三方庫(kù),而采用了蘋(píng)果原生的掃描。下面這篇文章就介紹了iOS自帶原生二維碼掃描的實(shí)現(xiàn),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-01-01
  • iOS中UIView實(shí)現(xiàn)不同方向的導(dǎo)角

    iOS中UIView實(shí)現(xiàn)不同方向的導(dǎo)角

    這篇文章主要給大家介紹了關(guān)于iOS中UIView實(shí)現(xiàn)不同方向的導(dǎo)角的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或使用iOS具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • iOS中正向、逆向傳值的方法總結(jié)

    iOS中正向、逆向傳值的方法總結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于iOS中正向、逆向傳值的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • iOS?組件化初步構(gòu)思

    iOS?組件化初步構(gòu)思

    這篇文章主要介紹了iOS組件化初步構(gòu)思,并對(duì)iOS組件化常用方式的討論進(jìn)行了方案分析,以便幫助大家對(duì)ios組件化有一個(gè)深刻的了解
    2023-03-03
  • Flutter Widgets MediaQuery控件屏幕信息適配

    Flutter Widgets MediaQuery控件屏幕信息適配

    這篇文章主要為大家介紹了Flutter Widgets 之 MediaQuery控件獲取屏幕信息和屏幕適配示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • iOS CAEmitterLayer實(shí)現(xiàn)粒子發(fā)射動(dòng)畫(huà)效果

    iOS CAEmitterLayer實(shí)現(xiàn)粒子發(fā)射動(dòng)畫(huà)效果

    這篇文章主要為大家詳細(xì)介紹了iOS CAEmitterLayer 實(shí)現(xiàn)粒子發(fā)射動(dòng)畫(huà)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • UIMenuController在Cell內(nèi)部無(wú)法顯示的解決辦法(iOS9.2)

    UIMenuController在Cell內(nèi)部無(wú)法顯示的解決辦法(iOS9.2)

    這篇文章主要為大家詳細(xì)介紹了UIMenuController在Cell內(nèi)部無(wú)法顯示的解決辦法,感興趣的小伙伴們可以參考一下
    2016-08-08

最新評(píng)論