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:
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:
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
:
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):
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
And finally back to main.dart
file and add these code:
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? Then you'll need to setup your TabController
so that it can sync with the updated data. 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:
List<Widget> myTabs = [...];
List<Widget> myTabsContent = [...];
Instead of using DefaultTabController
, you'll need to create your own TabController
, and initialize it in 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:
@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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.