Here is my issue: The button should Not overlap the textfield.
Notice that I added a SingleChildScrollView(). The user can still scroll up and achieve the desired the result but I want to make it automatic:
Here is my code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_masked_text/flutter_masked_text.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:talking_dodo/dodo/pages/payment/credit_card.dart';
class WithdrawPage extends StatefulWidget {
#override
WithdrawPageState createState() {
return new WithdrawPageState();
}
}
class WithdrawPageState extends State<WithdrawPage> {
bool isDataAvailable = true;
int _radioValue = 0;
MaskedTextController ccMask =
MaskedTextController(mask: "0000 0000 0000 0000");
Widget _buildBody() {
return Stack(
children: <Widget>[
SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(
left: 16.0, right: 16.0, top: 16.0, bottom: 16.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 18.0),
child: Text('Please select withdrawal method below'),
),
],
),
Container(
margin: EdgeInsets.only(top: 12.0),
child: Row(
children: <Widget>[
new Radio(
value: 0,
groupValue: _radioValue,
onChanged: ((value) {
setState(() {
_radioValue = value;
});
}),
),
Text(
'ATM Withdrawal',
),
],
),
),
Container(
height: 220.0,
padding: EdgeInsets.only(left: 20.0, right: 10.0),
margin: const EdgeInsets.all(2.0),
decoration: BoxDecoration(
// color: Colors.white,
border: Border.all(color: Colors.black),
borderRadius: BorderRadius.all(Radius.circular(12.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Bullet('Visit mcb Branch'),
Bullet('Select "Dodo Wallet" in the options'),
Bullet('Select the amount to withdraw'),
Bullet('Input your dodo wallet pin'),
Bullet(
'Input the code in the input box below and click withdraw'),
Padding(
padding: const EdgeInsets.only(top:18.0),
child: TextField(
controller: ccMask,
keyboardType: TextInputType.number,
maxLength: 19,
style:
TextStyle(fontFamily: 'Raleway', color: Colors.black),
decoration: InputDecoration(
labelText: "Code",
labelStyle: TextStyle(fontWeight: FontWeight.bold),
border: OutlineInputBorder()),
),
),
],
),
),
Row(
children: <Widget>[
new Radio(
value: 1,
groupValue: _radioValue,
onChanged: ((value) {
setState(() {
_radioValue = value;
});
}),
),
Text(
'Transfer to card',
),
],
),
],
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: isDataAvailable
? Expanded(
child: ButtonTheme(
height: 65.0,
child: RaisedButton(
color: Theme.of(context).primaryColorLight,
child: Text('Withdraw funds'),
onPressed: () => showSuccessDialog()),
),
)
: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: CircularProgressIndicator()),
),
],
),
),
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Withdrawal"),
),
body: _buildBody(),
);
}
void showSuccessDialog() {
setState(() {
isDataAvailable = false;
Future.delayed(Duration(seconds: 1)).then((_) => goToDialog());
});
}
goToDialog() {
setState(() {
isDataAvailable = true;
});
showDialog(
context: context,
barrierDismissible: true,
builder: (context) => Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
successTicket(),
SizedBox(
height: 10.0,
),
FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(
Icons.clear,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed('/chat');
},
)
],
),
),
));
}
successTicket() => Container(
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: Material(
clipBehavior: Clip.antiAlias,
elevation: 2.0,
borderRadius: BorderRadius.circular(4.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
ProfileTile(
title: "Thank You!",
textColor: Colors.purple,
subtitle: "Your transaction was successful",
),
ListTile(
title: Text("Date"),
subtitle: Text("26 June 2018"),
trailing: Text("11:00 AM"),
),
ListTile(
title: Text("Daniel Daniel"),
subtitle: Text("gmail#daniel.com"),
trailing: CircleAvatar(
radius: 20.0,
backgroundImage: NetworkImage(
"https://avatars0.githubusercontent.com/u/12619420?s=460&v=4"),
),
),
ListTile(
title: Text("Amount"),
subtitle: Text("\$423.00"),
trailing: Text("Completed"),
),
Card(
clipBehavior: Clip.antiAlias,
elevation: 0.0,
color: Colors.grey.shade300,
child: ListTile(
leading: Icon(
FontAwesomeIcons.ccAmex,
color: Colors.blue,
),
title: Text("Credit/Debit Card"),
subtitle: Text("Amex Card ending ***6"),
),
),
],
),
),
),
);
}
class Bullet extends Text {
const Bullet(
String data, {
Key key,
TextStyle style,
TextAlign textAlign,
TextDirection textDirection,
Locale locale,
bool softWrap,
TextOverflow overflow,
double textScaleFactor,
int maxLines,
String semanticsLabel,
}) : super(
'• $data',
key: key,
style: style,
textAlign: textAlign,
textDirection: textDirection,
locale: locale,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
semanticsLabel: semanticsLabel,
);
}
What you're looking for is the scrollPadding parameter of textfield. Flutter automatically scrolls the view to the top of the keyboard when the textfield is focused, but it has no idea about the fact that you've placed a button that sits at the bottom of the screen.
With your current code, you could simply replace scrollPadding with padding that has a larger bottom (i.e. the size of the yellow button) and flutter should do the rest for you.
Related
Hello i was just trying to include a switch button on the right side of a list item. While doing so i ended up with this BoxConstraints forces an infinite width error. As im a complete beginner to flutter Can someone please let me know what does it means? and what changes i have to do in my code to get rid of this error?
import 'package:attendee/constants.dart';
import 'package:flutter/material.dart';
import 'package:attendee/models/userdeails.dart';
class userdetailsTile extends StatelessWidget {
final userdetails userdetail;
userdetailsTile({this.userdetail});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Card(
//margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
child: GestureDetector(
child: ListTile(
leading: CircleAvatar(
radius: 25.0,
backgroundColor: Colors.lightGreen,
),
title: Text(userdetail.fullname),
),
),
),
Switch(
value: present,
onChanged: (value) {
//setState(() {
present = value;
print(present);
//});
},
activeTrackColor: Colors.lightGreenAccent,
activeColor: Colors.green,
),
//),
],
),
);
}
}
Please check the following solutions.
Solution 1
return Material(child: Padding(
padding: EdgeInsets.only(top: 8.0),
child: ListTile(
leading: CircleAvatar(
radius: 25.0,
backgroundColor: Colors.lightGreen,
),
title: Text(userdetail.fullname),
trailing: Switch(
value: present,
onChanged: (value) {
//setState(() {
present = value;
print(present);
//});
},
activeTrackColor: Colors.lightGreenAccent,
activeColor: Colors.green,
),
),
),
);
Solution 2
return Material(child:
Padding(
padding: EdgeInsets.only(top: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Card(
//margin: EdgeInsets.fromLTRB(20.0, 6.0, 20.0, 0.0),
child: Row(
children: [
CircleAvatar(
radius: 25.0,
backgroundColor: Colors.lightGreen,
), Text(userdetail.fullname)
],
),
),
),
Switch(
value: present,
onChanged: (value) {
//setState(() {
present = value;
print(present);
//});
},
activeTrackColor: Colors.lightGreenAccent,
activeColor: Colors.green,
),
//),
],
),
),
);
i'm stuck on this problem for long time
in debug console
i don't know how to fix it please help
it says flexible while i did not use flexible widget.
i only used expanded and even when i remove expanded widget still have the same error
also i tried to remove everything except the list view builder widget i sill get the same error
this is the code:
import 'package:flutter/material.dart';
import 'package:todoy/Colors.dart';
import 'Taskslistview.dart';
import 'TasksListTile.dart';
import 'package:provider/provider.dart';
import 'Helper.dart';
bool isChekec = false;
class TasksScreen extends StatelessWidget {
Widget buildsheet(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white,
),
height: 400,
child: Padding(
padding: EdgeInsets.only(left: 50.0, right: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(
height: 10,
),
Center(
child: Text(
'Add Task',
style: TextStyle(
fontSize: 30,
color: Provider.of<Helper>(context).choosedcolor),
)),
TextField(
decoration: InputDecoration(
helperStyle: TextStyle(color: Colors.red),
helperText: Provider.of<Helper>(context).alreadyexist
? "this task already exist"
: " "),
textAlign: TextAlign.center,
onChanged: (value) {
if (Provider.of<Helper>(context, listen: false)
.tasknames
.contains(value)) {
Provider.of<Helper>(context, listen: false)
.alreadyture();
} else {
Provider.of<Helper>(context, listen: false)
.alreadyfalse();
}
Provider.of<Helper>(context, listen: false)
.addtaskname(value);
Provider.of<Helper>(context, listen: false)
.addtaskname(value);
print(Provider.of<Helper>(context, listen: false)
.addedtask);
},
),
SizedBox(
height: 10,
),
Container(
height: 50,
// ignore: deprecated_member_use
child: FlatButton(
color: Provider.of<Helper>(context).choosedcolor,
onPressed: () {
if (Provider.of<Helper>(context, listen: false)
.alreadyexist) {
print("you cant");
} else if (Provider.of<Helper>(context, listen: false)
.addedtask ==
"") {
print("ffgg");
} else {
Provider.of<Helper>(context, listen: false).addname(
Provider.of<Helper>(context, listen: false)
.addedtask);
Provider.of<Helper>(context, listen: false)
.add(TasksListTile(
isChcked: isChekec,
nameofthetask:
Provider.of<Helper>(context, listen: false)
.addedtask,
));
Provider.of<Helper>(context, listen: false)
.addedtask = "";
Navigator.pop(context);
}
},
child: Text(
"ADD",
style: TextStyle(color: Colors.white, fontSize: 20),
)),
)
],
),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Provider.of<Helper>(context).choosedcolor,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.only(left: 300.0, top: 30, right: 15),
child: GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => ColorsScreen()));
},
child: CircleAvatar(
radius: 35,
backgroundColor: Colors.white,
child: Icon(
Icons.invert_colors,
size: 40,
color: Provider.of<Helper>(context).choosedcolor,
)),
),
),
Padding(
padding: EdgeInsets.only(left: 40.0, top: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
radius: 35,
backgroundColor: Colors.white,
child: Icon(
Icons.list,
size: 40,
color: Provider.of<Helper>(context).choosedcolor,
)),
Padding(
padding: const EdgeInsets.only(right: 30.0),
child: Container(
height: 67,
child: FittedBox(
child: FloatingActionButton(
child: Icon(Icons.delete_forever,
size: 40,
color: Provider.of<Helper>(context)
.choosedcolor),
backgroundColor: Colors.white,
onPressed: () {
Provider.of<Helper>(context, listen: false)
.remove();
},
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 8.0, left: 10, bottom: 10),
child: Text(
"Todoy",
style: TextStyle(color: Colors.white, fontSize: 40),
textAlign: TextAlign.start,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
' ${Provider.of<Helper>(context).tasks.length} Tasks',
style: TextStyle(color: Colors.white, fontSize: 40),
textAlign: TextAlign.start,
),
Padding(
padding: const EdgeInsets.only(right: 30.0),
child: Container(
height: 70,
child: FittedBox(
child: FloatingActionButton(
child: Text(
"+",
style: TextStyle(
fontSize: 50,
color: Provider.of<Helper>(context)
.choosedcolor),
),
backgroundColor: Colors.white,
onPressed: () {
showModalBottomSheet(
context: context, builder: buildsheet);
},
),
),
),
),
],
),
],
),
),
SizedBox(
height: 20,
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40),
topRight: Radius.circular(40))),
child: Taskslistview(),
),
),
],
),
),
);
}
}
inside Tasklistview:
class Taskslistview extends StatelessWidget {
#override
Widget build(BuildContext context) {
bool isChecked = false;
return ListView.builder(
itemCount: Provider.of<Helper>(context).tasks.length,
itemBuilder: (context, index) {
return TasksListTile(
isChcked: isChecked,
nameofthetask:
Provider.of<Helper>(context, listen: false).tasknames[index],
);
},
);
}
}
please help i tried everything to fix it nothing worked
I have a form builder application, I have stateless widgets which get added to list view, each widget has a delete icon, I want to delete the widget and update the list view.
one of the code widget code is this
class HeaderTextWidget extends StatelessWidget {
final VoidCallback onDelete;
HeaderTextWidget({Key key, this.onDelete}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 12.0),
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.only(
topRight: Radius.circular(15.0),
topLeft: Radius.circular(15.0),
),
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(6.0),
child: Text(
'Header',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
),
),
),
Card(
elevation: 5.0,
color: Colors.blueGrey.shade50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0),
topRight: Radius.circular(15.0),
),
),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 10.0, 8.0, 10.0),
child: TextField(
textCapitalization: TextCapitalization.words,
keyboardType: TextInputType.text,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
decoration: InputDecoration(
hintText: 'untitled header',
hintStyle: TextStyle(
color: Colors.grey,
fontStyle: FontStyle.italic,
fontSize: 14.0,
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 20.0),
child: TextField(
textCapitalization: TextCapitalization.words,
keyboardType: TextInputType.text,
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.normal,
),
decoration: InputDecoration(
hintText: 'Description (optional)',
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 14.0,
),
),
),
),
Divider(
indent: 4.0,
endIndent: 4.0,
thickness: 2.0,
),
IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(Icons.content_copy),
iconSize: 24.0,
color: Colors.blue,
onPressed: () {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('COpy'),
),
);
},
),
IconButton(
icon: Icon(Icons.delete),
iconSize: 24.0,
color: Colors.red,
onPressed: this.onDelete,
),
VerticalDivider(
thickness: 2.0,
endIndent: 6.0,
indent: 4.0,
),
Padding(
padding: const EdgeInsets.only(right: 12.0),
child: SwitchWidget(),
),
],
),
),
],
),
),
],
),
);
}
}
This is my Listview builder
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FormBuilder(
key: widget.fbKey,
autovalidate: true,
child: Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView.builder(
itemCount: widget.data.widgets.length,
controller: _scrollController,
itemBuilder: (context, index) {
return widget.data.widgets[index];
},
),
),
)),
],
),
);
This is how the widget is being added the view is getting changed from selected the widget to List view builder page, when clicked on that particular icon. Where should be the delete function be added, in the List view or in the widget itself ?
Scaffold(
appBar: AppBar(
title: Text('Form Widgets'),
),
body: LayoutBuilder(
builder:
(BuildContext context, BoxConstraints viewPointConstrainsts) {
return SingleChildScrollView(
padding: EdgeInsets.all(12.0),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewPointConstrainsts.maxHeight,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FormWidget(
key: UniqueKey(),
iconData: Icons.title,
widgetTxT: 'Header',
onTap: () {
setState(() {
widget.data.widgets.add(HeaderTextWidget());
widget.pickWidgetsView = false;
});
},
),
Try the following approach:
Store only the data, not the Widget itself in the list
List<DataModel> data = []
Create list view item using createListViewItem() which should return widget as the following
ListView.builder(
itemCount: widget.dataList.length,
controller: _scrollController,
itemBuilder: (context, index) {
return createListViewItem(index);
},
),
Now inside createListViewItem(index) you can create data as per widget.dataList[index] and delete the list item on click of delete icon
setState(){
widget.dataList.deleteAt(index);
}
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton(
items: _Mothe.map(
(String dropdownMenuItem) {
return DropdownMenuItem<String>(
value: dropdownMenuItem,
child: Text(dropdownMenuItem),
);
},
).toList(),
onChanged: (String? value) {
setState(
() {
name == value!;
},
);
},
value: name,
isExpanded: true,
icon: SizedBox(),
),
],
),
);
}
I am beginner in flutter and following some tutorials. I need to know how can I show data in a function by looping? For now, I am calling function 2 or 3 times to show data on how its possible ill call function just one time and shop my data which is in array?
Here. my data file which name is post_model.dart
class Post {
String authorName;
String authorImageUrl;
String timeAgo;
String imageUrl;
Post({
this.authorName,
this.authorImageUrl,
this.timeAgo,
this.imageUrl,
});
}
final List<Post> posts = [
Post(
authorName: 'Umaiz Khan',
authorImageUrl: 'assets/images/user0.png',
timeAgo: '5 min',
imageUrl: 'assets/images/post0.jpg',
),
Post(
authorName: 'Saad ahmed',
authorImageUrl: 'assets/images/user1.png',
timeAgo: '10 min',
imageUrl: 'assets/images/post1.jpg',
),
Post(
authorName: 'Hiba',
authorImageUrl: 'assets/images/user4.png',
timeAgo: '10 min',
imageUrl: 'assets/images/post2.jpg',
),
];
final List<String> stories = [
'assets/images/user1.png',
'assets/images/user2.png',
'assets/images/user3.png',
'assets/images/user4.png',
'assets/images/user0.png',
'assets/images/user1.png',
'assets/images/user2.png',
'assets/images/user3.png',
];
Here is my code at the end of the line you can see I am calling function and sending index. I need to call the function just one time and it will show all my arrays in data. Thanks in advance
import 'package:flutter/material.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'package:mytravel/screens/loginPage.dart';
import 'package:mytravel/screens/guidePlacePage.dart';
import 'package:mytravel/models/post_model.dart';
import 'package:mytravel/screens/view_post_screen.dart';
class newsFeedPage extends StatefulWidget {
#override
_newsFeedPageState createState() => _newsFeedPageState();
}
class _newsFeedPageState extends State<newsFeedPage> {
List<Widget> _buildPost() {
List<Widget> items = [];
items.add(
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
child: Container(
width: double.infinity,
height: 560.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25.0),
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Column(
children: <Widget>[
ListTile(
leading: Container(
width: 50.0,
height: 50.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black45,
offset: Offset(0, 2),
blurRadius: 6.0,
),
],
),
child: CircleAvatar(
child: ClipOval(
child: Image(
height: 50.0,
width: 50.0,
image: AssetImage(posts[].authorImageUrl),
fit: BoxFit.cover,
),
),
),
),
title: Text(
posts[].authorName,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(posts[].timeAgo),
trailing: IconButton(
icon: Icon(Icons.more_horiz),
color: Colors.black,
onPressed: () => print('More'),
),
),
InkWell(
onDoubleTap: () => print('Like post'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ViewPostScreen(
post: posts[],
),
),
);
},
child: Container(
margin: EdgeInsets.all(10.0),
width: double.infinity,
height: 400.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
BoxShadow(
color: Colors.black45,
offset: Offset(0, 5),
blurRadius: 8.0,
),
],
image: DecorationImage(
image: AssetImage(posts[].imageUrl),
fit: BoxFit.fitWidth,
),
),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.favorite_border),
iconSize: 30.0,
onPressed: () => print('Like post'),
),
Text(
'2,515',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
),
),
],
),
SizedBox(width: 20.0),
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.chat),
iconSize: 30.0,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ViewPostScreen(
post: posts[],
),
),
);
},
),
Text(
'350',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
),
),
],
),
],
),
IconButton(
icon: Icon(Icons.bookmark_border),
iconSize: 30.0,
onPressed: () => print('Save post'),
),
],
),
),
],
),
),
],
),
),
),
);
for (var i = 0; i < posts.length; i++) {
items.add(_buildPost(i));
}
return items;
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFEDF0F6),
body: ListView(
physics: AlwaysScrollableScrollPhysics(),
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Social Travel',
style: TextStyle(
fontFamily: 'Billabong',
fontSize: 32.0,
),
),
],
),
),
ListView(
physics: AlwaysScrollableScrollPhysics(),
children: _buildPost(),
),
],
),
);
}
}
You can build the children array of your ListView in a new method like this :
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFEDF0F6),
body: ListView(
physics: AlwaysScrollableScrollPhysics(),
children: _buildListViewItems(),
),
);
}
List<Widget> _buildListViewItems() {
List<Widget> items = [];
items.add(
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'Instagram',
style: TextStyle(
fontFamily: 'Billabong',
fontSize: 32.0,
),
),
],
),
),
);
for (var i = 0; i < posts.length; i++) {
items.add(_buildPost(i));
}
return items;
}
I am a beginner of flutter.
I am developing a flutter app.
this is my flutter app screen.
I want to hide the marked part as blue when I tap the bookmark tab bar.
I have tried several methods, but I could not achieve my goal.
I really need your helps.
I attached my whole code.
import 'package:botanic_flutter/login_page.dart';
import 'package:botanic_flutter/main.dart';
import 'package:botanic_flutter/root_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:botanic_flutter/custom_color_scheme.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AccountPage extends StatefulWidget {
final String userUid;
AccountPage(this.userUid);
#override
_AccountPageState createState() => _AccountPageState();
}
class _AccountPageState extends State<AccountPage>
with SingleTickerProviderStateMixin {
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _Auth = FirebaseAuth.instance;
FirebaseUser _currentUser;
TabController _controller;
ScrollController _scrollController;
#override
void initState() {
super.initState();
_scrollController = ScrollController();
_controller = TabController(length: 2, vsync: this);
}
#override
void dispose() {
_controller.dispose();
_scrollController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
bottom: true,
child: DefaultTabController(
length: 2,
child: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (context, isScrolled) {
return <Widget>[
SliverList(
delegate: SliverChildListDelegate([
_detailedBody()
]),
),
SliverPersistentHeader(
pinned: true,
delegate: TabBarDelegate(
Column(
children: <Widget>[
TabBar(
unselectedLabelColor: Theme.of(context).colorScheme.greyColor,
labelColor: Theme.of(context).colorScheme.mainColor,
controller: _controller,
indicatorColor: Theme.of(context).colorScheme.mainColor,
tabs: [
Container(
height: 80,
padding: EdgeInsets.only(top: 10),
child: Tab(
icon: const Icon(Icons.home,
),
text: 'PLANTS',
),
),
Container(
height: 80,
padding: EdgeInsets.only(top: 10),
child: Tab(
icon: const Icon(Icons.bookmark_border,
),
text: 'BOOKMARK',
),
)
],
),
_bottomButtons(tabindi)
],
),
),
),
];
},
body: SizedBox(
height: MediaQuery.of(context).size.height,
child: TabBarView(
controller: _controller,
children: <Widget>[
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
itemCount: notes.length,
itemBuilder: (context, index) => Card(
child: Image.network(notes[index],
fit: BoxFit.cover,
),
),
),
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
mainAxisSpacing: 1.0,
crossAxisSpacing: 1.0),
itemCount: notes.length,
itemBuilder: (context, index) => Card(
child: Image.network(notes[index],
fit: BoxFit.cover,
),
),
)
],
),
),
),
),
),
);
}
Widget _detailedBody() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width * 3 / 4,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'http://www.korea.kr/newsWeb/resources/attaches/2017.08/03/3737_cp.jpg'),
),
),
),
Container(
transform: Matrix4.translationValues(0.0, -41.0, 0.0),
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: 90.0,
height: 90.0,
child: CircleAvatar(
backgroundColor: Colors.white,
),
),
SizedBox(
width: 82.0,
height: 82.0,
child: CircleAvatar(
backgroundImage: NetworkImage(
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG')),
),
Container(
width: 90.0,
height: 90.0,
alignment: Alignment.bottomRight,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
width: 28.0,
height: 28.0,
child: FloatingActionButton(
onPressed: null,
backgroundColor: Colors.white,
//child: Icon(Icons.add),
),
),
SizedBox(
width: 25.0,
height: 25.0,
child: FloatingActionButton(
onPressed: null,
backgroundColor:
Theme.of(context).colorScheme.mainColor,
child: Icon(Icons.add),
),
),
],
))
],
),
Padding(padding: EdgeInsets.all(5.0)),
Text(
'nickname',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24.0),
),
Padding(padding: EdgeInsets.all(5.0)),
Text(
'introduce',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
),
Padding(padding: EdgeInsets.all(9.0)),
FlatButton(
onPressed: () {
signOutWithGoogle().then((_) {
Navigator.popUntil(context, ModalRoute.withName('/'));
});
},
color: Theme.of(context).colorScheme.mainColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
child: Text('로그아웃'),
),
Padding(padding: EdgeInsets.all(9.0)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'식물수',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'팔로워',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
),
Column(
children: <Widget>[
Text(
'0',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16.0),
),
Text(
'팔로잉',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
],
)
],
)
],
),
),
],
);
}
var tabindi = 0;
Widget _bottomButtons(tabindi) {
print(tabindi);
return tabindi == 0
? Container(
child: Row(
children: <Widget>[
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
child: Icon(
Icons.clear_all,
color: Colors.grey,
),
),
Container(
width: MediaQuery.of(context).size.width/3*1.4,
child: DropdownButton<String>(
isExpanded: true,
items: <String>['Foo', 'Bar'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (_) {},
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: Icon(
Icons.mode_edit,
color: Colors.grey,
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 1.0),
child: Icon(
Icons.delete,
color: Colors.grey,
),
),
Padding(
padding: EdgeInsets.all(4.0),
),
Container(
height: 30,
width: MediaQuery.of(context).size.width/4.5,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.mainColor,
borderRadius: BorderRadius.all(Radius.circular(20)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
),
child: FlatButton(
child: Text(
"+식물등록",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.white,
),
),
onPressed: () => {
},
),
),
],
),
)
:
Container();
}
List<String> notes = [
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
'https://steemitimages.com/DQmS1gGYmG3vL6PKh46A2r6MHxieVETW7kQ9QLo7tdV5FV2/IMG_1426.JPG',
'https://lh3.googleusercontent.com/proxy/BKvyuWq6b5apNOqvSw3VxB-QhezYHAoX1AptJdWPl-Ktq-Efm2gotbeXFtFlkr_ZPZmpEHc2BsKTC9oFQgzBimKsf5oRtTqOGdlO3MTfwiOT54E5m-lCtt6ANOMzmhNsYMGRp9Pg1NzjwMRUWNoWX0oJEFcnFvjOj2Rr4LtZpkXyiQFO',
'https://img1.daumcdn.net/thumb/R720x0.q80/?scode=mtistory2&fname=http%3A%2F%2Fcfile28.uf.tistory.com%2Fimage%2F2343174F58DBC14C2ECB8B',
];
Future<void> signOutWithGoogle() async {
// Sign out with firebase
await _Auth.signOut();
// Sign out with google
await _googleSignIn.signOut();
}
}
class TabBarDelegate extends SliverPersistentHeaderDelegate {
TabBarDelegate(this._tabBar);
final Column _tabBar;
#override
double get minExtent => 130.0;
#override
double get maxExtent => 130.0;
#override
Widget build(BuildContext context, double shrinkOffset,
bool overlapsContent) {
return Container(
color: Color(0xFFFAFAFA),
height: 130.0,
child: _tabBar
);
}
#override
bool shouldRebuild(covariant TabBarDelegate oldDelegate) {
return false;
}
}
I am looking forward your answers.
Thank you!
Use Offstage widget
Offstage(
offstage: _controller.index == 1,
child: _bottomButtons(tabindi)
),
Update when tap TabBar
TabBar(onTap: (_) => setState((){}));