[NGỤP LẶN VỚI FLUTTER] PHẦN 3: LẬP TRÌNH ỨNG DỤNG FLUTTER ĐẦU TIÊN

26/11/2021 87
lap trinh ung dung flutter
CODEWELL

Sau khi làm quen với Flutter, đồng thời tìm hiểu về StatelessWidget và StatefullWidget, các bạn đã có những kiến thức cơ bản về Flutter. Hãy cùng CO-WELL Asia viết ứng dụng Flutter đầu tiên theo hướng dẫn chi tiết trong bài viết này nhé.

 

Chúng ta sẽ bắt đầu với một ứng dụng di động đơn giản, đó là tạo ra một danh sách tên, có thể là sản phẩm,… Người dùng có thể thực hiện các thao tác: chọn và bỏ chọn, lưu. Trong ứng dụng này, khi chúng ta nhấn vào biểu tượng danh sách ở phía trên bên phải của thanh ứng dụng thì sẽ điều hướng đến một trang mới (được gọi là một route) chỉ liệt kê các tên, sản phẩm đã được ưa thích.

 

flutter 2

 

  1. Import thư viện

 

File dùng để import thêm các libs ngoài có tên là pubspec.yaml, mở file này ra và thêm đoạn code để import library như sau:

dependencies:

  flutter:

    sdk: flutter

 

  # The following adds the Cupertino Icons font to your application.

  # Use with the CupertinoIcons class for iOS style icons.

  cupertino_icons: ^0.1.2

  english_words: ^3.1.0 // add this line

 

Ở đây cần dùng  “English Words”, điều này có tác dụng tạo ra các cặp từ tiếng anh ngẫu nhiên. Sau khi thêm libs thì nhấn chọn Packages get ở góc trên bên phải để pull package này về project. Khi chạy xong sẽ hiển thị như sau:

 

flutter 3

 

2. Các Widgets được sử dụng trong code

 

Để chuẩn bị cho ví dụ này, hãy cùng tìm hiểu một số Widget sau:

 

 

  • MaterialApp: ứng dụng sử dụng material design. Đây là một widget tiện lợi có thể gói lại nhiều widget được yêu cầu cho ứng dụng material design. Các thuộc tính thường sử dụng:

 

class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      debugShowCheckedModeBanner: false,

      title: 'Startup Name Generator',

      theme: ThemeData(

        primaryColor: Colors.white,

      ),

      home: RandomWords(),

    );

  }

}

 

Chú thích:

 

  • debugShowCheckedModeBanner: dùng để xóa nhãn debug trên màn hình ứng dụng, thường để là false.
  • title: title của ứng dụng.
  • theme: set theme cho ứng dụng.
  • home: muốn điều hướng tới class nào ngay khi run app thì cho vào đây, trong ví dụ này lựa chọn class RandomWords().

Tham khảo thêm tại đây: https://api.flutter.dev/flutter/material/MaterialApp-class.html

 

  • ListView: hiển thị danh sách item có thể cuộn lên xuống. Tương tự như Listview, RecyclerView trong android hoặc table view trong IOS.

 

Widget _buildSuggestions() {

    return ListView.builder(

        padding: const EdgeInsets.all(16.0),

        itemCount: itemCount,

        itemBuilder: (context, i) {

          if (i.isOdd) return Divider();

          final index = i ~/ 2;

          if (index >= _suggestions.length) {

            _suggestions.addAll(generateWordPairs().take(10));

          }

          return _buildRow(_suggestions[index]);

        });

  }

 

Ở đây dùng Listview.builder(), có các thuộc tính thường sử dụng như sau:

  • padding: giãn cách giữa nội dung item so với lề trong.
  • itemCount: số lượng item, có thể không set thuộc tính này nếu list là vô hạn.
  • itemBuilder: có tác dụng xây dựng từng item tại vị trí position.

Tham khảo thêm: https://medium.com/flutter-community/flutter-listview-and-scrollphysics-a-detailed-look-7f0912df2754

 

  • ListTile: giúp xây dựng từng item cho ListView:

 

Widget _buildRow(WordPair pair) {

    final bool alreadySaved = _saved.contains(pair);

    return ListTile(

      title: Text(

        pair.asPascalCase,

        style: _biggerFont,

      ),

      subtitle: Text('sub Tile'),

      leading : Icon(Icons.favorite),

      trailing: Icon(

        alreadySaved ? Icons.favorite : Icons.favorite_border,

        color: alreadySaved ? Colors.red : null,

      ),

      onTap: () {

        setState(() {

          if (alreadySaved) {

            _saved.remove(pair);

          } else {

            _saved.add(pair);

          }

        });

      },

    );

  }

 

Các thuộc tính xuất hiện trong ví dụ trên:

  • title: đóng vai trò là title của ListTile.
  • subtitle: phần chữ nhỏ hơn của title, hiển thị ngay dưới title.
  • leading: thêm image hoặc icon phía start của ListTile.
  • trailing: thêm image hoặc icon phía end của ListTile.
  • onTap: bắt sự kiện click cho ListTile đó.

Tham khảo thêm: https://medium.com/@studymongolian/a-complete-guide-to-flutters-listtile-597a20a3d449

 

  • Scaffold: mọi thứ để xây dựng một ứng dụng cơ bản đều có thể tìm thấy ở đây. Trong ví dụ này dùng AppBar và Body:

 

@override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text('Startup Name Generator'),

        actions: <Widget>[

          IconButton(icon: Icon(Icons.list), onPressed: _pushSaved),

        ],

      ),

      body: _buildSuggestions(),

    );

  }

 

  • appBar: thiết kế trên thanh appBar, gồm title và action.
  • body: phần bên dưới của appBar, có gì sẽ viết ở khu vực này.

Tham khảo thêm: https://proandroiddev.com/flutter-material-design-using-scaffold-appbar-body-bottom-navigation-floating-action-f84d71e68c76 

 

3. Code demo

 

Code trong file main.dart như sau:

 

import 'package:english_words/english_words.dart';

import 'package:flutter/material.dart';

 

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

 

class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      debugShowCheckedModeBanner: false,

      title: 'Startup Name Generator',

      theme: ThemeData(

        primaryColor: Colors.white,

      ),

      home: RandomWords(),

    );

  }

}

 

class RandomwordsState extends State<RandomWords> {

  final List<WordPair> _suggestions = <WordPair>[];

  final Set<WordPair> _saved = Set<WordPair>();

  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);

 

  Widget _buildSuggestions() {

    return ListView.builder(

        padding: const EdgeInsets.all(16.0),

        itemBuilder: (context, position) {

          if (position.isOdd) return Divider();

          final index = position ~/ 2;

          if (index >= _suggestions.length) {

            _suggestions.addAll(generateWordPairs().take(10));

          }

          return _buildRow(_suggestions[index]);

        });

  }

 

  Widget _buildRow(WordPair pair) {

    final bool alreadySaved = _saved.contains(pair);

    return ListTile(

      title: Text(

        pair.asPascalCase,

        style: _biggerFont,

      ),

      subtitle: Text('sub Tile'),

      leading : Icon(Icons.favorite),

      trailing: Icon(

        alreadySaved ? Icons.favorite : Icons.favorite_border,

        color: alreadySaved ? Colors.red : null,

      ),

      onTap: () {

        setState(() {

          if (alreadySaved) {

            _saved.remove(pair);

          } else {

            _saved.add(pair);

          }

        });

      },

    );

  }

 

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text('Startup Name Generator'),

        actions: <Widget>[

          IconButton(icon: Icon(Icons.list), onPressed: _pushSaved),

        ],

      ),

      body: _buildSuggestions(),

    );

  }

 

  void _pushSaved() {

    Navigator.of(context)

        .push(MaterialPageRoute<void>(builder: (BuildContext context) {

      final Iterable<ListTile> tiles = _saved.map((WordPair pair) {

        return ListTile(

          title: Text(

            pair.asPascalCase,

            style: _biggerFont,

          ),

        );

      });

 

      final List<Widget> divided =

          ListTile.divideTiles(tiles: tiles, context: context).toList();

 

      return Scaffold(

        appBar: AppBar(

          title: Text('Saved Suggestion'),

        ),

        body: ListView(

          children: divided,

        ),

      );

    }));

  }

}

 

class RandomWords extends StatefulWidget {

  @override

  State<StatefulWidget> createState() => new RandomwordsState();

}

 

Kết quả:

 

flutter 1

 

4. Tạm kết

Hi vọng những hướng dẫn để lập trình thành công ứng dụng flutter đơn giản trên đây sẽ giúp bạn có những trải nghiệm thực tế nhất về bộ công cụ phát triển phần mềm đang được săn đón này. Đừng quên theo dõi chuyên mục CODEWELL trên website CO-WELL Asia để đón đọc những bài viết bổ ích về công nghệ nhé!

 

Tham khảo:

[Flutter Document]
https://flutter.dev/docs/cookbook

[Widgets Intro]
https://flutter.dev/docs/development/ui/widgets-intro

 

TRẦN HỮU ĐÔNG – CO-WELL Asia