簡體   English   中英

如何從 JSON API 調用項目並添加到 TabBar - Flutter

[英]How to call items from JSON API and added to TabBar - Flutter

我想創建(新聞應用程序),我在網站中有一個類別列表,我遵循了這個文檔,所以我需要將網站的類別添加到我的TabBar中,就像這張圖片一樣:

在此處輸入圖像描述

我怎樣才能做到這一點?

我想從左到右改變方向,從右到左,我該怎么做?

代碼:

Category Class:

import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<Category> fetchCatgeory() async {
  final response = await http.get("url");

  if (response.statusCode == 200) {
    return Category.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed to load category');
  }
}

class Category {
  final int id;
  final String title;

  Category({this.id, this.title});

  factory Category.fromJson(Map<String, dynamic> json) {
    return Category (
      id: json['id'],
      title: json['title'],
    );
  }

}

HomePage Class:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:munaw3_news/extra/json_file.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();

  final Future<Category> catg;

  HomePage({Key key, this.catg}) : super(key: key);

}

class _HomePageState extends State<HomePage> {

  _HomePageState();

  int a = 0;
  Future<Category> catg;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    catg = fetchCatgeory();
  }
  bool isPressed = false;

  _pressed() {
    var newVal = true;
    if(isPressed) {
      newVal = false;
    } else {
      newVal = true;
    }

    setState((){
      isPressed = newVal;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: DefaultTabController(
        length: catg.toString().length,
        child: Scaffold(
          appBar: AppBar(
            title: Image.asset('assets/logo.png', fit: BoxFit.cover,),
            centerTitle: true,
            backgroundColor: Colors.grey[900],
            bottom: TabBar(

              tabs: [
                // Tab(text: catg[0],),
                // Tab(text: catg[1],),
                // Tab(text: catg[2],),
                // Tab(text: catg[3],)
              ],
            ),
      ),
      body: TabBarView(

        children: [
          // Tab(text: catg[0],),
          // Tab(text: catg[1],),
          // Tab(text: catg[2],),
          // Tab(text: catg[3],)
        ],

      ),
      bottomNavigationBar: BottomAppBar(
        clipBehavior: Clip.antiAlias,
        elevation: 0,
        color: Colors.grey[900],
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Container(
              height: 5,
              width: double.infinity,
              color: Colors.grey[900],
            ),
            Padding(
              padding: const EdgeInsets.only(left: 8, right: 8),
              child: Container(
                height: 60,
                child: Align(
                  alignment: FractionalOffset.center,
                  child: new Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      IconButton(icon: Icon(Icons.info), color: Colors.grey[600], iconSize: 30,
                                  disabledColor: Colors.white,
                                  onPressed: a==3 ? null : () => setState(() {
                                    a=3;
                                  })),

                      IconButton(icon: Icon(Icons.local_mall), color: Colors.grey[600], iconSize: 30,
                                  disabledColor: Colors.white,
                                  onPressed: a==2 ? null : () => setState(() {
                                    a=2;
                                  })),

                      IconButton(icon: Icon(Icons.bookmark), color: Colors.grey[600], iconSize: 30,
                                  disabledColor: Colors.white,
                                  onPressed: a==1 ? null : () => setState(() {
                                    a=1;
                                  })),

                      IconButton(icon: Icon(Icons.home), color: Colors.grey[600], iconSize: 30,
                                  disabledColor: Colors.white,
                                  onPressed: a==0 ? null : () => setState(() {
                                    a=0;
                                  })),
                    ],
                  ),
                ),
              ),
            ),

          ],
        ),
      ),
      ),),

    );
  }
}

我解決了,首先創建一個名為category.dart的文件,然后在一個文件中創建一個 class:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class Category {
  int id;
  String title;

  Category({
    this.id,
    this.title,
  });

  static Future<List<Category>> getCategories() async {
    http.Response response = await http.get("JSON API Url");

    List<Category> list = [];

    try {
      if (response.statusCode == 200) {
        Map<String, dynamic> map = json.decode(response.body);

        for (var map in map['categories']) {
          list.add(Category(id: map['id'], title: map['title']));
        }
      }
    } catch (e, _) {
      debugPrint(e.toString());
    }
    return list;
  }
}

並創建一個文件名list_news.dart

import 'package:flutter/material.dart';
import 'package:munaw3_app/model/category.dart';

class ListNews extends StatefulWidget {
  ListNews({Key key}) : super(key: key);

  @override
  _ListNewsState createState() => _ListNewsState();
}

class _ListNewsState extends State<ListNews> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Category>>(
      future: Category.getCategories(), //NOT Recommended
      builder: (c, s) {
        if (s.hasData) {
          List<Tab> tabs = new List<Tab>();

          for (int i = 0; i < s.data.length; i++) {
            tabs.add(Tab(
              child: Text(
                s.data[i].title,
                style: TextStyle(color: Colors.white),
              ),
            ));
          }
          return DefaultTabController(
            length: s.data.length,
            child: Scaffold(
              appBar: AppBar(
                title: Image.asset('assets/logo.png', fit: BoxFit.cover),
                backgroundColor: Colors.grey[900],
                bottom: TabBar(
                  isScrollable: true,
                  tabs: tabs,
                ),
              ),
            ),
          );
        }
        if (s.hasError) print(s.error.toString());
        return Scaffold(
          body: Center(
              child: Text(s.hasError ? s.error.toString() : "Loading...")),
        );
      },
    );
  }
}

最后,對於TabBar的方向,您應該更改應用程序的本地化以支持任何國家/地區並支持從右到左(RTL),首先 go 到pubspec.yaml和新 pub in(依賴項):

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

最后回到main.dart文件並添加以下代碼:

import 'package:flutter/material.dart';
import 'package:munaw3_app/views/list_news.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() => runApp(MaterialApp(
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [const Locale("ar", "AE")], // Here you can add any language you need
      home: ListNews(),
    ));

首先,您將 JSON 數據、類別存儲在列表的某個位置,對嗎? 然后你需要設置你的TabController以便它可以與更新的數據同步。 這是一個簡化的示例:

您可能需要更改為:

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {

然后,假設 Tabs/TabBarViews 將使用您從 API 調用中檢索到的內容進行初始化:

List<Widget> myTabs = [...];
List<Widget> myTabsContent = [...];

而不是使用DefaultTabController ,您需要創建自己的TabController ,並在void initState()中對其進行初始化:

TabController myTabController;

@override
void initState() {
  super.initState();
  var lastIndex = myTabs.length - 1;
  myTabController = new TabController(
      vsync: this,
      length: myTabs.length,
      initialIndex: lastIndex
  );
}

您的 Widget 構建的簡化版本如下所示,因此請根據需要進行修改:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text(widget.title),
      bottom: TabBar(
        isScrollable: true,
        controller: myTabController,
        tabs: myTabs.toList(),
      ),
    ),

    body: TabBarView(
      controller: myTabController,
      children: myTabsContent.toList(),
    ),
  );
}

至於這個:

我想從左到右改變方向,從右到左,我該怎么做?

如果我理解正確,這基本上是initialIndex ,如果您希望選擇器位於最右側的選項卡上,請將其設置為最后一個索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM