Flutter - Position list view below another widget - mobile

I'm starting with Flutter, and I came across a layout with which I'm having trouble building, below a visual example:
I already tried something like:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('App'),
),
body: new Column(
children: <Widget>[
new Text('LISTA',
style: new TextStyle(
fontSize: 15.2,
fontWeight: FontWeight.bold,
)
),
new Container(
height: 200.0,
child: new ListView(
children: <Widget>[
new RaisedButton(
onPressed: null,
child: new Text("text button"),
),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(
onPressed: null,
child: new Text("text button 2"),
)
],
),
)
]
)
),
);
}
}
But for Container it needs a height, and I need it to take up the rest of the screen.

new Column(
children: <Widget>[
new Text('LISTA', style: new TextStyle(
fontSize: 15.2,
fontWeight: FontWeight.bold,
)),
new Expanded(
child: new Container(
decoration: new BoxDecoration(color: Colors.blue),
child: new ListView(
children: <Widget>[
new RaisedButton(
onPressed: null,
child: new Text("text button"),
),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(
onPressed: null,
child: new Text("text button 2"),
)
],
),
)
)
]
)

Related

how to show sub category data by category in flutter from sqlite db

import 'package:flutter/material.dart';
import 'package:stone_recipe_app/homepage.dart';
import 'package:stone_recipe_app/models/recipe.dart';
import 'package:share_plus/share_plus.dart';
class DetailedScreen extends StatelessWidget {
DetailedScreen({Key? key, required this.recipe, required this.index}) : super(key: key);
List<Recipe>? recipe;
int index;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Row(
children: [
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage()));
},
),
Text(
'Back',
style: TextStyle(color: Color(0xff007AFF)),
)
],
),
iconTheme: const IconThemeData(color: Color(0xff007AFF)),
title: Center(
child: Text(
recipe![index].recipe_name,
style: TextStyle(color: Colors.black),
),
),
backgroundColor: Colors.white,
elevation: 0,
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(200),
),
child: Container(
width: 400,
height: 200,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(9.0)),
image: DecorationImage(
image: AssetImage("images/cook.jpg"),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
blurRadius: 5,
color: Colors.black,
)
],
),
),
),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
const Icon(
Icons.file_download_sharp,
color: Colors.blue,
size: 40,
),
const Icon(
Icons.document_scanner,
size: 40,
),
IconButton(
onPressed: () {
Share.share(recipe![index].recipe_prep);
},
icon: const Icon(
Icons.share,
color: Colors.blue,
size: 40,
)),
const Icon(
Icons.favorite,
color: Colors.red,
size: 40,
),
]),
SizedBox(
height: 500,
child: Card(
elevation: 4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Text(
'Ingredients',
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
Column(
children: [
Text(recipe![index].recipe_ingrdients),
],
),
Center(
child: Text(
'Method',
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
Text(
recipe![index].recipe_prep,
style: TextStyle(
fontSize: 20,
),
)
],
),
),
)
],
),
),
);
// Scaffold(
// appBar: AppBar(
// title: Text(recipe![index].recipe_name),
// ),
// body: Center(
// child: SingleChildScrollView(
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// SelectableText(recipe![index].recipe_cat),
// Text(recipe![index].recipe_prep),
// Text(recipe![index].recipe_id.toString()),
// Text(recipe![index].recipe_ingrdients),
// Text(recipe![index].image_name),
// OutlinedButton(
// onPressed: () {
// Share.share(recipe![index].recipe_prep);
// },
// child: Text('Share'))
// ],
// ),
// ),
// ),
// );
}
}
import 'package:flutter/material.dart';
import 'package:stone_recipe_app/detailedScreen.dart';
import 'package:stone_recipe_app/models/recipe.dart';
import 'package:stone_recipe_app/services/db_services.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final dbservice = DataBaseService();
#override
void dispose() {
dbservice.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Recipe App')),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: FutureBuilder<List<Recipe>>(
future: dbservice.getRecipe(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Center(child: CircularProgressIndicator());
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data?.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailedScreen(
recipe: snapshot.data,
index: index,
)));
},
title: Text(snapshot.data![index].recipe_name, style: TextStyle(color: Colors.black)),
// trailing: Text(
// snapshot.data![index].recipe_cat,
// style: TextStyle(color: Colors.black),
// overflow: TextOverflow.fade,
// ),
);
},
);
},
)),
);
}
}
enter image description herei am trying to show data from sqlite db in flutter when user click on country category like india china after user click user navigate to other page which are recipe name related to chine or related to india i am trying to show data from sqlite db in flutter when user click on country category like india china after user click user navigate to other page which are recipe name related to chine or related to india enter image description here
add group_list_view: ^1.1.1 package in your pubspec.yaml file.
try below the example then implement it in your project
import 'package:flutter/material.dart';
import 'package:group_list_view/group_list_view.dart';
import 'package:group_listview_example/app_colors.dart';
void main() => runApp(MyApp());
Map<String, List> _elements = {
'Team A': ['Klay Lewis', 'Ehsan Woodard', 'River Bains'],
'Team B': ['Toyah Downs', 'Tyla Kane'],
'Team C': ['Marcus Romero', 'Farrah Parkes', 'Fay Lawson', 'Asif Mckay'],
'Team D': [
'Casey Zuniga',
'Ayisha Burn',
'Josie Hayden',
'Kenan Walls',
'Mario Powers'
],
'Team Q': ['Toyah Downs', 'Tyla Kane', 'Toyah Downs'],
};
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Group List View Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Group List View Demo'),
),
body: GroupListView(
sectionsCount: _elements.keys.toList().length,
countOfItemInSection: (int section) {
return _elements.values.toList()[section].length;
},
itemBuilder: _itemBuilder,
groupHeaderBuilder: (BuildContext context, int section) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8),
child: Text(
_elements.keys.toList()[section],
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
);
},
separatorBuilder: (context, index) => SizedBox(height: 10),
sectionSeparatorBuilder: (context, section) => SizedBox(height: 10),
),
),
);
}
Widget _itemBuilder(BuildContext context, IndexPath index) {
String user = _elements.values.toList()[index.section][index.index];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Card(
elevation: 8,
child: ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 18, vertical: 10.0),
leading: CircleAvatar(
child: Text(
_getInitials(user),
style: TextStyle(color: Colors.white, fontSize: 18),
),
backgroundColor: _getAvatarColor(user),
),
title: Text(
_elements.values.toList()[index.section][index.index],
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400),
),
trailing: Icon(Icons.arrow_forward_ios),
),
),
);
}
String _getInitials(String user) {
var buffer = StringBuffer();
var split = user.split(" ");
for (var s in split) buffer.write(s[0]);
return buffer.toString().substring(0, split.length);
}
Color _getAvatarColor(String user) {
return AppColors
.avatarColors[user.hashCode % AppColors.avatarColors.length];
}
}

How to refer to a variable in a Firebase server which belongs to a particular document?

Background: I'm writing an app in which you can store the plus points and fives of a class.
I do this with Flutter and Firebase. My Firestore database collection is called 'mates' and it has several documents, with a unique, auto-ID. Every document has three fields: a name(string), points(number), fives(number).
I have made this far with the help of this tutorial: https://www.youtube.com/watch?v=DqJ_KjFzL9I&t=591s
I want to modify the GUI a bit, in each listtile I display the name, button for decrementing points, the value of points, button for incrementing points, button for decrementing fives, value of fives, button for incrementing fives and a button for setting the value of fives to zero.
My question would be, that how can I refer to the fields(points, fives) of the database when changing their values?
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Widget _buildListItem(BuildContext context, DocumentSnapshot document){
return ListTile(
title: Row(
children: [
Expanded(
child: Text(
document["Name"],
style: Theme.of(context).textTheme.headline,
)
),
Container(
decoration: const BoxDecoration(
color: Color(0xffddddff)
),
padding: const EdgeInsets.all(10.0),
child: Text(
document['Points'].toString(),
style: Theme.of(context).textTheme.display1,
),
),
Container(
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.keyboard_arrow_left),
iconSize: 30,
onPressed: (){
setState(() {
if(points!=0) { //I mean here
points--; //I mean here
}
});
}
),
Text(
"$points", //I mean here
style: TextStyle(
fontSize: 30
),
),
IconButton(
icon: Icon(Icons.keyboard_arrow_right),
iconSize: 30,
onPressed: (){
setState(() {
points++; //I mean here
if(points==10){ //I mean here
points=0; //I mean here
fives++; //I mean here
}
});
}
),
Text(
"$fives", //I mean here
style: TextStyle(
fontSize: 30
),
),
IconButton(
icon: Icon(Icons.check_circle),
iconSize: 30,
onPressed: (){
setState(() {
fives=0; //I mean here
});
}
),
]
)
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Center(
child: Scaffold(
appBar: AppBar(
title: Text("Punkte++"),
centerTitle: true,
),
body: StreamBuilder(
stream: Firestore.instance.collection("mates").snapshots(),
builder: (context, snapshot) {
if(!snapshot.hasData) return const Text("Loading...");
return ListView.builder(
itemExtent: 80.0,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) =>
_buildListItem(context, snapshot.data.documents[index]),
);
}
),
)
);
}
}

Flutter: Building a Cupertino Picker that shows rows containing 2 widgets, from looping through a Map

I've created a picker that displays a Icon and a String, next to each other. The pickers items are taken from a Map I created that contains Key: String and Value: Icon.
In my code right now, I'm using the Cupertino Picker and adding children: [ Row(Icon + String)] but that's quite bad if I want to update them.
I was trying to get a loop going to generate those rows + children but I can't figure out how.
Could someone show me the way or perhaps a more efficient way of getting this result? I'm thinking Extracting row and creating a constructor to input the icon and string, but I'm sure there's a better way...
Here's the code:
Expanded(
child: CupertinoPicker(
itemExtent: 40,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[0],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[0],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[1],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[1],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[2],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[2],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[3],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[3],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[4],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[4],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[5],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[5],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[6],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[6],
style:
TextStyle(color: Colors.white70),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[7],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[7],
style:
TextStyle(color: Colors.white70),
),
)
],
)
],
onSelectedItemChanged: (int index) {
print('good boi');
},
looping: true,
backgroundColor: Color(0xff2e3032),
),
),
How it looks like:
You can copy paste run full code below
You can use control-flow-collections
code snippet
children: <Widget>[
for (var i = 0;
i < BuildingProblem.problemListIcons.length;
i++)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[i],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[i],
style: TextStyle(color: Colors.white70),
),
)
],
),
],
working demo
You need to add file analysis_options.yaml to root of your project and the following line
analyzer:
enable-experiment:
- control-flow-collections
full code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class BuildingProblem {
static List<Icon> problemListIcons = [];
static List<String> problemListNames = [];
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
void initState() {
BuildingProblem.problemListIcons.add(Icon(Icons.add));
BuildingProblem.problemListIcons.add(Icon(Icons.cast));
BuildingProblem.problemListNames.add("add");
BuildingProblem.problemListNames.add("cast");
// TODO: implement initState
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: CupertinoPicker(
itemExtent: 40,
children: <Widget>[
for (var i = 0;
i < BuildingProblem.problemListIcons.length;
i++)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BuildingProblem.problemListIcons[i],
Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
BuildingProblem.problemListNames[i],
style: TextStyle(color: Colors.white70),
),
)
],
),
],
onSelectedItemChanged: (int index) {
print('good boi');
},
looping: true,
backgroundColor: Color(0xff2e3032),
),
),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Card layouts - Flutter

I am trying to build a card using flutter, that looks like the concept shown below, but I am getting this instead.
Here's the card widget code in Dart:
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.symmetric(horizontal: 14.0),
color: Colors.white,
elevation: 6.0,
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onLongPress: () {_copy();},
onTap: () {},
child: Container(
child: Padding(
padding: EdgeInsets.all(12.0),
child: Row(
children: <Widget>[
Text(widget.cardTitle),
Spacer(),
ButtonBar(
children: <Widget>[
new IconButton(
icon: Icon(CardsIcons.arrows_ccw, color: primaryDark,),
onPressed: () {_refresh();},
),
new IconButton(
icon: Icon(CardsIcons.heart_empty, color: Colors.redAccent,),
onPressed: () {_bookmark();},
),
],
),
SizedBox(height: 24.0,),
Text(
widget.cardContent,
),
],
),
),
),
),
),
);
}
This is the output I am getting currently
This is the desired output
Your structure is close but to get the layout you'll need to wrap everything in a Column widget first with children containing your row and then text.
The code below should be a good start, you'll just need to adjust padding/text style etc to get it like your mockup
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.symmetric(horizontal: 14.0),
color: Colors.white,
elevation: 6.0,
child: InkWell(
splashColor: Colors.blue.withAlpha(30),
onLongPress: () {_copy();},
onTap: () {},
child: Container(
child: Padding(
padding: EdgeInsets.all(12.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(widget.cardTitle),
Spacer(),
ButtonBar(
children: <Widget>[
new IconButton(
icon: Icon(CardsIcons.arrows_ccw, color: primaryDark,),
onPressed: () {_refresh();},
),
new IconButton(
icon: Icon(CardsIcons.heart_empty, color: Colors.redAccent,),
onPressed: () {_bookmark();},
),
],
),
SizedBox(height: 24.0,),
],
),
Container(
child: Text(
widget.cardContent,
),
),
],
),
),
),
),
),
);
}

Flutter checkbox unwanted touch space

I tried to create a login screen using flutter, there I added remember me checkbox, but I could not align it correctly,
Flutter checkbox took unwanted space around itself, for the provide good touch user experience.
This is the how my layout show,
Check below code,
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
children: <Widget>[
new Checkbox(
activeColor: Colors.grey,
value: _isChecked,
onChanged: (bool value) {
_onChecked(value);
},
),
new GestureDetector(
onTap: () => print("Remember me"),
child: new Text(
"Remember me",
style: new TextStyle(color: Colors.white70),
),
)
],
),
new Text(
"Forgot password ?",
style: new TextStyle(color: Colors.white70),
)
],
),
Use SizedBox
The widget is basically made for resizing its child.
SizedBox(
width: 15,
height: 15,
child: Checkbox(value: false, onChanged: null)
)
EDIT
Short Answer
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
...
)
..................
Long Answer
You can achieve this by customising the Checkbox widget.
Create a CustomCheckbox using the exact code from
flutter/packages/flutter/lib/src/material/checkbox.dart.
Add a new field to your CustomCheckbox widget
final bool useTapTarget;
Make sure to add the new field to your constructor with it default
value set to true.
this.useTapTarget = true
Modify the build method in the _CheckboxState method. Add this
block of code above the return call.
Size noTapTargetSize = Size(CustomCheckbox.width,
CustomCheckbox.width);
final BoxConstraints additionalConstraints =
BoxConstraints.tight(widget
.useTapTarget? size : noTapTargetSize);
Finally, use your CustomCheckbox widget in your code, and set your
custom field to false to remove material padding. example
Container(
margin: EdgeInsets.only(right: 15),
child:CustomCheckbox(
value: _checked,
materialTapTargetSize: null,
onChanged: _onCheckBoxChange,
useTapTarget: false,
activeColor: Colors.teal),
)
Try this then,
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'NonStopIO',
theme: new ThemeData(
primarySwatch: Colors.red,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _rememberMeFlag = false;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('NonStopIO'),
),
body: new Container(
color: Colors.black38,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
margin: new EdgeInsets.symmetric(vertical: 5.0, horizontal: 35.0),
color: Colors.white70,
height: 50.0,
),
new Container(
margin: new EdgeInsets.symmetric(vertical: 5.0, horizontal: 35.0),
color: Colors.white70,
height: 50.0,
),
new Container(
margin: new EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
children: <Widget>[
new GestureDetector(
child: new Row(
children: <Widget>[
new Checkbox(
value: _rememberMeFlag,
onChanged: (value) => setState(() {
_rememberMeFlag = !_rememberMeFlag;
}),
),
new Text(
"Remember me",
style: new TextStyle(color: Colors.white70),
)
],
),
onTap: () => setState(() {
_rememberMeFlag = !_rememberMeFlag;
}),
),
],
),
new Container(
margin: new EdgeInsets.only(right: 15.0),
child: new Text(
"Forgot password ?",
style: new TextStyle(color: Colors.white70),
),
)
],
)),
new Container(
margin: new EdgeInsets.symmetric(vertical: 5.0, horizontal: 35.0),
color: Colors.orange,
height: 50.0,
),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Here, I have adjusted the margin to align the Checkbox and Forgot password Text.

Resources