Reputation: 11
I am working on a flutter project where I have 3 tabs in tabbar. In tab 1 and tab 2, there are lists showing some data using ListView. When clicked on a list item, I want to pass some string to tab 3 and show tab 3.
Below is my home page code:
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
TabController controller;
@override
void initState() {
super.initState();
controller = new TabController(vsync: this, length: 3);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {},
child: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("InstaPost"),
backgroundColor: Colors.black45,
bottom: TabBar(
tabs: [
Tab(
text: "Tab 1",
),
Tab(text: "Tab 2"),
Tab(text: "Tab 3"),
// Tab(text: "My Posts")
],
),
),
body: TabBarView(
children: <Widget>[
Tab1(),
Tab2(),
Tab3(),
],
),
),
),
);
}
}
So, when the app is launched the first screen will be tab 1 which shows a list of names. The code is below
class _HashtagPageState extends State<HashtagPage> {
Future<dynamic> getLists() async {
// get list
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {},
child: FutureBuilder(
future: getLists(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container(
child: SpinKitDoubleBounce(color: Colors.green, size: 100),
);
} else {
// log(snapshot.data.toString());
var data = snapshot.data;
return Container(
child: Column(
children: <Widget>[
Expanded(
child: ListView.separated(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index]),
onTap: () {
// code to pass a string value to tab 3 and navigate to tab 3
},
);
},
),
)
],
),
);
}
},
),
);
}
}
When clicked on a list item in tab 1, how should I pass a string to tab 3 and navigate to tab 3 at the same time ?
Upvotes: 1
Views: 2005
Reputation: 10397
This is what worked for me.
Set up the TabController
as such:
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: _tabController,
tabs: ...,
),
),
body: TabBarView(
controller: _tabController,
children: ...
And then to switch between tabs
// Set desired state to cause changes in target tab
setState(() {
appState.targetValue = newValue;
});
// Important for the timing/sequence of the actions
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
_tabController.animateTo(newTabIndex);
});
Upvotes: 0
Reputation: 54377
You can copy paste run full code below
You can use https://pub.dev/packages/provider
Step 1: You can save parameter in YourModel
Step 2: In Tab3
, you can access with (context.watch<YourModel>().parameter)
code snippet
class YourModel extends ChangeNotifier {
String _parameter = "";
String get parameter => _parameter;
void passParameter(String parameter) {
_parameter = parameter;
print(_parameter);
notifyListeners();
}
}
...
ChangeNotifierProvider(
create: (context) => YourModel(),
child: MyApp(),
),
...
class Tab3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("${(context.watch<YourModel>().parameter)}"));
}
}
...
return ListTile(
title: Text(data[index]),
onTap: () {
Provider.of<YourModel>(context, listen: false)
.passParameter(data[index]);
widget.controller.animateTo(2);
},
);
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'dart:collection';
import 'package:provider/provider.dart';
class YourModel extends ChangeNotifier {
String _parameter = "";
String get parameter => _parameter;
void passParameter(String parameter) {
_parameter = parameter;
print(_parameter);
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => YourModel(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(title: 'Flutter Demo Home Page'),
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin {
TabController controller;
@override
void initState() {
super.initState();
controller = TabController(vsync: this, length: 3);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {},
child: Scaffold(
appBar: AppBar(
title: Text("InstaPost"),
backgroundColor: Colors.black45,
bottom: TabBar(
controller: controller,
tabs: [
Tab(
text: "Tab 1",
),
Tab(text: "Tab 2"),
Tab(text: "Tab 3"),
// Tab(text: "My Posts")
],
),
),
body: TabBarView(
controller: controller,
children: <Widget>[
HashtagPage(controller),
Tab2(),
Tab3(),
],
),
),
);
}
}
class Tab2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("Tab2");
}
}
class Tab3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(child: Text("${(context.watch<YourModel>().parameter)}"));
}
}
class HashtagPage extends StatefulWidget {
TabController controller;
HashtagPage(this.controller);
@override
_HashtagPageState createState() => _HashtagPageState();
}
class _HashtagPageState extends State<HashtagPage> {
Future<List<String>> _future;
Future<List<String>> getLists() async {
await Future.delayed(Duration(seconds: 1), () {});
return Future.value(["a", "b", "c", "d", "e", "f", "g"]);
}
@override
void initState() {
_future = getLists();
super.initState();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {},
child: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container(
child: SpinKitDoubleBounce(color: Colors.green, size: 100),
);
} else {
// log(snapshot.data.toString());
var data = snapshot.data;
return Container(
child: Column(
children: <Widget>[
Expanded(
child: ListView.separated(
separatorBuilder: (BuildContext context, int index) =>
Divider(),
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index]),
onTap: () {
Provider.of<YourModel>(context, listen: false)
.passParameter(data[index]);
widget.controller.animateTo(2);
},
);
},
),
)
],
),
);
}
},
),
);
}
}
Upvotes: 1