Creating a dynamic array of boxes in listview in Flutter? - json

I am really confused as per what should I do, I am pretty bad with the layout of flutter.
I want to create boxes in the listview according to the number of strings (addresses) I have in another class - what is the best practice or approach for that?
Here Is the Image of the APP
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'AddData.dart';
import 'package:donation_yoga/services/json_service.dart';
//import 'package:provider/provider.dart';
class Map extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MapState();
}
class _MapState extends State<Map> {
/* Getting Live Location */
Completer<GoogleMapController> _controllerGoogleMap = Completer();
GoogleMapController newGoogleMapController;
Position currentPosition;
var geoLocator = Geolocator();
void locatePosition() async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
currentPosition = position;
LatLng latLngPos = LatLng(position.latitude, position.longitude);
CameraPosition cameraPosition =
CameraPosition(target: latLngPos, zoom: 15.0);
newGoogleMapController
.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
}
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
myLayoutWidget(),
_buildContainer(),
_createForm(context),
],
),
);
}
Widget myLayoutWidget() {
return Container(
child: GoogleMap(
mapType: MapType.normal,
myLocationButtonEnabled: true,
initialCameraPosition: _kGooglePlex,
myLocationEnabled: true,
zoomGesturesEnabled: true,
onMapCreated: (GoogleMapController controller) {
_controllerGoogleMap.complete(controller);
newGoogleMapController = controller;
locatePosition();
},
),
);
}
}
Widget _buildContainer() {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 150.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
SizedBox(width: 10.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: _boxes(
"https://lh5.googleusercontent.com/p/AF1QipO3VPL9m-b355xWeg4MXmOQTauFAEkavSluTtJU=w225-h160-k-no",
40.738380,
-73.988426,
Centres.first),
),
SizedBox(width: 10.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: _boxes(
"https://lh5.googleusercontent.com/p/AF1QipMKRN-1zTYMUVPrH-CcKzfTo6Nai7wdL7D8PMkt=w340-h160-k-no",
40.761421,
-73.981667,
Centres.second),
),
SizedBox(width: 10.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: _boxes(
"https://images.unsplash.com/photo-1504940892017-d23b9053d5d4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
40.732128,
-73.999619,
Centres.third),
),
],
),
),
);
}
Widget _boxes(String _image, double lat, double long, String restaurantName) {
return GestureDetector(
onTap: () {},
child: Container(
child: new FittedBox(
child: Material(
color: Colors.white,
elevation: 14.0,
borderRadius: BorderRadius.circular(24.0),
shadowColor: Color(0x802196F3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: 180,
height: 200,
child: ClipRRect(
borderRadius: new BorderRadius.circular(24.0),
child: Image(
fit: BoxFit.fill,
image: NetworkImage(_image),
),
),
),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: myDetailsContainer1(restaurantName),
),
),
],
)),
),
),
);
}
Widget myDetailsContainer1(String restaurantName) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Container(
child: Text(
restaurantName,
style: TextStyle(
color: Color(0xff6200ee),
fontSize: 24.0,
fontWeight: FontWeight.bold),
)),
),
SizedBox(height: 5.0),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
child: Text(
"4.1",
style: TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
)),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStarHalf,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Text(
"(946)",
style: TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
)),
],
)),
SizedBox(height: 5.0),
Container(
child: Text(
"This is ",
style: TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
)),
SizedBox(height: 5.0),
Container(
child: Text(
"Closed \u00B7 Opens 17:00 Thu",
style: TextStyle(
color: Colors.black54, fontSize: 18.0, fontWeight: FontWeight.bold),
)),
],
);
}
Widget _createForm(BuildContext context) {
return Align(
alignment: Alignment(-0.2, -1.0),
child: TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddData()),
);
},
child: Text("Create")),
);
}
Here is my Other Class.
class Centres {
static const String first = 'This is our first location';
static const String second = 'This is our Second location';
static const String third = 'This is our Third locations';
}
The data in this class is gonna come from server.

You can use a ListView.builder to create a list of your boxes, just provide an item count that means how many widgets it will create and use the index to access each value you want to take from the lists of values.
I know i did not use you Centres class, unless you really need it to be a class, i find it easier to use a list with the values you need
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
final List<String> entries = <String>['A', 'B', 'C'];
final List<String> centres = [
'first location',
'second location',
'third location'
];
final List<double> latitudes = [40.732128, 40.732128, 40.732128];
final List<double> longitudes = [-73.999619, -73.999619, -73.999619];
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return _boxes(
entries[index],
latitudes[index],
longitudes[index],
centres[index],
);
});
}
}

You can use both ListView.builder() and PageView.builder(). in ListView you can stay in between two boxes but PageView only stays on one box. both have the itemCount and itemBuilder.

Related

passing a list of data from one screen to 2nd screen

I am passing a list of data that I called through API on 1st screen to 2nd screen and I am able to print all the data at once.
but now I want to use this data one by one and I don't know how to do that.... can you help?
this is the second screen -:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'Home_View.dart';
class AboutScreen extends StatefulWidget {
final data;
AboutScreen({Key key,#required this.data}) : super(key: key);
#override
_AboutScreenState createState() => _AboutScreenState(data:data);
}
class _AboutScreenState extends State<AboutScreen> {
var data;
_AboutScreenState({this.data});
int i = 0;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
print(data.toString()); // here i am printing all data
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 150, bottom: 40),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card(
elevation: 25,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(65),
),
child: CircleAvatar(
child: Icon(Icons.insert_emoticon_outlined, size: 100,),
radius: 80,
foregroundColor: Colors.deepPurpleAccent,
),
),
],
),
),
Text(
'${data[0][i.toString()]}', // here i wanted to get data individually but it's showing error
style: TextStyle(
fontSize: 30,
letterSpacing: 2.5,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 30,),
Text(
'Version 2.2',
style: TextStyle(
fontSize: 20,
letterSpacing: 2.5,
),
),
SizedBox(height: 30,),
Text(
'Developed By Black Console',
style: TextStyle(
fontSize: 20,
letterSpacing: 2.5,
),
),
SizedBox(height: 40,),
FloatingActionButton(
child: Icon(Icons.arrow_back_ios),
backgroundColor: Colors.deepPurpleAccent,
elevation: 16,
onPressed: (){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => homeView()
));
},
),
],
),
);
}
}
below is the data that I am getting as a list -:
I/flutter ( 4689): {alternateno: [7845659877, 9865358577], coachaddress: [anand vihar, delhi, delhi, Gautam Budha nagar, noida], coachemail: [bct#gmail.com, SSG#gmail.com], coachid: [1, 2], coachname: [BCT Coaching, SSG Coaching], primary_number: [9865328899, 9898557898], userid: [1, 1]}
can you guide me please..
Your data variable seems to be a Map, not a list, so you can access its values like this:
data['alternateno'][i]

A non-null String must be provided to a Text widget error

hello iam new to flutter and iam getting this error for the first time ! , i dont know why actually but its weird because it was running great
the error is:A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 360 pos 10: 'data != null'
my code for register state :
class Register extends StatefulWidget {
#override
_RegisterState createState() => _RegisterState();
}
class _RegisterState extends State<Register> {
TextEditingController email = TextEditingController();
TextEditingController password = TextEditingController();
TextEditingController name = TextEditingController();
TextEditingController year = TextEditingController();
TextEditingController type = TextEditingController();
final _key = GlobalKey<FormState>();
bool _secureText = true ;
showHide(){
setState(() {
_secureText=!_secureText;
});
}
check(){
final form = _key.currentState;
if(form.validate()){
form.save();
register();
}
}
void register()async{
final response = await http.post('http://msc-mu.com/register.php',body: {
'email':email.text,
'password':password.text,
'name':name.text,
'year':year.text,
'type':type.text
});
final userdata = json.decode(response.body);
String emailApi = userdata[0]['email'];
String nameAPI = userdata[0]['name'];
String id = userdata[0]['id'];
String yearAPI = userdata[0]['year'];
String typeAPI = userdata[0]['type'];
setState(() {
savePref(token, emailApi, nameAPI, id, yearAPI, typeAPI);
print(savePref(token, emailApi, nameAPI, id, yearAPI, typeAPI));
});
return userdata;
}
var token ;
savePref(String token, String email, String name,String id, String year, String type)async{
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
pref.setString('logged', token);
pref.setString('email', email);
pref.setString('name', name);
pref.setString('id', id);
pref.setString('year', year);
pref.setString('type', type);
pref.commit();
});
}
String _selectYear ;
List years = List();
Future<String> getYears()async{
final response = await http.get('http://msc-mu.com/getYears.php');
var resBody = json.decode(response.body);
setState(() {
years = resBody ;
}); }
String _selectType;
List types = List();
Future<String> getTypes ()async{
final response = await http.post('http://msc-mu.com/getlevel.php');
var resBody = json.decode(response.body);
setState(() {
types = resBody;
});
}
#override
void initState() {
// TODO: implement initState
year.text = _selectYear;
type.text = _selectType;
this.getYears();
this.getTypes();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
ClipPath(
clipper: OvalBottomBorderClipper(),
child: Image(
image: AssetImage('images/logo1.png'),
width: double.infinity,
height: MediaQuery.of(context).size.height / 3.5,
fit: BoxFit.cover,
),
),
Form(
key: _key,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 25.0,
),
Card(
elevation: 6.0,
child: TextFormField(
controller: name,
validator: MinLengthValidator(8,
errorText: ('Name must be at least 8 digit long')),
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w300,
),
decoration: InputDecoration(
prefixIcon: Padding(
padding: EdgeInsets.only(left: 20, right: 15),
child: Icon(Icons.person, color: Colors.black),
),
contentPadding: EdgeInsets.all(18),
labelText: "FullName"),
),
),
Card(
elevation: 6.0,
child: TextFormField(
controller: email,
validator: EmailValidator(
errorText: 'Please enter a valid email address'),
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w300,
),
decoration: InputDecoration(
prefixIcon: Padding(
padding: EdgeInsets.only(left: 20, right: 15),
child: Icon(Icons.email, color: Colors.black),
),
contentPadding: EdgeInsets.all(18),
labelText: "Email"),
),
),
Card(
elevation: 6.0,
child: TextFormField(
controller: password,
validator: MultiValidator([
RequiredValidator(errorText: 'Password is Required'),
MinLengthValidator(8,
errorText:
'Password must be at least 8 digit long')
]),
obscureText: _secureText,
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w300,
),
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: showHide,
icon: Icon(_secureText
? Icons.visibility_off
: Icons.visibility),
),
prefixIcon: Padding(
padding: EdgeInsets.only(left: 20, right: 15),
child: Icon(Icons.phonelink_lock,
color: Colors.black),
),
contentPadding: EdgeInsets.all(18),
labelText: "Password"),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:<Widget> [
Card(
elevation: 6.0,
child: DropdownButton<String>(
hint: Text('Choose your role'),
icon: Icon(Icons.arrow_drop_down),
iconSize: 24.0,
elevation: 16,
style: TextStyle(color: Colors.black, fontSize: 16.0),
underline: Container(
height: 2,
color: Theme.of(context).primaryColor,
),
items: types.map((item) {
return DropdownMenuItem(
child: Text(item['levelname']),
value: item['levelname'].toString(),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_selectType = newVal;
type.text = _selectType;
});
},
value: _selectType,
),
),
Card(
elevation: 6.0,
child: DropdownButton<String>(
hint: Text('Choose your Year'),
icon: Icon(Icons.arrow_drop_down),
iconSize: 24.0,
elevation: 16,
style: TextStyle(color: Colors.black, fontSize: 16.0),
underline: Container(
height: 2,
color: Theme.of(context).primaryColor,
),
items: years.map((item) {
return DropdownMenuItem(
child: Text(item['name']),
value: item['name'].toString(),
);
}).toList(),
onChanged: (newVal){
setState(() {
_selectYear = newVal ;
year.text = _selectYear;
});
},
value: _selectYear,
),
),
],
),
SizedBox(height: 20.0,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(
width: 150.0,
height: 44.0,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15.0)),
child: Text(
"Register",
style: TextStyle(fontSize: 18.0),
),
textColor: Colors.white,
color: Theme.of(context).primaryColor,
onPressed: () {
check();
}),
),
SizedBox(
width: 150.0,
height: 44.0,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15.0)),
child: Text(
"GoTo Login",
style: TextStyle(fontSize: 18.0),
),
textColor: Colors.white,
color: Theme.of(context).primaryColor,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Login()),
);
}),
),
],
),
],
),
),
],
),
),
),
);
}
}
So 2 things:
item['levelname'] is null: Your API call returns Levelname (capital L)
item['name'] is also null since it's not present in the js returned by your API call.

How do I switch to another employee by clicking on the "NEXT" button? And how do I add a page after PageView.builder?

I have employees with their images, names, and emails displayed in pageView form "the number of employees depends on the Http query of the JSON API."
I want to switch from one employee to another by clicking on the "NEXT" button.
In addition, I would like to add a page after viewing all PageViews employees.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Employees(),
);
}
}
class Employees extends StatefulWidget {
#override
_EmployeesState createState() => _EmployeesState();
}
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(initialPage: 0,);
getEmployees()async{
String theUrl = 'http://demo8161595.mockable.io/employee';
var res = await http.get(Uri.encodeFull(theUrl),headers:{"Accept":"application/json"});
var responsBody = json.decode(res.body);
print(responsBody);
return responsBody;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title:Text("Employees") ,
),
body:FutureBuilder(
future: getEmployees(),
builder: (BuildContext context , AsyncSnapshot snapshot){
List snap = snapshot.data;
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
if(snapshot.hasError){
return Center(
child: Text("Error .... "),
);
}
return PageView.builder(
itemCount: snap.length,
itemBuilder: (context,index){
return PageView(
controller:_controller,
children: <Widget>[
Container(
padding: EdgeInsets.all(5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage("${snap[index]['avatar']}"),
backgroundColor: Colors.transparent,
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Name',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${snap[index]['firstName']}" + " " + "${snap[index]['lastName']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Email',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${snap[index]['email']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height:5.0),
Padding(
padding: EdgeInsets.all(5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
child: Center(
child:Container(
child: RaisedButton.icon(
onPressed: () {
int page = _controller.page.toInt();
_controller.animateToPage(page + 1 , duration: Duration(milliseconds: 500),curve: Curves.ease,);
_controller.jumpToPage(page+1);
if(_controller.page.toInt() == snap.length)
{
Container(
child: Center(
child: Text("Last Page"),
),
);
}
},
color: Colors.teal,
icon: Icon(Icons.navigate_next,color:Colors.white ,),
label: Text("NEXT",style: TextStyle(color: Colors.white),),
),
),
),
),
),
],
),
),
],
),
),
],
);
},
);
},
),
);
}
}
EDIT 2: Changed the code.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Employees(),
);
}
}
class Employees extends StatefulWidget {
#override
_EmployeesState createState() => _EmployeesState();
}
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(initialPage: 0,);
getEmployees()async{
String theUrl = 'http://demo8161595.mockable.io/employee';
var res = await http.get(Uri.encodeFull(theUrl),headers:{"Accept":"application/json"});
var responsBody = json.decode(res.body);
print(responsBody);
return responsBody;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title:Text("Employees") ,
),
body:FutureBuilder(
future: getEmployees(),
builder: (BuildContext context , AsyncSnapshot snapshot){
List snap = snapshot.data;
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
if(snapshot.hasError){
return Center(
child: Text("Error .... "),
);
}
return PageView.builder(
itemCount: snap.length,
itemBuilder: (context,index){
return PageView(
controller:_controller,
children: snap.map((e) => employeePage(e,snap.length)).toList(),
);
},
);
},
),
);
}
Widget employeePage(node , length)
{
return Container(
padding: EdgeInsets.all(5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage("${node['avatar']}"),
backgroundColor: Colors.transparent,
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Name',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${node['firstName']}" + " " + "${node['lastName']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Email',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${node['email']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height:5.0),
Padding(
padding: EdgeInsets.all(5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
child: Center(
child:Container(
child: RaisedButton.icon(
onPressed: () {
int page = _controller.page.toInt();
_controller.animateToPage(page + 1 , duration: Duration(milliseconds: 500),curve: Curves.ease,);
_controller.jumpToPage(page+1);
if(_controller.page.toInt() == length)
{
Container(
child: Center(
child: Text("Last Page"),
),
);
}
},
color: Colors.teal,
icon: Icon(Icons.navigate_next,color:Colors.white ,),
label: Text("NEXT",style: TextStyle(color: Colors.white),),
),
),
),
),
),
],
),
),
],
),
);
}
}
EDIT 1: After you have changed the code i have realized your mistake.
This is how the PageView widget works
PageView(
controller: _controller,
children: [
MyPage1Widget(),
MyPage2Widget(),
MyPage3Widget(),
],
)
Here you are providing 3 screens in the children of the PageView and asking page view to go to the next one when _controller.jumpToPage() or _controller.next() is called.
But in your code, in the PageView widget children you have provided a single container, so there is only one screen to show. Which is why you are not able to see any changes.
Previous Answer :
What you need is the PageViewController through which you can jump/animate to any page.
STEP 1 : instantiate the Page View Controller
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(
initialPage: 0,
);
STEP 2 : Add the Page View Controller in the PageView
return PageView(
controller:_controller
children: <Widget>[
Container(
padding: EdgeInsets.all(5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage("${snap[index]['avatar']}"),
backgroundColor: Colors.transparent,
),
),
.....
STEP 3 : Change the page view when button tapped
onTap: () {
//Current page
int page = _controller.page.toInt();
//Animate to page
_controller.animateToPage(page + 1);
//Jump to page
controller.animateToPage(page + 1);
//if page view reaches last page
if(controller.page.toInt() == snap.length)
{
//Navigate to some page
}
}
Given above is the OnTapped function, you can wrap the Text widget in a Button and insert the code in the ontapped parameter.
Let me know if you face errors.

How to send arguments to another screen? Flutter

I am trying to send the arguments of a "participant" to another screen, I could do it with a ListView and load the list of events, but it is not working in the same way with the participants, now if the list works, but when I tap and I want to see the info of the "participant" everything comes out in null:
In this part I create the participant and generate the list to be able to visualize it, and by giving the tap I send the info of this (according to me)
Widget _crearListadoParticipantes() {
return FutureBuilder<List<Participantes>>(
future: eventosProvider.cargarParticipantes(evento, participantes),
builder: (context, snapshot) {
if ( snapshot.hasData ) {
final participantes = snapshot.data;
return ListView.builder(
itemCount: participantes.length,
itemBuilder: (context, i) {
return _crearParticipante(context, participantes[i], evento);
}
);
} else if (snapshot.hasError){
return Center(child: Text("${snapshot.error}"));
} else {
return Center( child: CircularProgressIndicator());
}
},
);
}
Widget _crearParticipante(BuildContext context, Participantes participantes, EventoModel evento) {
return Padding(
padding: EdgeInsets.all(12.0),
child: GestureDetector(
child: RichText(
softWrap: false,
text: TextSpan(
style: TextStyle(
color: Colors.black,
fontFamily: "Lato_LightItalic",
fontStyle: FontStyle.italic,
fontSize: 20.0,
fontWeight: FontWeight.w400
),
children: [
TextSpan(text: ' '+'${participantes.numero}',
style: TextStyle(
fontWeight: FontWeight.w600
)
),
TextSpan(text: " "),
TextSpan(text: '${participantes.apellido} ${participantes.nombre}',)
],
),
),
onTap: () => Navigator.pushNamed(context, 'destalleParticipante', arguments: evento),
),
);
}
And this is where I am supposed to receive the arguments of the participant to whom I tapped, but as I say, a null returns
class DetalleParticipante extends StatefulWidget {
#override
_DetalleParticipanteState createState() => _DetalleParticipanteState();
}
class _DetalleParticipanteState extends State<DetalleParticipante> {
final eventosProvider = new EventosProvider();
EventoModel evento = new EventoModel();
Participantes participantes = new Participantes();
#override
Widget build(BuildContext context) {
final EventoModel eventoData = ModalRoute.of(context).settings.arguments;
if ( eventoData != null ) {
evento = eventoData;
}
print(participantes.nombre);
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(0),
child: AppBar(
backgroundColor: Color(0xFF249FE2),
),
),
backgroundColor: Colors.white,
body: Container(
color: Colors.white,
child: Column(
children: <Widget>[
_encabezadoParticipante(context, AssetImage("assets/icon/info_corredor.png"), participantes, evento),
],
),
),
);
}
Widget _backBottom() {
return FloatingActionButton(
elevation: 0.0,
backgroundColor: Colors.white,
child: Icon(
Icons.arrow_back,
size: 45.0,
color: Colors.black,
),
onPressed: (){
Navigator.pop(context);
},
);
}
Widget _encabezadoParticipante(BuildContext context, AssetImage image, Participantes participantes, EventoModel evento) {
return Container(
color: Colors.grey[600],
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_backBottom(),
Flexible(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text('${participantes.apellido}',
textAlign: TextAlign.center,
maxLines: 3,
softWrap: true,
style: TextStyle(
color: Colors.white,
fontFamily: "Lato",
fontStyle: FontStyle.italic,
fontSize: 30.0,
fontWeight: FontWeight.bold
),
),
),
),
Image(image: image,
fit: BoxFit.cover,
),
],
),
),
);
}
}

How to make a floating search bar on top of Google Maps in Flutter?

I am trying to make a floating search bar on top of my map, the same way there is a search bar in the Google Maps app. Something like this -
I can't seem to make it to be floating. The search bar does not overlay on the map. It rather just renders in its own box.
void main() {
runApp(MaterialApp(
title: 'Navigation Basics',
theme: ThemeData.dark(),
home: MyAppState(),
));
}
class MyAppState extends StatelessWidget {
final LatLng _center = const LatLng(28.535517, 77.391029);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: FloatAppBar(),
body: Map(_center),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Report()),
);
},
child: Icon(Icons.add, semanticLabel: 'Action'),
backgroundColor: Colors.black87,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomNavBar(),
),
);
}
}
class FloatAppBar extends StatelessWidget with PreferredSizeWidget {
#override
Widget build(BuildContext context) {
return (FloatingSearchBar(
trailing: CircleAvatar(
child: Text("RD"),
),
drawer: Drawer(
child: Container(),
),
onChanged: (String value) {},
onTap: () {},
decoration: InputDecoration.collapsed(
hintText: "Search...",
),
children: [
],
));
}
#override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
I expect the search bar to float on top of the map but it renders in its own box.
I have achieved the same results in here:
Code:
Stack(
children: <Widget>[
// Replace this container with your Map widget
Container(
color: Colors.black,
),
Positioned(
top: 10,
right: 15,
left: 15,
child: Container(
color: Colors.white,
child: Row(
children: <Widget>[
IconButton(
splashColor: Colors.grey,
icon: Icon(Icons.menu),
onPressed: () {},
),
Expanded(
child: TextField(
cursorColor: Colors.black,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.go,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding:
EdgeInsets.symmetric(horizontal: 15),
hintText: "Search..."),
),
),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: CircleAvatar(
backgroundColor: Colors.deepPurple,
child: Text('RD'),
),
),
],
),
),
),
],
),
UPDATE
I think this will be more suitable for you now => FloatingSearchBar by Rody Darvis :")