I tried to add resizeToAvoidBottomPadding: false below Scaffold but it doesn't change anything.
Could anyone help me figure out how to fix this?
Here is the entire code of the file:
class showAll extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _showAllState();
}
}
class _showAllState extends State<showAll> {
navigateToDetail(DocumentSnapshot indexedData, context) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(itemSelected: indexedData)));
}
Widget build(BuildContext context) {
return Scaffold(
// resizeToAvoidBottomPadding: false, <-- it does not work...
// resizeToAvoidBottomInset: false, <-- it does not work...
appBar: AppBar(
title: Text('All Items'),
backgroundColor: Colors.teal,
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(
context: context,
delegate: CustomSearchDelegate(),
);
},
),
],
),
body: StreamBuilder(
stream: Firestore.instance
.collection('ARC_items')
.orderBy('name')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('loading...');
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(
snapshot.data.documents[index].data['name'].toString()),
subtitle: Text(
'Total amount: ${snapshot.data.documents[index].data['# of items'].toString()}'),
onTap: () {
navigateToDetail(snapshot.data.documents[index], context);
// testingReservations(
// snapshot.data.documents[index].documentID);
},
),
);
}),
);
}
}
class CustomSearchDelegate extends SearchDelegate {
navigateToDetail(DocumentSnapshot indexedData, context) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(itemSelected: indexedData)));
}
displayGrids(data, context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: Padding(
padding: EdgeInsets.all(5.0),
child: GridView.count(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: data.map<Widget>(
(categoryInfo) {
return GestureDetector(
child: GridTile(
child: CustomCell(categoryInfo),
),
onTap: () {
navigateToDetail(categoryInfo, context);
},
);
},
).toList(),
),
),
),
],
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = '';
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
// TODO: implement buildResults
return null;
}
#override
Widget buildSuggestions(BuildContext context) {
// If you want to add search suggestions as the user enters their search term, this is the place to do that.
return StreamBuilder(
stream: Firestore.instance.collection('ARC_items').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return const Text('loading...');
final results = snapshot.data.documents.where(
(DocumentSnapshot a) =>
a.data['name'].toString().toLowerCase().contains(
query.trim().toLowerCase(),
),
);
return displayGrids(results, context);
});
}
}
Related
Validation is working well but incase of validation error, option to select on option is disabled.
DropdownButtonFormField(
isExpanded: true,
hint: Text('Gender'),
value: _selectedGender,
onChanged: (newValue) {
setState(() {
_selectedGender = newValue;
});
},
items: _gender.map((gender) {
return DropdownMenuItem(
child: new Text(gender),
value: gender,
);
}).toList(),
validator: (value) {
if (value == null)
return "Please select your gender";
return null;
},
),
Above code is in a page view,
my variables
List<String> _gender = ['Male', 'Female'];
String _selectedGender;
My entire Form code : just reduced to one field its very long
class SignUp extends StatefulWidget {
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final List<GlobalKey<FormState>> _page = [
GlobalKey<FormState>(),
GlobalKey<FormState>(),
GlobalKey<FormState>(),
];
final _key = GlobalKey<ScaffoldState>();
List<String> _gender = ['Male', 'Female'];
String _selectedGender;
void changePage() {
if (currentPageValue < 3) {
if (_page[currentPageValue].currentState.validate()) {
setState(() {
currentPageValue += 1;
});
}
}
}
#override
Widget build(BuildContext context) {
var deviceSize = MediaQuery.of(context).size;
var deviceWidth = deviceSize.width;
return Scaffold(
key: _key,
backgroundColor: _backgroundColor,
appBar: AppBar(
backgroundColor: _backgroundColor,
leading: IconButton(
icon: Icon(
currentPageValue == 0 ? Icons.close : Icons.keyboard_backspace,
size: 20.0,
color: _headerColor,
),
onPressed: currentPageValue == 0
? () => Navigator.pop(context)
: () => back()),
centerTitle: true,
elevation: 0.0,
),
body: Form(
key: _page[0],
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: deviceWidth * 0.9,
height: dropDownHeight,
child: ButtonTheme(
child: DropdownButtonFormField(
isExpanded: true,
hint: Text('Gender'),
value: _selectedGender,
onChanged: (newValue) {
setState(() {
_selectedGender = newValue;
});
},
items: _gender.map((gender) {
return DropdownMenuItem(
child: new Text(gender),
value: gender,
);
}).toList(),
validator: (value) {
if (value == null) return "Please select your gender";
return null;
},
),
),
),
RaisedButton(
color: buttonColor,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0),
),
child: Text(
'Next',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w400,
),
),
onPressed: () => changePage(),
),
],
),
),
),
);
Looking at your code, I strongly recommend you create 3 different Forms and validate them separately, so you don't have any problem regarding form state. To achieve this, you can just wrap the fields into their respective Form and be sure not to mix the forms nor have them one inside the other.
Below, an example based on your code and on what I have said:
class SignUp extends StatefulWidget {
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final _page1 = GlobalKey<FormState>();
final _page2 = GlobalKey<FormState>();
final _page3 = GlobalKey<FormState>();
final _key = GlobalKey<ScaffoldState>();
int currentPageValue;
List<String> _gender = ['Male', 'Female'];
String _selectedGender;
void changePage(GlobalKey<FormState> page) {
if (currentPageValue < 3) {
if (page.currentState.validate()) {
setState(() {
currentPageValue += 1;
});
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _key,
body: ListView(
children: <Widget>[
Form(
key: _page1,
child: Column(
children: [
DropdownButtonFormField(
isExpanded: true,
hint: Text('Gender'),
value: _selectedGender,
onChanged: (newValue) {
setState(() {
_selectedGender = newValue;
});
},
items: _gender.map((gender) {
return DropdownMenuItem(
child: new Text(gender),
value: gender,
);
}).toList(),
validator: (value) {
if (value == null) return "Please select your gender";
return null;
},
),
RaisedButton(
child: Text('Next'),
onPressed: () => changePage(_page1),
),
],
),
),
Form(
key: _page2,
child: Column(
children: [
// SomeField(
//
// ),
// SomeOtherField(
//
// ),
RaisedButton(
child: Text('Next'),
onPressed: () => changePage(_page2),
),
],
),
),
],
),
);
}
}
Here I want I've some listed item and I want to sort item them on its id or rating. when I click on the side drawer button it will need to rearrange the list view with sorted items hope you understand my question.
I've tried this smooth_sort package for sorting but it won't work for me because it will sort based on the index. and I want to sort based on my own value.
Here is the output image
Here is my code
class _MapAddressListingScreenState extends State<MapAddressListingScreen>
with AfterLayoutMixin<MapAddressListingScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
List addressData;
#override
void afterFirstLayout(BuildContext context) {
_getAddress();
}
_getAddress() {
List requestedLatlong = ModalRoute.of(context).settings.arguments;
print("============================Address Data");
print(requestedLatlong);
setState(() {
addressData = requestedLatlong;
});
}
List<Widget> _addressData() {
List<Widget> _address = [];
for (int i = 0; i < addressData.length; i++) {
_address.add(
GestureDetector(
onTap: () {
print('address list taped');
AddWalkinModel model = widget.addWalkinModel;
print("After model");
model.fromMap = false;
model.fromMapListing = true;
model.autoAssign = addressData[i]['autoAssign'];
model.branchId = addressData[i]['branchId'];
model.branchServiceId = addressData[i]['branchServiceId'];
print("After Model Model");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DynamicScreen(
addWalkinModel: model,
),
),
);
},
child: AddressListingTile(listingTileData: addressData[i]),
),
);
}
return _address;
}
Widget itemCard() {
return Container(
child: Column(
children: _addressData(),
),
);
}
#override
Widget build(BuildContext context) {
var colorStyles = Theming.colorstyle(context);
return Scaffold(
key: _scaffoldKey,
backgroundColor: colorStyles['primary'],
appBar: AppBar(
title: Text("BSP Listview "),
centerTitle: true,
elevation: 0,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.sort),
onPressed: () {
_scaffoldKey.currentState.openEndDrawer();
},
),
],
),
endDrawer: Drawer(
child: Column(
children: <Widget>[
SizedBox(
height: 100,
),
FlatButton(
onPressed: () {
ratingSort.shuffle();
},
child: Text("sort")),
],
),
),
body: Stack(
children: <Widget>[
Container(
child: ClipRRect(
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(30.0),
topRight: const Radius.circular(30.0)),
child: Stack(
children: <Widget>[
SingleChildScrollView(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
itemCard(),
],
),
),
)
],
),
),
),
],
),
);
}
}
You can use the sort method of the list for sorting the list in the specific format as follows
#override
void initState() {
super.initState();
for(int i=0;i<fields.length;i++) {
print("BEFORE==>>> ${fields[i].rating}");
}
fields.sort((a, b) => a.rating.compareTo(b.rating)); ///FROM THIS LINE YOU CAN PERFORM SHORTING ACCORDING TO THE RATING BASES
for(int i=0;i<fields.length;i++) {
print("AFTER==>>> ${fields[i].rating}");
}
}
And i have use the my demo custom list for it
List<Fields> fields = [
new Fields(
'DEFAULT CATEGORY',
2,
),
new Fields(
'DEFAULT CATEGORY',
1,
),
new Fields(
'DEFAULT CATEGORY',
5,
),
new Fields(
'DEFAULT CATEGORY',
3,
),
new Fields(
'DEFAULT CATEGORY',
4,
),
];
And output will be follow
Please check the full source of code for it
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutterlearningapp/colors.dart';
class HomeScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _HomeScreen();
}
}
class _HomeScreen extends State<HomeScreen> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: Text("Demo Scroll"),
),
body: Container(
height: double.infinity,
width: double.infinity,
color: Colors.white,
child: Column(
children: <Widget>[
RaisedButton(
child: Text("Shoring"),
onPressed: (){
setState(() {
fields.sort((a, b) => a.rating.compareTo(b.rating));
});
},
),
Expanded(
child: ListView.builder
(
itemCount: fields.length,
itemBuilder: (BuildContext ctxt, int index) {
return ListTile(
title: new Text("Rating #${fields[index].rating}"),
subtitle: new Text(fields[index].title),
);
}
) ,
)
],
),
),
));
}
}
class Fields {
final String title;
final int rating;
Fields(this.title, this.rating);
}
List<Fields> fields = [
new Fields(
'Two',
2,
),
new Fields(
'One',
1,
),
new Fields(
'DEFAULT CATEGORY',
5,
),
new Fields(
'Three',
3,
),
new Fields(
'Four',
4,
),
];
And above output of the program as follow
I have Button and I want to call a method to check a case, if the case is true, then I do some code, else I want to show a dialog.
The code for the UI:
new RaisedButton(key:null, onPressed:buttonPressed,
color: const Color(0xFFe0e0e0),
child:
new Text(
"Submit",
style: new TextStyle(fontSize:12.0,
color: const Color(0xFF000000),
fontWeight: FontWeight.w200,
fontFamily: "Roboto"),
)
)
The method is:
Future<void> buttonPressed() async {
if (DataStore.shared.getPerson() != null)
{
// do some code...
}
else
{
// show dialog
await showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Login'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Login is required to submit.'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Login'),
onPressed: () {
Navigator.pushNamed(context, "/login");
},
),
],
);
},
);
}
}
The Dialog is not shown.
I'm having trouble with app bar animation, I'm using SilverAppBar, in my app. So, the problem is when I'm in the middle of my list and I scroll up, the app bar does not appear, but it appears just when scrolling reaches the top of the items list. I already tested the snap parameter and give it true, but not the result I expect. I have ideas about creating a custom animation for this, but I'm not too experienced in Flutter, and also if there is a way to add parameters, or another widget that will work for my situation, it would be great.
The actual code of the demo I'm using:
Widget _search() => Container(
color: Colors.grey[400],
child: SafeArea(
child: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
enabled: false,
style: TextStyle(fontSize: 16, color: Colors.white),
decoration: InputDecoration(
prefix: SizedBox(width: 12),
hintText: "Search",
contentPadding:
EdgeInsets.symmetric(horizontal: 32.0, vertical: 14.0),
border: InputBorder.none,
),
),
),
)),
);
Container _buildBody() {
return Container(
child: new GridView.count(
crossAxisCount: 2,
children: List.generate(100, (index) {
return Center(
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline,
),
);
}),
));
}
#override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
body: new NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
new SliverAppBar(
title: Text("Demo",
style: TextStyle(
color: Colors.white,
)),
pinned: false,
floating: true,
forceElevated: innerBoxIsScrolled,
),
];
},
body: new Column(children: <Widget>[
_search(),
new Expanded(child: _buildBody())
])));
}
The result I have now:
Image 1
The result I got after giving true to the snap parameter:
Image 2
Plenty of applications like WhatsApp, Facebook, LinkedIn ... have this animating app bar. To explain more what exactly I expect with this animating app bar, I added an example of Google Play Store, showing the wanted animation: Play Store example
I had a similar issue with CustomScrollView and SliverAppbar using refresh indicator i ended up creating my own custom appbar.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class HomeView extends StatefulWidget {
#override
HomeState createState() => HomeState();
}
class HomeState extends State<HomeView> with SingleTickerProviderStateMixin {
bool _isAppbar = true;
ScrollController _scrollController = new ScrollController();
#override
void initState() {
super.initState();
_scrollController.addListener(() {
if (_scrollController.position.userScrollDirection ==
ScrollDirection.reverse) {
appBarStatus(false);
}
if (_scrollController.position.userScrollDirection ==
ScrollDirection.forward) {
appBarStatus(true);
}
});
}
void appBarStatus(bool status) {
setState(() {
_isAppbar = status;
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: AnimatedContainer(
height: _isAppbar ? 55.0 : 0.0,
duration: Duration(milliseconds: 200),
child: CustomAppBar(),
),
),
body: ListView.builder(
controller: _scrollController,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return container();
},
),
),
);
}
}
Widget container() {
return Container(
height: 80.0,
color: Colors.pink,
margin: EdgeInsets.all(8.0),
width: 100,
child: Center(
child: Text(
'Container',
style: TextStyle(
fontSize: 18.0,
),
)),
);
}
class CustomAppBar extends StatefulWidget {
#override
AppBarView createState() => new AppBarView();
}
class AppBarView extends State<CustomAppBar> {
#override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Colors.white,
leading: InkWell(
onTap: () => {},
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
backgroundColor: Colors.white,
child: ClipOval(
child: Image.network(
'https://images.squarespace-cdn.com/content/5aee389b3c3a531e6245ae76/1530965251082-9L40PL9QH6PATNQ93LUK/linkedinPortraits_DwayneBrown08.jpg?format=1000w&content-type=image%2Fjpeg'),
),
),
),
),
actions: <Widget>[
IconButton(
alignment: Alignment.centerLeft,
icon: Icon(
Icons.search,
color: Colors.black,
),
onPressed: () {},
),
],
title: Container(
alignment: Alignment.centerLeft,
child: Text("Custom Appbar", style: TextStyle(color: Colors.black),)
),
);
}
}
To get this functionality to work, you will need to use the CustomScrollView widget instead of NestedScrollView. Google Documentation
Here is a working example:
class MyHomeState extends State<MyHome> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
pinned: false,
snap: false,
floating: true,
flexibleSpace: FlexibleSpaceBar(
title: Text('Demo'),
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 50,
),
),
],
)
);
}
}
Example of this running here
I was able to make the floating Appbar with Tabbar similar to that of WhatsApp by using SliverAppbar with NestedScrollView. Do remember to add floatHeaderSlivers: true, in NestedScrollView. Link to sample code
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: CustomSliverAppbar(),
);
}
}
class CustomSliverAppbar extends StatefulWidget {
#override
_CustomSliverAppbarState createState() => _CustomSliverAppbarState();
}
class _CustomSliverAppbarState extends State<CustomSliverAppbar>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
_tabController = TabController(
initialIndex: 0,
length: 2,
vsync: this,
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
title: Text(
"WhatsApp type sliver appbar",
),
centerTitle: true,
pinned: true,
floating: true,
bottom: TabBar(
indicatorColor: Colors.black,
labelPadding: const EdgeInsets.only(
bottom: 16,
),
controller: _tabController,
tabs: [
Text("TAB A"),
Text("TAB B"),
]),
),
];
},
body: TabBarView(
controller: _tabController,
children: [
TabA(),
const Center(
child: Text('Display Tab 2',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
),
],
),
),
);
}
#override
void dispose() {
_tabController.dispose();
super.dispose();
}
}
class TabA extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scrollbar(
child: ListView.separated(
separatorBuilder: (context, child) => Divider(
height: 1,
),
padding: EdgeInsets.all(0.0),
itemCount: 30,
itemBuilder: (context, i) {
return Container(
height: 100,
width: double.infinity,
color: Colors.primaries[Random().nextInt(Colors.primaries.length)],
);
},
),
);
}
}
I am trying to show the following flare animation in my Flutter App
https://www.2dimensions.com/a/pollux/files/flare/smiley-switch
I downloaded it as binary
FlareActor(
"assets/Smiley Switch.flr",
color: Colors.black,
fit: BoxFit.contain,
animation: "On",
),
I want the animation to toggle from on to off just like a switch widget so i wrapped it inside a InkWell
var a = false;
return Center(
child: InkWell(
onTap: (){
if(a){
setState(() {
a = false;
});
} else {
setState(() {
a = true;
});
}
},
child: FlareActor(
"assets/Smiley Switch.flr",
color: Colors.black,
fit: BoxFit.contain,
animation: a ? "On" : "Off",
),
),
);
but the above code does not work. How to toggle the animation of FlareActor?
Double check if you declared your flare file (.flr) in pubspec.yaml
Below is a working example
import "package:flare_flutter/flare_actor.dart";
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flare Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: 'Flare-Flutter'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isOn = false;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(title: Text(widget.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: InkWell(
onTap: () {
setState(() {
isOn = !isOn;
});
},
child: FlareActor(
"assets/flare/SmileySwitch.flr",
alignment: Alignment.center,
fit: BoxFit.contain,
animation: isOn ? "On" : "Off",
),
))
],
),
));
}
}