今日的程式碼 => GIHUB
GetX 是一個很神奇的狀態管理,裡面有路由、語言、網路、還有一些內建的方法。我個人覺得他可以使用簡短的程式碼,達到想要的效果。可以看到下面的這幾張圖片。Navigation、Dialog、SnackBar、便利的資料傳遞、快速的儲存資料、簡單的國際化語言、簡單的改片 App 顏色、快速的驗證。
他可以快速的分享資料、狀態等資訊,因此他很強大。
圖片來源 => https://raw.githubusercontent.com/jonataslaw/getx-community/master/getx.png
StreamController
get
StatelessWidget 節省一些記憶體,使用 Get 你可能不再需要使用 StatefulWidget。GetX 可能就需要一些時間更新了GetX 綁住以上是小弟的見解,有誤,歡迎留言底下和我說~~
首先 Model 的部分可以參考 【第七天 - Flutter Api、Json 物件教學】
GetConnect 是一個 GetX 提供給 Api 請求資料的一個類別。因此不需要去使用 Http 的套件了。
class PostService extends GetConnect {
//  請求 Api
  Future<List<PostModel>> fetchData() async {
    return await get(
      'https://jsonplaceholder.typicode.com/posts',
      decoder: (data) =>
      List<PostModel>.from(data.map((e) => PostModel.fromJson(e))),
    ).then((value) => value.body!).catchError((e) => throw e);
  }
}
GetxController 是一個控制器,我們繼承他,就可以操作了。也不用把他想的那麼複雜。
.obs 的話,代表我們可以觀察那筆資料。當我們使用 update() 就可以通知畫面我們更新數據了。
enum SortState { userID, id, title, body }
class PostController extends GetxController {
  var isLoading = true.obs;
  var postList = <PostModel>[].obs;
  @override
  void onInit() {
    super.onInit();
    fetchApi();
  }
  void fetchApi() async {
    isLoading(true);
    await PostService().fetchData().then((value) {
      postList.assignAll(value);
      isLoading(false);
      update();
    }).catchError((e) {});
  }
  // sort method
  void sort(SortState sortState) async {
    switch (sortState) {
      case SortState.title:
        postList.sort((a, b) => a.title.compareTo(b.title));
        break;
      case SortState.id:
        postList.sort((a, b) => a.id.compareTo(b.id));
        break;
      case SortState.userID:
        postList.sort((a, b) => a.userId.compareTo(b.userId));
        break;
      case SortState.body:
        postList.sort((a, b) => a.body.compareTo(b.body));
        break;
    }
    update();
  }
}
如果資料都有 .obs 的話,我們在 UI 的部分就可以直接 body: Obx(() => Widget) 的方式直接拿到數據。
初始化 controller 使你其對當下的所有子路由可用。
final PostController controller = Get.put(PostController());
你可以找到一個正在被其他頁面使用的 Controller。
Get.find<PostController>().sort(value);
class HomePage extends StatelessWidget {
  HomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  final PostController controller = Get.put(PostController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        actions: <Widget>[
          PopupMenuButton<SortState>(
            icon: Icon(Icons.more_vert),
            itemBuilder: (context) => [
              PopupMenuItem(
                child: Text('使用 userId 排序'),
                value: SortState.userID,
              ),
              PopupMenuItem(
                child: Text('使用 id 排序'),
                value: SortState.id,
              ),
              PopupMenuItem(
                child: Text('使用 title 排序'),
                value: SortState.title,
              ),
              PopupMenuItem(
                child: Text('使用 body 排序'),
                value: SortState.body,
              )
            ],
            onSelected: (SortState value) {
              Get.find<PostController>().sort(value);
            },
          )
        ],
      ),
      body: _MyListView()
    );
  }
}
class _MyListView extends StatelessWidget {
   _MyListView({Key? key}) : super(key: key);
  final PostController controller = Get.find<PostController>();
  @override
  Widget build(BuildContext context) {
    return Obx(() => controller.isLoading.value
        ? Center(child: CircularProgressIndicator())
        : ListView.builder(
      itemCount: controller.postList.length,
      itemBuilder: (context, index) {
        PostModel item = controller.postList[index];
        return Container(
            decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(16)),
                color: Colors.white,
                border:
                Border.all(color: Colors.blueAccent, width: 2.0)),
            margin: EdgeInsets.all(8),
            padding: EdgeInsets.all(8),
            child: RichText(
              text: TextSpan(
                style: DefaultTextStyle.of(context).style,
                children: <TextSpan>[
                  TextSpan(
                    text: item.id.toString() + ". " + item.title,
                    style: TextStyle(fontSize: 18, color: Colors.red),
                  ),
                  TextSpan(
                    text: '\n' + item.body,
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                  TextSpan(
                    text: "\nUser ID:" + item.userId.toString(),
                    style: TextStyle(fontSize: 18),
                  ),
                ],
              ),
            ));
      },
    ));
  }
}