Hi so I'm trying to show alertDialog when you press the close icon on the card but if I tap the "Close" button, it didn't show the alertDialog for delete confirmation, on the other hand when I tap the "check" Icon on, it successfully show a snackbar.
here's my code for the page:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'Schedule.dart';
class HomeView extends StatefulWidget {
HomeViewState createState() => HomeViewState();
}
class HomeViewState extends State<HomeView> {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final Icon actionIcon = Icon(Icons.plus_one);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnscheduledField()),
);
},
)
],
),
body: Container(
child: ListView.builder(
itemCount: scheduleList.length,
itemBuilder: (context, int index) => buildCard(context, index)),
));
}
}
Widget buildCard(BuildContext context, int index) {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final schedule = scheduleList[index];
return Container(
child: GestureDetector(
onTap: () {
showBottomSheet(
context: context,
builder: (context) => Container(
height: 550,
color: Colors.lightBlue,
));
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 4),
child: Row(
children: <Widget>[
Text(schedule.companyName,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4, bottom: 4),
child: Row(
children: <Widget>[Text(schedule.location)],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(
children: <Widget>[
Text('check in at:'),
Text(
"${DateFormat('HH:mm').format(schedule.startTime).toString()}"),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(children: <Widget>[
Text('check out at:'),
Text(
"${DateFormat('HH:mm').format(schedule.endTime).toString()}"),
]),
),
Row(
children: <Widget>[
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
alert(context);
},
icon: Icon(
Icons.close,
),
color: Colors.red,
),
),
),
),
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
final snackbar = SnackBar(
content: Text('Successfully added'),
duration: Duration(seconds: 2),
);
Scaffold.of(context).showSnackBar(snackbar);
},
icon: Icon(
Icons.check,
),
color: Colors.lightGreen[300],
),
),
),
),
],
),
]))),
));
}
void alert(BuildContext context) {
var alertDialog = AlertDialog(
title: Text("Confirmation"),
content: Text("Are you sure you want to delete this?"),
actions: <Widget>[
FlatButton(
child: Text("No"),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: Text("Yes"),
onPressed: () {
Navigator.of(context).pop();
})
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
Any help would be appreciated! thanks
your code is perfect but you have to define alert dialog before you call it,
So define Alert Dialog before you call it in OnPress method of button and Pass it to alert method
class HomeView extends StatefulWidget {
HomeViewState createState() => HomeViewState();
}
class HomeViewState extends State<HomeView> {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final Icon actionIcon = Icon(Icons.plus_one);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Dashboard"),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => UnscheduledField()),
);
},
)
],
),
body: buildCard(context, 0),
body: Container(
child: ListView.builder(
itemCount: scheduleList.length,
itemBuilder: (context, int index) => buildCard(context, index)),
)
);
}
}
Widget buildCard(BuildContext context, int index) {
final List<Schedule> scheduleList = [
Schedule("Hotel 1", DateTime.now(), DateTime.now(), "Germany"),
Schedule("Hotel 2", DateTime.now(), DateTime.now(), "France")
];
final schedule = scheduleList[index];
return Container(
child: GestureDetector(
onTap: () {
showBottomSheet(
context: context,
builder: (context) => Container(
height: 550,
color: Colors.lightBlue,
));
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, bottom: 4),
child: Row(
children: <Widget>[
Text(schedule.companyName,
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold)),
Spacer(),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4, bottom: 4),
child: Row(
children: <Widget>[Text(schedule.location)],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(
children: <Widget>[
Text('check in at:'),
Text(
"${DateFormat('HH:mm').format(schedule.startTime).toString()}"),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4),
child: Row(children: <Widget>[
Text('check out at:'),
Text(
"${DateFormat('HH:mm').format(schedule.endTime).toString()}"),
]),
),
Row(
children: <Widget>[
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
var alertDialog = AlertDialog(
title: Text("Confirmation"),
content:
Text("Are you sure you want to delete this?"),
actions: <Widget>[
FlatButton(
child: Text("No"),
onPressed: () {
Navigator.of(context).pop();
}),
FlatButton(
child: Text("Yes"),
onPressed: () {
Navigator.of(context).pop();
})
],
);
alert(context, alertDialog);
},
icon: Icon(
Icons.close,
),
color: Colors.red,
),
title: Text("hello"),
),
),
),
Expanded(
child: SizedBox(
height: 40,
child: ListTile(
trailing: IconButton(
onPressed: () {
final snackbar = SnackBar(
content: Text('Successfully added'),
duration: Duration(seconds: 2),
);
Scaffold.of(context).showSnackBar(snackbar);
},
icon: Icon(
Icons.check,
),
color: Colors.lightGreen[300],
),
),
),
),
],
),
]))),
));
}
void alert(BuildContext context, AlertDialog alertDialog) {
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
Related
I have Created a list and an Add Button When user clicks on ADD button a widget is Created and Added to the Widget List.
Image of Output which has list of Predefined widgets on the left and an instance of that widget is created and shown on the right side when user clicks on Add Button : -
Now I want to edit the properties of those widgets on the right .For example making the text Bold or Add value to textfield or changing the Text on the Button or defining what happens on onPressed event dynamically
Here is the code for Both the classes
PredfinedFileds.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class PreDefinedFields{
static Text textCustom= Text("New Text");
static TextFormField textFieldCustom= TextFormField(
);
static ElevatedButton elevatedButtonCustom= ElevatedButton(onPressed: (){}, child: Text("New Button"));
}
CustomizableForm.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'PreDefinedFields.dart';
class CustomizableForm extends StatefulWidget {
const CustomizableForm({Key? key}) : super(key: key);
#override
State<CustomizableForm> createState() => _CustomizableFormState();
}
class _CustomizableFormState extends State<CustomizableForm> {
static bool isBold=false;
List fieldList=[];
List widgetList=[];
var text;
#override
Widget build(BuildContext context) {
void ShowDilogText(isBold){
showGeneralDialog(
context: context,
barrierLabel: "Barrier",
barrierDismissible: true,
barrierColor: Colors.black.withOpacity(0.5),
transitionDuration: Duration(milliseconds: 700),
pageBuilder: (_, __, ___) {
return Center(
child: Container(
height: 440,
width: MediaQuery.of(context).size.width/2,
child: SizedBox(child: Container(
child: Center(child: ElevatedButton(
onPressed: (){
isBold != isBold;
},
child: Text("Bold"),
),),
)),
margin: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(40)),
),
);
},
transitionBuilder: (_, anim, __, child) {
Tween<Offset> tween;
if (anim.status == AnimationStatus.reverse) {
tween = Tween(begin: Offset(-1, 0), end: Offset.zero);
} else {
tween = Tween(begin: Offset(1, 0), end: Offset.zero);
}
return SlideTransition(
position: tween.animate(anim),
child: FadeTransition(
opacity: anim,
child: child,
),
);
},
);
}
TextEditingController dateController= TextEditingController();
TextField datePickerField=TextField(
controller: dateController, //editing controller of this TextField
decoration: const InputDecoration(
icon: Icon(Icons.calendar_today), //icon of text field
labelText: "Enter Date" //label text of field
),
readOnly: true, // when true user cannot edit text
onTap: () async {
//when click we have to show the datepicker
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(), //get today's date
firstDate:DateTime(2000), //DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2101)
);
if(pickedDate != null ){
print(pickedDate); //get the picked date in the format => 2022-07-04 00:00:00.000
String formattedDate = DateFormat('yyyy-MM-dd').format(pickedDate); // format date in required form here we use yyyy-MM-dd that means time is removed
print(formattedDate); //formatted date output using intl package => 2022-07-04
//You can format date as per your need
setState(() {
dateController.text = formattedDate; //set foratted date to TextField value.
});
}else{
print("Date is not selected");
}
}
);
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Row(
children: [
//For Predefined Fields
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: MediaQuery.of(context).size.width/3,
child: Column(
children: [
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Text"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('Text');
widgetList.add(PreDefinedFields.textCustom);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Text Field"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('TextField');
widgetList.add(PreDefinedFields.textFieldCustom);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Button"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('Button');
widgetList.add(PreDefinedFields.elevatedButtonCustom);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
ListTile(
leading: const Icon(Icons.text_fields),
title: const Text("Date"),
trailing: ElevatedButton(onPressed: (){
fieldList.add('Date Picker');
widgetList.add(datePickerField);
setState(() {
print(fieldList);
});
}, child: Text("+ Add")),
),
],
),
),
),
//For Form
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
height: MediaQuery.of(context).size.height-50,
width: MediaQuery.of(context).size.width/2,
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent)
),
child: Form(
child: ListView.builder(
shrinkWrap: true,
itemCount: fieldList.length,
itemBuilder: (context,index){
if(fieldList[index]=='Text'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
PreDefinedFields.textCustom,
Spacer(),
IconButton(onPressed: (){
ShowDilogText(isBold);
setState(() {
final tile = widgetList.firstWhere((item) => item[index]);
});
}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){
}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
if(fieldList[index]=='Date Picker'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
SizedBox(
width: 400,
child: datePickerField),
Spacer(),
IconButton(onPressed: (){}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
if(fieldList[index]=='TextField'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
SizedBox(
width: 400,
child: PreDefinedFields.textFieldCustom),
Spacer(),
IconButton(onPressed: (){}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
if(fieldList[index]=='Button'){
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
PreDefinedFields.elevatedButtonCustom,
Spacer(),
IconButton(onPressed: (){}, icon: Icon(Icons.edit)),
IconButton(onPressed: (){}, icon: Icon(Icons.delete,color: Colors.red,))
],
),
);
}
return Container();
})
),
),
)],
),
],
),
),
);
}
}
How can I fix the RenderFlex overflowed pixel in my card Flutter? I cant seem to find a tutorial regarding this kind of problem. All of the tutorials in StackOverflow teach you to use the listview and SingleChildScrollView but that is not the case for me. The error shows in the card itself and I don't want the card to be using a singlechildscrollview.
I already tried fixing it by lowering the height and width but I will still need a proper tutorial that can help me fix this kind of issues.
This is the card.dart for the application
import 'package:flutter/material.dart';
class ListViewCard extends StatelessWidget {
final String title;
final void Function()? onTap;
final String imageOfPlant; //Change to String
const ListViewCard({
super.key,
required this.title,
required this.onTap,
required this.imageOfPlant,
});
#override
Widget build(BuildContext context) {
return Card(
color: const Color.fromARGB(255, 75, 175, 78),
elevation: 1,
margin: const EdgeInsets.all(8),
semanticContainer: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: InkWell(
splashColor: Colors.lightGreenAccent.withAlpha(30),
onTap: onTap,
//sizedBox of the card
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//image of the card
Image.asset(
imageOfPlant,
height: 200,
width: 150,
fit: BoxFit.cover,
),
SizedBox(
height: 50,
width: 150,
child: Center(
child: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)), // textstyle
),
),
), //text //SizedBox
], // <widget>[]
), // column
), //inkwell
); // card
}
}
This is the home.dart where the card will be called.
import 'package:flutter/material.dart';
import 'package:picleaf/nav_pages/plant.dart';
import '../widgets/card.dart';
class homePage extends StatefulWidget {
const homePage({super.key});
#override
State<homePage> createState() => _HomePageState();
}
List<String> plants = [
"Bell Pepper",
"Cassava",
"Grape",
"Potato",
"Strawberry",
"Tomato",
];
class CustomSearchDelegate extends SearchDelegate {
// Demo list to show querying
CustomSearchDelegate({String hinttext = "Search plants here"})
: super(searchFieldLabel: hinttext);
// first overwrite to
// clear the search text
#override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
onPressed: () {
query = '';
},
icon: const Icon(Icons.clear),
),
];
}
// second overwrite to pop out of search menu
#override
Widget? buildLeading(BuildContext context) {
return IconButton(
onPressed: () {
close(context, null);
},
icon: const Icon(Icons.arrow_back),
);
}
// third overwrite to show query result
#override
Widget buildResults(BuildContext context) {
List<String> matchQuery = [];
for (var fruit in plants) {
if (fruit.toLowerCase().contains(query.toLowerCase())) {
matchQuery.add(fruit);
}
}
return ListView.builder(
itemCount: matchQuery.length,
itemBuilder: (context, index) {
var result = matchQuery[index];
return ListTile(
title: Text(
result,
style: const TextStyle(fontFamily: 'RobotoMedium'),
),
);
},
);
}
// last overwrite to show the
// querying process at the runtime
#override
Widget buildSuggestions(BuildContext context) {
List<String> matchQuery = [];
for (var fruit in plants) {
if (fruit.toLowerCase().contains(query.toLowerCase())) {
matchQuery.add(fruit);
}
}
return ListView.builder(
itemCount: matchQuery.length,
itemBuilder: (context, index) {
var result = matchQuery[index];
return ListTile(
title: Text(
result,
style: const TextStyle(fontFamily: 'RobotoMedium'),
),
);
},
);
}
}
class _HomePageState extends State<homePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text(
"PicLeaf",
style: TextStyle(
color: Color.fromRGBO(102, 204, 102, 1.0),
fontWeight: FontWeight.bold),
),
backgroundColor: Colors.white,
shadowColor: const Color.fromARGB(255, 95, 94, 94),
actions: [
IconButton(
onPressed: () {
// method to show the search bar
showSearch(
context: context,
// delegate to customize the search bar
delegate: CustomSearchDelegate());
},
icon: const Icon(Icons.search, color: Colors.black),
)
],
),
backgroundColor: const Color(0xffeeeeee),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(
height: 10,
),
Container(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
child: const Text(
'Take a pic!',
style: TextStyle(
fontSize: 35,
fontFamily: 'RobotoBold',
color: Colors.black),
textAlign: TextAlign.left,
),
),
Container(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 10),
child: const Text('Find out what is wrong with your plant!',
style: TextStyle(
fontSize: 18,
fontFamily: 'RobotoMedium',
color: Color.fromRGBO(102, 124, 138, 1.0)),
textAlign: TextAlign.left),
),
const SizedBox(
height: 10,
),
Container(
color: const Color.fromRGBO(102, 204, 102, 1.0),
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 0),
margin: const EdgeInsets.symmetric(horizontal: 0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Expanded(
child: Text('List of Plants',
style: TextStyle(
fontSize: 30,
fontFamily: 'RobotoBold',
color: Color(0xffeeeeee)),
textAlign: TextAlign.center),
),
],
),
),
GridView.count(
physics: const ScrollPhysics(),
shrinkWrap: true,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
crossAxisCount: 2,
children: <Widget>[
ListViewCard(
title: "Bell Pepper",
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const SecondPage(plantname: 'Bell Pepper')));
},
imageOfPlant:
"assets/Images_of_Plant/BellPeper_Image.jpg",
),
ListViewCard(
title: "Bell Pepper",
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const SecondPage(plantname: 'Bell Pepper')));
},
imageOfPlant:
"assets/Images_of_Plant/BellPeper_Image.jpg",
),
ListViewCard(
title: "Bell Pepper",
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const SecondPage(plantname: 'Bell Pepper')));
},
imageOfPlant:
"assets/Images_of_Plant/BellPeper_Image.jpg",
),
ListViewCard(
title: "Bell Pepper",
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const SecondPage(plantname: 'Bell Pepper')));
},
imageOfPlant:
"assets/Images_of_Plant/BellPeper_Image.jpg",
),
ListViewCard(
title: "Bell Pepper",
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const SecondPage(plantname: 'Bell Pepper')));
},
imageOfPlant:
"assets/Images_of_Plant/BellPeper_Image.jpg",
),
ListViewCard(
title: "Bell Pepper",
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
const SecondPage(plantname: 'Bell Pepper')));
},
imageOfPlant:
"assets/Images_of_Plant/BellPeper_Image.jpg",
),
],
),
],
),
),
],
),
),
);
}
}
Your gridView's Item give you a specific size but you are setting more than that for your container and text, I suggest you try this:
child: Stack(
children: <Widget>[
//image of the card
Image.asset(
imageOfPlant,
height: double.infinity,
width: 150,
fit: BoxFit.cover,
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: SizedBox(
height: 50,
width: 150,
child: Center(
child: Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 19,
fontFamily: 'RobotoMedium',
color: Color(0xffeeeeee)), // textstyle
),
),
),
), //text //SizedBox
], // <widget>[]
),
and If you want to change item's AspectRatio you can do this:
GridView.count(
physics: const ScrollPhysics(),
shrinkWrap: true,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
crossAxisCount: 2,
childAspectRatio: 2 / 3, <--- add this
children: <Widget>[
...
]
)
I have this bit of code and I want the onPressed function for all options on my menu to open a url. I'm not entirely familar with this so I need a little help.
Here is my code below
class NewProfile extends StatefulWidget {
const NewProfile({Key key, this.scaffoldKey}) : super(key: key);
final GlobalKey<ScaffoldState> scaffoldKey;
_NewProfileState createState() => _NewProfileState();
}
class _NewProfileState extends State<NewProfile> {
Widget _menuHeader() {
final state = context.watch<AuthState>();
if (state.userModel == null) {
return ConstrainedBox(
constraints: BoxConstraints(minWidth: 200, minHeight: 100),
child: Center(
child: Text(
'Login to continue',
style: TextStyles.onPrimaryTitleText,
),
),
).ripple(() {
_logOut();
// Navigator.of(context).pushNamed('/signIn');
});
} else {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
height: 120,
width: 120,
margin: EdgeInsets.only(left: 17, top: 10),
decoration: BoxDecoration(
border: Border.all(color: kPrimaryColor, width: 2),
borderRadius: BorderRadius.circular(200),
image: DecorationImage(
image: customAdvanceNetworkImage(
state.userModel.profilePic ?? Constants.dummyProfilePic,
),
fit: BoxFit.cover,
)),
),
SizedBox(
height: 20,
),
ListTile(
onTap: () {
Navigator.push(context,
ProfilePage.getRoute(profileId: state.userModel.userId));
},
title: Row(
children: <Widget>[
UrlText(
text: state.userModel.displayName ?? "",
style: TextStyles.onPrimaryTitleText
.copyWith(color: Colors.black, fontSize: 20),
),
SizedBox(
width: 3,
),
state.userModel.isVerified ?? false
? customIcon(context,
icon: AppIcon.blueTick,
istwitterIcon: true,
iconColor: AppColor.primary,
size: 18,
paddingIcon: 3)
: SizedBox(
width: 0,
),
],
),
subtitle: customText(
state.userModel.userName,
style: TextStyles.onPrimarySubTitleText
.copyWith(color: Colors.black54, fontSize: 15),
),
trailing: customIcon(context,
icon: AppIcon.arrowDown,
iconColor: AppColor.primary,
paddingIcon: 20),
),
Container(
alignment: Alignment.center,
child: Row(
children: <Widget>[
SizedBox(
width: 17,
),
_tappbleText(context, '${state.userModel.getFollower}',
' Connections', 'FollowerListPage'),
SizedBox(width: 10),
_tappbleText(context, '${state.userModel.getFollowing}',
' Mentors', 'FollowingListPage'),
],
),
),
],
),
);
}
}
Widget _tappbleText(
BuildContext context, String count, String text, String navigateTo) {
return InkWell(
onTap: () {
var authstate = context.read<AuthState>();
List<String> usersList;
authstate.getProfileUser();
Navigator.pop(context);
switch (navigateTo) {
case "FollowerListPage":
usersList = authstate.userModel.followersList;
break;
case "FollowingListPage":
usersList = authstate.userModel.followingList;
break;
default:
}
Navigator.push(
context,
FollowerListPage.getRoute(
profile: authstate.userModel, userList: usersList));
},
child: Row(
children: <Widget>[
customText(
'$count ',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 17),
),
customText(
'$text',
style: TextStyle(color: AppColor.darkGrey, fontSize: 17),
),
],
),
);
}
ListTile _menuListRowButton(String title,
{Function onPressed, IconData icon, bool isEnable = false}) {
return ListTile(
onTap: () {
if (onPressed != null) {
onPressed();
}
},
leading: icon == null
? null
: Padding(
padding: EdgeInsets.only(top: 5),
child: customIcon(
context,
icon: icon,
size: 25,
iconColor: isEnable ? AppColor.darkGrey : AppColor.lightGrey,
),
),
title: customText(
title,
style: TextStyle(
fontSize: 20,
color: isEnable ? AppColor.secondary : AppColor.lightGrey,
),
),
);
}
Positioned _footer() {
return Positioned(
bottom: 0,
right: 0,
left: 0,
child: Column(
children: <Widget>[
Divider(height: 0),
Row(
children: <Widget>[
TextButton(
onPressed: () {
Navigator.push(
context,
ScanScreen.getRoute(
context.read<AuthState>().profileUserModel));
},
child: Image.asset(
"assets/images/qr.png",
height: 25,
),
),
],
),
],
),
);
}
void _logOut() {
final state = Provider.of<AuthState>(context, listen: false);
Navigator.pop(context);
state.logoutCallback();
}
// ignore: unused_element
void _navigateTo(String path) {
Navigator.pop(context);
Navigator.of(context).pushNamed('/$path');
}
#override
Widget build(BuildContext context) {
return Center(
child: SafeArea(
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 45),
child: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Container(
child: _menuHeader(),
),
Divider(),
_menuListRowButton('Profile',
icon: AppIcon.profiles, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Help Center',
icon: AppIcon.helped, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Terms of Service',
icon: AppIcon.agreement, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Privacy Policy',
icon: AppIcon.privacy, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
_menuListRowButton('Cookie Use',
icon: AppIcon.cookies, isEnable: true, onPressed: () {
var state = context.read<AuthState>();
Navigator.push(
context, ProfilePage.getRoute(profileId: state.userId));
}),
Divider(),
_menuListRowButton('Logout',
icon: AppIcon.logout, onPressed: _logOut, isEnable: true),
],
),
),
_footer()
],
),
),
);
}
}
I want them to open to different urls on the web. If there is anything I should add such as dependencies or import any packages, please let me know.
You can navigate to a webpage with the Url Launcher package.
Future<void> launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
i'm trying to make a Tabbar that appear in a new page when the search icon in pressed. The code works fine but i don't know how to implement this tabbar. I want to use the tabbar for splitting the search info, each icon has to show only specific info.
I guess each icon has a specific list?
This is my search_tool.dart this appear when the icon button at the main page is pressed
[EDIT] Now the result is shown correctly, but when I press the search box to write the error message contained in buildSuggestion always appears, instead it should only show the list with the relative records and if something not belonging to that category is searched then it must give the error message
import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';
class LinkItemsSearch extends SearchDelegate<LinkItem>{
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
}
#override
Widget buildResults(BuildContext context) {
var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();
return Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
return mylist.isEmpty?
Container(
color: red,
child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
):Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(onTap: (){ showResults(context);},
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
}
Search icon
IconButton(onPressed:(){
showSearch(context: context, delegate: LinkItemsSearch());
}, icon: Icon(Icons.search),),
List
class LinkItem{
final String title;
final String description;
final link;
LinkItem({
required this.title,
required this.description,
required this.link,
});
}
List<LinkItem> loadLinkItem(){
var link = <LinkItem>[
LinkItem(
title: 'Title1',
description: 'Apps',
link: Title1(),
),LinkItem(
title: 'Title2',
description: 'Movies',
link: Title2(),
),LinkItem(
title: 'Title3',
description: 'Games',
link: Title3(),
),
];
return link;
}
You can override the buildBottom method in your LinkItemsSearch:
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
mylist = loadLinkItem()
.where((p) => p.description.contains(query))
.toList();
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
For this to work, you have to create myList on the top of your LinkItemsSearch and reuse it when filtering everywhere.
Also, I just updated loadLinkItem method to have some input for filtering:
List<LinkItem> loadLinkItem() {
var link = <LinkItem>[
LinkItem(
title: 'Title1',
description: 'Movies',
link: '',
),
LinkItem(
title: 'Title2',
description: 'Games',
link: '',
),
LinkItem(
title: 'Title3',
description: 'Apps',
link: '',
),
];
return link;
}
Of course, I have not completely matched your style, so I did not style buttons as you need it, you might higher bottom bar than 60 as I used. I also have not attached any on press handlers since I am not sure what should they do, but it looks as it is expected: https://i.stack.imgur.com/osUkt.png
I wrapped them with a Column and SingleChildScrollView in case you have more of those items and they need to be scrollable: https://i.stack.imgur.com/FyWVX.png
You can even add some conditions in cases when you don't need this bottom bar to be displayed and in that case, you can just return null from the buildBottom method.
FIX
import 'package:flutter/material.dart';
import 'package:solaris/lista_data.dart';
import 'constants.dart';
class LinkItemsSearch extends SearchDelegate<LinkItem>{
#override
PreferredSizeWidget buildBottom(BuildContext context) {
return PreferredSize(
child: Container(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Apps';
this.showResults(context);
},
child: Text('Apps'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Movies';
this.showResults(context);
},
child: Text('Movies'),
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: ElevatedButton(
onPressed: () {
query = 'Games';
this.showResults(context);
},
child: Text('Games'),
),
),
],
),
),
),
preferredSize: Size.fromHeight(60),
);
}
#override
List<Widget> buildActions(BuildContext context) {
return [IconButton(icon: Icon(Icons.clear),onPressed: () { query=""; },)];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(onPressed: () { Navigator.pop(context); }, icon: Icon(Icons.arrow_back),);
}
#override
Widget buildResults(BuildContext context) {
var mylist = loadLinkItem().where((p) => p.description.contains(query)).toList();
return Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
#override
Widget buildSuggestions(BuildContext context) {
final mylist = query.isEmpty? loadLinkItem():loadLinkItem().where((p) => p.description.contains(RegExp(query, caseSensitive: false))).toList();
return mylist.isEmpty?
Container(
color: red,
child: Center(child: Text('No Result Found . . .', style: TextStyle(color: Colors.white,fontSize: 20,))),
):Container(
color: blue,
child: ListView.builder(
itemCount: mylist.length,
itemBuilder: (context,index){
final LinkItem listitem = mylist[index];
return Container(
color: blue,
child: ListTile(onTap: (){ showResults(context);},
title:InkWell(
onTap: () { Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => listitem.link)); },
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget> [
Text(listitem.title, style: TextStyle(color: Colors.white),),
Text(listitem.description, style: TextStyle(color: Colors.white,fontSize: 14),),
Divider(color: white,),
],
),
),
),
);
}
),
);
}
}
This is a snippet of my widgets.dart file where I defined a widget called see_all_cards and its only purpose is to show an extended list of all cards that I was initially displaying. It should just redirect to Trending.dart. That's my main goal here.
Widget see_all_cards(){
return Container(
child: FlatButton(
child: Text(
"See all (43)",
style: TextStyle(
color: Theme.of(context).accentColor, // error
),
),
onPressed: (){
Navigator.push(
context, // error
MaterialPageRoute(
builder: (BuildContext context){
return trending();
},
),
);
},
)
);
}
The following segment is my main page. I've called SlowlyApp from void main.
class SlowlyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SlowlyApp',
home: Scaffold(
appBar: AppBar(
title: Text('Search',
style: TextStyle(
color: Color.fromRGBO(0,0,0,1),
),
),
backgroundColor: Color.fromRGBO(225,225,0,1),
actions: <Widget>[
IconButton(
icon:
Icon(Icons.search),
onPressed: (){
showSearch(context: context, delegate: data_search());
}
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
smallgap(),
current_cards_heading(),
current_cards(),
see_all_cards(),
smallgap(),
],
),
),
);
}
}
see_all_cards should expect context as parameter. You only have context in your main widget's build method
Widget see_all_cards(BuildContext context){
return Container(
child: FlatButton(
child: Text(
"See all (43)",
style: TextStyle(
color: Theme.of(context).accentColor, // error
),
),
onPressed: (){
Navigator.push(
context, // error
MaterialPageRoute(
builder: (BuildContext context){
return trending();
},
),
);
},
)
);
}
And then you can call passing the context.
class SlowlyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SlowlyApp',
home: Scaffold(
appBar: AppBar(
title: Text('Search',
style: TextStyle(
color: Color.fromRGBO(0,0,0,1),
),
),
backgroundColor: Color.fromRGBO(225,225,0,1),
actions: <Widget>[
IconButton(
icon:
Icon(Icons.search),
onPressed: (){
showSearch(context: context, delegate: data_search());
}
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
smallgap(),
current_cards_heading(),
current_cards(),
see_all_cards(context),
smallgap(),
],
),
),
);
}
}
I also get this error to solve this way
it's the main file container called my widgets _buildFoodItem define context with parameters
Container(
height: MediaQuery.of(context).size.height - 185.0,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(75.0),
),
),
child: ListView(
primary: true,
padding: const EdgeInsets.only(left: 25.0, right: 20.0),
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 45.0),
child: Container(
height: MediaQuery.of(context).size.height - 300.0,
child: ListView(children: [
_buildFoodItem(context, 'assets/images/plate1.png',
'Slazmon bowl', '₹ 150:00'),
_buildFoodItem(context, 'assets/images/plate2.png',
'Spring bowl', '₹ 120:00'),
_buildFoodItem(context, 'assets/images/plate3.png',
'Chikz bowl', '₹ 100:00'),
_buildFoodItem(context, 'assets/images/plate4.png',
'Berry Bowl', '₹ 199:00'),
_buildFoodItem(context, 'assets/images/plate5.png',
'Greezy bowl', '₹ 170:00'),
]),
),
)
],
),
),
this is my widget _buildFoodItem check the context
Widget _buildFoodItem(
BuildContext context, String imgPath, String foodName, String price) {
return Padding(padding: const EdgeInsets.only(
top: 10.0, left: 10.0, right: 10.0),
child: InkWell(
onTap: () {
Navigator.push(
context,
(MaterialPageRoute(
builder: (context) => FoodDetailsPage(
heroTag: imgPath,
foodName: foodName,
foodPrice: price,
),
)));
},
))
}
)