[英]How to call items from JSON API and added to TabBar - Flutter
I want to create (News App), I have a list of category in the website, I followed this documentation , so I need to add website's category to my TabBar
, exactly like this image:我想创建(新闻应用程序),我在网站中有一个类别列表,我遵循了这个文档,所以我需要将网站的类别添加到我的
TabBar
中,就像这张图片一样:
How can I do that?我怎样才能做到这一点?
And I want to change direction from left to right to from right to left, How can I do that?我想从左到右改变方向,从右到左,我该怎么做?
Code:代码:
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;
})),
],
),
),
),
),
],
),
),
),),
);
}
}
I solved it, first create a file named it category.dart
, and in a file create a class:我解决了,首先创建一个名为
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;
}
}
And creating a file name it list_news.dart
:并创建一个文件名
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...")),
);
},
);
}
}
And finally, for directional of TabBar
you should change the localization of your app to support any country and support fro right to left (RTL), first go to pubspec.yaml
and new pub in (dependencies):最后,对于
TabBar
的方向,您应该更改应用程序的本地化以支持任何国家/地区并支持从右到左(RTL),首先 go 到pubspec.yaml
和新 pub in(依赖项):
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
And finally back to main.dart
file and add these code:最后回到
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(),
));
First, you're storing your JSON data, Categories, somewhere in a list, right?首先,您将 JSON 数据、类别存储在列表的某个位置,对吗? Then you'll need to setup your
TabController
so that it can sync with the updated data.然后你需要设置你的
TabController
以便它可以与更新的数据同步。 Here's a simplified example:这是一个简化的示例:
You might need to change to:您可能需要更改为:
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
Then, assuming Tabs/TabBarViews will be initialized with stuff that you've retrieved from your API call:然后,假设 Tabs/TabBarViews 将使用您从 API 调用中检索到的内容进行初始化:
List<Widget> myTabs = [...];
List<Widget> myTabsContent = [...];
Instead of using DefaultTabController
, you'll need to create your own TabController
, and initialize it in void initState()
:而不是使用
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
);
}
A simplified version of your Widget build will look like this, so modify as needed:您的 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(),
),
);
}
And as for this:至于这个:
“ And I want to change direction from left to right to from right to left, How can I do that?
“我想从左到右改变方向,从右到左,我该怎么做? ”
”
If I understand correctly, this is basically initialIndex
, set it to the last index if you want the selector to be on the right most tab.如果我理解正确,这基本上是
initialIndex
,如果您希望选择器位于最右侧的选项卡上,请将其设置为最后一个索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.