Ví dụ sử dụng GetX trong Flutter để quản lý state

Ví dụ sử dụng GetX trong Flutter để quản lý state
Lập trình Lập trình Flutter

Ví dụ sử dụng GetX trong Flutter để quản lý state

Bài viết này hướng dẫn bạn cách sử dụng GetX trong Flutter để quản lý các trạng thái của ứng dụng. Chúng ta sẽ xây dựng một ứng dụng đơn giản hiển thị danh sách các sản phẩm. Sau đó người dùng có thể thêm sản phẩm vào danh sách yêu thích hoặc xóa sản phẩm trong danh sách yêu thích.

Ứng dụng sẽ có 2 màn hình: HomeScreen và WishListScreen :

  • HomeScreen chứa một nút và một danh sách các sản phẩm. Nút hiển thị số lượng sản phẩm đã được thêm vào danh sách yêu thích.
  • WishListScreen hiển thị danh sách các sản phẩm yêu thích mà người dùng đã chọn.

Getting Started

1. Tạo một Flutter project: 

flutter create get_state_example

Tiếp sau đó thêm GetX vào project:

flutter pub add get

2. Bây giờ bên trong thư mục /lib các bạn thêm các file và folder theo cấu trúc bên dưới:

├── main.dart
├── models
│   └── item.dart
├── screens
│   ├── home_screen.dart
│   └── wish_list_screen.dart
└── state
    └── products.dart

Nó có vẻ thừa khi một số thư mục chỉ chứa một tệp trong đó. Tuy nhiên, điều này giúp bạn dễ dàng mở rộng dự án của mình trong tương lai mà không cần thay đổi cấu trúc thư mục.

Làm việc với State

3. Tạo một class Item trong models/item.dart. Code của class này như sau:

import 'package:get/get.dart';

class Item {
  int id;
  String name;
  double price;
  RxBool inWishList; // Make inWishList observable by adding ".obs".
  Item(
      {required this.id,
      required this.name,
      required this.price,
      required this.inWishList});
}

// In the past, I used "@required" instead of "require" as now

 4. Lớp Products sẽ là lớp xử lý logic nghiệp vụ. Chúng ta sẽ tạo các phương thức để xử lý việc thêm ( phương thức addItem()) hoặc loại bỏ ( phương thức removeItem() ) các items khỏi danh sách yêu thích.

Để làm cho biến _items có thể quan sát được (variable observable), chúng ta sử dụng “.obs”.

// state/products.dart
import 'package:get/get.dart';
import 'dart:math';
import '../models/item.dart';

class Products extends GetxController {
  // All products
  // In production, these things usually be loaded them from API or database or something like that
  RxList<Item> _items = List.generate(
      100,
      (index) => Item(
          id: index,
          name: 'Product $index',
          price: Random().nextDouble() * 100,
          inWishList: false.obs)).obs;

  // Use this to retrieve all products
  List<Item> get items {
    return [..._items];
  }

  // This will return the products that were added to wish list
  List<Item> get wishListItems {
    return _items.where((item) => item.inWishList.value == true).toList();
  }

  // Add an item to the wish list
  void addItem(int id) {
    final int index = _items.indexWhere((item) => item.id == id);
    _items[index].inWishList.value = true;
  }

  // Remove an item from the wish list
  void removeItem(int id) {
    final int index = _items.indexWhere((item) => item.id == id);
    _items[index].inWishList.value = false;
  }
}

Làm việc với các màn hình

5. Tại HomeScreen chúng ta sẽ hiển thị danh sách các sản phẩm đồng thời hiển thị số lượng các sản phẩm đã có trong danh sách các sản phẩm yêu thích:

// screens/home_screen.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../state/products.dart';
import 'wish_list_screen.dart';

class HomeScreen extends StatelessWidget {
  // Instantiate our Products class using Get.put()
  final Products _p = Get.put(Products());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Column(
        children: [
          SizedBox(
            height: 20,
          ),
          // This button also shows you how many items in the wish list
          // It lets you go to the WishListScreen
          InkWell(
            child: Container(
              width: 300,
              height: 80,
              color: Colors.red,
              alignment: Alignment.center,
              // Use Obx(()=> to update Text() whenever _wishList.items.length is changed
              child: Obx(() => Text(
                    'Wish List: ${_p.wishListItems.length}',
                    style: TextStyle(fontSize: 28, color: Colors.white),
                  )),
            ),
            onTap: () => Navigator.push(context,
                MaterialPageRoute(builder: (context) => WishListScreen())),
          ),

          SizedBox(
            height: 20,
          ),

          Expanded(
              // Display all products in home screen
              child: ListView.builder(
                  itemCount: _p.items.length,
                  // List item widget
                  itemBuilder: (context, index) {
                    final product = _p.items[index];
                    return Card(
                      key: ValueKey(product.id),
                      margin: EdgeInsets.all(5),
                      color: Colors.amberAccent,
                      child: ListTile(
                        title: Text(product.name),
                        subtitle: Text("\$${product.price.toStringAsFixed(2)}"),
                        // Use Obx(()=> to update icon color when product.inWishList change
                        trailing: Obx(() => IconButton(
                              onPressed: () {
                                if (product.inWishList.value == false) {
                                  _p.addItem(product.id);
                                } else {
                                  _p.removeItem(product.id);
                                }
                              },
                              icon: Icon(
                                Icons.favorite,
                                color: product.inWishList.value == false
                                    ? Colors.white
                                    : Colors.red,
                              ),
                            )),
                      ),
                    );
                  })),
        ],
      ),
    );
  }
}

6. Và tiếp theo, là màn hình WishListScreen:

// screens/wish_list_screen.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../state/products.dart';

class WishListScreen extends StatelessWidget {
  // Ask Get to find our "controller"
  final Products _p = Get.find<Products>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('WishList'),
        ),
        body: Obx(
          () => ListView.builder(
            itemCount: _p.wishListItems.length,
            itemBuilder: (context, index) {
              final item = _p.wishListItems[index];
              return Card(
                key: ValueKey(item.id),
                margin: EdgeInsets.all(5),
                color: Colors.blue[200],
                child: ListTile(
                  title: Text(item.name),
                  subtitle: Text(item.price.toStringAsFixed(2)),
                  // This button use to remove )the item from wish list
                  trailing: IconButton(
                    icon: Icon(Icons.close),
                    onPressed: () {
                      item.inWishList.value = false;
                      _p.removeItem(item.id);
                    },
                  ),
                ),
              );
            },
          ),
        ));
  }
}

Cuối cùng, các bạn cần chỉnh sửa lại một chút trong file main.dart:

// main.dart
import 'package:flutter/material.dart';
import './screens/home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomeScreen(),
    );
  }
}

Bây giờ bạn đã có thể chạy thử project và kiểm tra kết quả. Happy coding…

Đừng quên theo dõi Học Lập Trình.me để khám phá các khóa học mới nhé!

Leave your thought here

Your email address will not be published. Required fields are marked *

Select the fields to be shown. Others will be hidden. Drag and drop to rearrange the order.
  • Image
  • SKU
  • Rating
  • Price
  • Stock
  • Availability
  • Add to cart
  • Description
  • Content
  • Weight
  • Dimensions
  • Additional information
  • Attributes
  • Custom attributes
  • Custom fields
Click outside to hide the compare bar
Compare
Wishlist 0
Open wishlist page Continue shopping