Flutter: Adding a custom dialog to Text - flutter

I am trying to create a Custom dialog when the text is clicked. but dialog is not creating.
below adding the Dialog box implementation code
child: new Center(
child: new RichText(
text: new TextSpan(
children: [
new TextSpan(
text: 'Accept the ',
style: new TextStyle(color: Colors.black),
),
new TextSpan(
text: 'Terms & Conditions',
style: new TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold),
recognizer: new TapGestureRecognizer()
..onTap = () {
CustomDialogBox(
title: "Custom Dialog Demo",
descriptions: "Hii all this is a custom dialog in flutter and you will be use in your flutter applications",
text: "Yes",
);
},
),
],
),
),
),
adding Custom Dialog Code. creating as new widget in new dart page and importing in the application.
we need it as a widget which we can use many times in the app.
so creating in a new dart page.
class CustomDialogBox extends StatefulWidget {
final String title, descriptions, text;
final Image img;
const CustomDialogBox({Key key, this.title, this.descriptions, this.text, this.img}) : super(key: key);
#override
_CustomDialogBoxState createState() => _CustomDialogBoxState();
}
class _CustomDialogBoxState extends State<CustomDialogBox> {
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(Constants.padding),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: contentBox(context),
);
}
contentBox(context){
return Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: Constants.padding,top: Constants.avatarRadius
+ Constants.padding, right: Constants.padding,bottom: Constants.padding
),
margin: EdgeInsets.only(top: Constants.avatarRadius),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(Constants.padding),
boxShadow: [
BoxShadow(color: Colors.black,offset: Offset(0,10),
blurRadius: 10
),
]
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(widget.title,style: TextStyle(fontSize: 22,fontWeight: FontWeight.w600),),
SizedBox(height: 15,),
Text(widget.descriptions,style: TextStyle(fontSize: 14),textAlign: TextAlign.center,),
SizedBox(height: 22,),
Align(
alignment: Alignment.bottomRight,
child: FlatButton(
onPressed: (){
Navigator.of(context).pop();
},
child: Text(widget.text,style: TextStyle(fontSize: 18),)),
),
],
),
),
],
);
}
}

Nothing wrong with CustomDialogBox ... your onTap method is incorrect in the question posted.
You should do
showDialog(
context: context,
builder: (BuildContext context) => CustomDialogBox(),
)

You need wrap 'CustomDialogBox' with 'showDialog()' widget.
child: new Center(
child: new RichText(
text: new TextSpan(
children: [
new TextSpan(
text: 'Accept the ',
style: new TextStyle(color: Colors.black),
),
new TextSpan(
text: 'Terms & Conditions',
style: new TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold),
recognizer: new TapGestureRecognizer()
..onTap = () {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomDialogBox(
title: "Custom Dialog Demo",
descriptions: "Hii all this is a custom dialog in flutter and you will be use in your flutter applications",
text: "Yes",
);
}
);
},
),
],
),
),
),

Related

How to make each _buildrow go the next page in Flutter?

i got problem when i dont know to make each buildrow go to each page?this is for buildDrawer can you help me with this?
builDrawer fuction this for profile screen.dart
_buildDrawer() {
return ClipPath(
clipper: OvalRightBorderClipper(),
child: Drawer(
Container(
height: 90,
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient:
LinearGradient(colors: [Colors.pink, Colors.red])),
child: CircleAvatar(
radius: 40,
backgroundImage: NetworkImage(profile),
),
),
SizedBox(height: 5.0),
Text(
"Mohd Amin bin Yaakob",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
Text(
"Pegawai",
style: TextStyle(color: active, fontSize: 16.0),
),
SizedBox(height: 30.0),
_buildRow(Icons.home, "Home"),
_buildDivider(),
_buildRow(Icons.person_pin, "Your profile"),
_buildDivider(),
_buildRow(Icons.settings, "Settings"),
_buildDivider(),
_buildRow(Icons.email, "Contact us"),
_buildDivider(),
_buildRow(Icons.info_outline, "Help"),
_buildDivider(),
],
),
),
),
),
),
);
}
How to make Functional Navigator each buildRow
You need to make rows with clickable widgets like listtile.
Try this inside your _buildRow()
Widget _buildRow(IconData icon, String title) {
final TextStyle tStyle = TextStyle(color: active, fontSize: 16.0);
return ListTile(
title: Text( title, style: tStyle, ),
leading: Icon( icon, color: active, ),
onTap: () {
// Your navigation code here
},
);
}
You can remove the container as well and try contentPadding in ListTile
Its explained in the drawer documentation https://docs.flutter.dev/cookbook/design/drawer
You can require an onTap function in your _buildRow method. Also wrap you Container inside an InkWell widget and this function in onTap property.
Following is the revised code:
Widget _buildRow(IconData icon, String title, VoidCallback onTap) {
final TextStyle tStyle = TextStyle(color: active, fontSize: 16.0);
return InkWell(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: [
Icon(
icon,
color: active,
),
SizedBox(width: 10.0),
Text(
title,
style: tStyle,
),
],
),
),
onTap: onTap,
);
}
When calling the above function, provide the onTap callback like this:
_buildRow(Icons.home, "Home", () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return HomePage();
},
),
);
});

How to shorten the flutter dart code below to a function?

I am having a tough time shortening the code below to a function. I am looking to duplicate the elevated button below to hundreds of buttons in my screen hence believe function is the best way to do so, then I can just call the function in my page.
ElevatedButton(
style:
TextButton.styleFrom(backgroundColor: Colors.grey.shade200),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
textAlign: TextAlign.justify,
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: "Diploma in Business | ",
style: TextStyle(color: Colors.black),
),
TextSpan(
text: "Taylor\u0027s",
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),
),
],
),
),
),
onPressed: () {
sendAnalyticsEvent(
eventName: "diplomainbusiness_taylors",
clickevent: "User clicked dipt");
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
)),
builder: (context) => Container(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.network(
'https://i.imgur.com/bcAC3cA.jpg',
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const CircularProgressIndicator();
},
errorBuilder: (context, error, stackTrace) =>
const Text('Some errors occurred!'),
),
ListTile(
title: Text(
'\nThis programme is specifically designed to equip students with solid business knowledge and skills, with a central focus on instilling a global mindset as well as creative and critical thinking, set in an experimental learning environment. Upon successful completion of the programme, students will be able to seamlessly transition into our degree and have the competitive advantage required to seek global employment opportunities.\n',
textAlign: TextAlign.justify,
),
),
ListTile(
title: Text(
'• April and August Intake \n• 2 years programme\n• Scholarships available',
textAlign: TextAlign.justify,
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
width: double.infinity,
child: CupertinoButton.filled(
child: Text("Interested? Get more info!"),
onPressed: () => openBrowserTab(),
),
),
),
],
),
),
);
},
),
Basically, the elevated button will trigger a bottom sheet and inside the bottom sheet, there is an image, a few texts (List tile) and so. Is it possible to make this into a function or nah this is the shortest code possible? Kindly need some guidance on this.
Thank you so much!
Declare it like this
import 'package:flutter/material.dart';
class CustomElevatedButton extends StatelessWidget {
final String name;
final String education;
final String eventName;
final String clickEvent;
final String imageURl;
final String errorMessage;
final String information1;
final String information2;
final String information3;
const CustomElevatedButton(
{Key? key,
required this.name,
required this.education,
required this.eventName,
required this.clickEvent,
required this.imageURl,
required this.errorMessage,
required this.information1,
required this.information2,
required this.information3})
: super(key: key);
#override
Widget build(BuildContext context) {
return ElevatedButton(
style: TextButton.styleFrom(backgroundColor: Colors.grey.shade200),
child: Align(
alignment: Alignment.centerLeft,
child: RichText(
textAlign: TextAlign.justify,
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: education,
style: const TextStyle(color: Colors.black),
),
TextSpan(
text: name,
style:
const TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
],
),
),
),
onPressed: () {
sendAnalyticsEvent(
eventName: eventName,
clickevent: clickEvent);
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: const RoundedRectangleBorder(
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
)),
builder: (context) => Container(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.network(
imageURl,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const CircularProgressIndicator();
},
errorBuilder: (context, error, stackTrace) =>
Text(errorMessage),
),
ListTile(
title: Text(
information1,
textAlign: TextAlign.justify,
),
),
ListTile(
title: Text(
information2,
textAlign: TextAlign.justify,
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
width: double.infinity,
child: CupertinoButton.filled(
child: Text(information3),
onPressed: () => openBrowserTab(),
),
),
),
],
),
),
);
},
);
}
}
use it like this
const CustomElevatedButton(
clickEvent: 'User clicked dipt',
education: 'Diploma in Business | ',
errorMessage: 'Some errors occurred!',
eventName: 'diplomainbusiness_taylors',
imageURl: 'https://i.imgur.com/bcAC3cA.jpg',
information1: '\nThis programme is specifically designed to equip students with solid business knowledge and skills, with a central focus on instilling a global mindset as well as creative and critical thinking, set in an experimental learning environment. Upon successful completion of the programme, students will be able to seamlessly transition into our degree and have the competitive advantage required to seek global employment opportunities.\n',
information2: '• April and August Intake \n• 2 years programme\n• Scholarships available',
information3: 'Interested? Get more info!',
name: 'Taylor\u0027s',
),
You can extract anything you want including the styles and onpressed callbacks.
If you have any doubts feel free to ask.

Navigator.pop shows me a black screen

It's been a while since I've been blocking backtracking on my flutter application, I tried the Navigator.pop (context) but I still ran into a black screen, I searched the forums for success but I'm still stuck. I want that when I click on return that it brings me back to my previous page without initializing the page
import 'package:MerchantIsland/log/database.dart';
import 'package:MerchantIsland/pages/home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class productPage extends StatefulWidget {
final String productId;
const productPage({Key key, this.productId}) : super(key: key);
#override
_productPageState createState() => _productPageState();}
class _productPageState extends State<productPage> {
#override
Widget build(BuildContext context) {
ProductService productService = ProductService();
return WillPopScope(
onWillPop: (){
MovetoPreviousScreen();},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
MovetoPreviousScreen();
},
),
centerTitle: true,
title: Text(
'Merchant island',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
body: Stack(
children: [
FutureBuilder(
future: productService.ProductData.doc(widget.productId).get(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if(snapshot.connectionState==ConnectionState.done){
Map<String, dynamic> documentData=snapshot.data.data();
return ListView(
children: [
Container(
height: 400.0,
child: Image.network(
"${documentData['pictures'][0]}",
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0,horizontal: 24.0),
child: Text('${documentData['productName']}'??"Nom du produit",
style:TextStyle(
fontSize: 28.0,
fontWeight: FontWeight.bold,
) ,),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0,horizontal: 24.0),
child: Text('${documentData['price']}',
style:TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.bold,
color:Colors.red
) ),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0,horizontal: 24.0),
child: Text('${documentData['description']}',
style:TextStyle(
fontSize: 18
) ),
)
],
);
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}),
],
),
),
); }
// ignore: non_constant_identifier_names
void MovetoPreviousScreen() {
Navigator.of(context).pop(); }}
return page
import 'package:MerchantIsland/log/database.dart';
import 'package:MerchantIsland/log/loginUI.dart';
import 'package:MerchantIsland/pages/Sellproduct.dart';
import 'package:MerchantIsland/pages/bidPage.dart';
import 'package:MerchantIsland/products/productPage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:MerchantIsland/pages/profil.dart';
import 'package:MerchantIsland/pages/balance.dart';
import 'package:MerchantIsland/pages/Settings.dart';
import 'package:google_sign_in/google_sign_in.dart';
// ignore: camel_case_types
class home extends StatefulWidget {
#override
_homeState createState() => _homeState();}
// ignore: camel_case_types
class _homeState extends State<home> {
ProductService productService = ProductService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text("Merchant Island"),
actions: [
IconButton(
icon: Icon(Icons.search, color: Colors.white,), onPressed: null,),
],
),
body: Stack(
children: [
FutureBuilder<QuerySnapshot>(
future: productService.ProductData.get(),
builder:(context,snapshot){
if(snapshot.hasError){
return Scaffold(
body: Center(
child: Text("Error: ${snapshot.error}"),
),
);
}
if(snapshot.connectionState==ConnectionState.done){
return Container(
child: ListView(
children: snapshot.data.docs.map((documents){
return Container(
child: GestureDetector(
onTap: (){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>productPage(productId: documents.id,)));
},
child: Container(
child: productCard(documents.data()["productName"],documents.data()["category"], documents.data()["price"],documents.data()["pictures"]) ,
),
),
);
}).toList(),
),
);
}
return Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}),
],
),
drawer: BDrawer(context),
); }}
// ignore: non_constant_identifier_names
Drawer BDrawer(BuildContext context) {
FirebaseAuth _auth = FirebaseAuth.instance;
GoogleSignIn _googleSignIn = GoogleSignIn();
Future <void> signOut() async {
await _auth.signOut();
await _googleSignIn.disconnect();
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => LoginUI()));}
return Drawer(
child: ListView(
children: [
UserAccountsDrawerHeader(
accountName: Text('TITAN', style: TextStyle(
fontSize: 18.0,
),),
accountEmail: Text('philippetankoano#gmail.com'),
currentAccountPicture: GestureDetector(
child: CircleAvatar(
backgroundColor: Colors.grey,
child: Icon(
Icons.person, color: Colors.white
),
),
),
otherAccountsPictures: [
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => profil(),)),
child: (
Icon(
Icons.mode_edit, size: 30.0,
)
),
)
],
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => balancepage())),
child: ListTile(
leading: Icon(
Icons.account_balance, size: 30.0, color: Colors.blue,),
title: Text(' Balance', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => home())),
child: ListTile(
leading: Icon(Icons.home, size: 30.0, color: Colors.blue,),
title: Text(' Home', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SellProduct())),
child: ListTile(
leading: Icon(
Icons.account_balance, size: 30.0, color: Colors.blue,),
title: Text(' Sell product', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () {},
child: ListTile(
leading: Icon(
Icons.shopping_basket_outlined, size: 40.0,
color: Colors.blue,),
title: Text('Sale', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () {},
child: ListTile(
leading: Icon(Icons.category, size: 30.0, color: Colors.blue,),
title: Text(' Categories', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => bidPage())),
child: ListTile(
leading: Icon(
Icons.event_available, size: 40.0, color: Colors.blue,),
title: Text(' Bid', style: TextStyle(
fontSize: 18.0,
),),
),
),
Divider(),
InkWell(
onTap: () =>
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Settingpage(),)),
child: ListTile(
leading: Icon(Icons.settings, size: 30.0, color: Colors.blue,),
title: Text(' Setting', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () {},
child: ListTile(
leading: Icon(Icons.help, size: 30.0, color: Colors.blue,),
title: Text(' Help', style: TextStyle(
fontSize: 18.0,
),),
),
),
InkWell(
onTap: () async {
signOut();
},
child: ListTile(
leading: Icon(Icons.exit_to_app, size: 30.0, color: Colors.blue,),
title: Text(' Deconnexion', style: TextStyle(
fontSize: 18.0,
),),
),
),
]
), );}
Padding productCard(String name,String category,String price,List imageUrl){
return Padding(
padding: const EdgeInsets.all(6.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(-2,-1),
blurRadius: 5
)
] ),
child: GestureDetector(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(7.0),
child: Image.network(
"${imageUrl[0]}",
height: 500,
width: 450,
),
),
],
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(' $name ',style: TextStyle(fontSize: 24.0,fontWeight: FontWeight.bold)),
Text('$price ',style: TextStyle(fontSize: 20.0,fontWeight: FontWeight.bold,color: Colors.red)),
],
),
),
Text('Categorie: $category \n',style: TextStyle(fontSize: 24.0,)),
],
),
), ),);}
Method One(Recommended)
First check if there is more than one Material App in your project if found then remove all except the root one (Child of MyApp) if that does not work or you have only one MaterialApp in your project then only try second method
Method Two(Try only if method one doesn't solved your issue or you don't have more than one MaterialApp in your project)
Replace Navigator.of(context).pop(); with Navigator.of(context,rootNavigator:true).pop(context)
If you got a black screen, it's probably because you are popping the only screen in your stack.
If you want that Navigator.of(context).pop() remove only the last screen, you have to display the current screen with a Navigator.of(context).push()
When clicking on the custom back icon Leading with in flutter
Replace Navigator.of(context).pop(); with Navigator.of(context,rootNavigator:true).pop(context)
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: ColorConstants.kBlackColor,
leading: BackButton(
color: ColorConstants.kWhiteColor,
onPressed: (){
Navigator.of(context,rootNavigator:true).pop(context);
},
),
),
In my case the problem was having some Navigator.pop(context) inside other callback functions.
When I clicked the back button, a socket would close, and consequently call the callback function (that also called pop()), so I would have Navigator.pop(context) called more than one time. And since my Page widget was the second element of the stack, calling it 2 times would pop also the root, therefore generating the black screen.
What I did to fix it, even though I think there might be better solutions, was substituting all the Navigator.pop(context) calls with the following:
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
Another possible solution would be to initialize a bool variable (or a some kind of counter) and then call pop() only if that variable is true, then set it to false.:
// init
bool variable = true;
if (variable) {
Navigator.pop(context);
variable = false;
}

Flutter: ShowDialog not working with the OnTap() method of a ListTile

I am using a drawer to create a menu that houses ListTiles for the options. I want to create a popup when the tiles are tapped by the user. Currently, the code displays nothing when the tiles are tapped even though after the showDialog there is a Navigator.pop().
// Drawer that includes the ListTiles in question
Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Smash Tracker'),
),
),
ListTile(
title: Text(
'About',
style: TextStyle(
fontFamily: 'Smash',
fontSize: 15.0,
color: Color.fromRGBO(77, 114, 152, 1.0),
),
),
onTap: () {
// Show PopUp
showDialog(context: context, child:
new AlertDialog(
title: new Text(
'About',
style: TextStyle(fontFamily: "Smash"),
),
content: new Text(
'This is a placeholder. This is a placeholder. This is a placeholder. This is a placeholder.',
style: TextStyle(fontFamily: "Smash"),
),
)
);
// Doesn't run
Navigator.pop(context);
},
),
Here is a demo:
via GIPHY
The other ListTiles have the only have Navigator.pop() inside of their onTap() method.
The dialog isn't showing because you are popping it immediately with the Navigator.pop(context). You can await the Dialog since it returns a Future<T> before popping.
I added a demo using your widget tree as an example:
Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Smash Tracker'),
),
ListTile(
title: Text(
'About',
style: TextStyle(
fontFamily: 'Smash',
fontSize: 15.0,
color: Color.fromRGBO(77, 114, 152, 1.0),
),
),
onTap: () async { // mark the function as async
print('tap');
// Show PopUp
// await the dialog
await showDialog(
context: context,
child: new AlertDialog(
title: new Text(
'About',
style: TextStyle(fontFamily: "Smash"),
),
content: new Text(
'This is a placeholder. This is a placeholder. This is a placeholder. This is a placeholder.',
style: TextStyle(fontFamily: "Smash"),
),
));
// Doesn't run
Navigator.pop(context);
},
),
],
),
),
OUTPUT:

How to center the Title of a ListTile in Flutter

I have been trying again today to center the title of a Flutter ListTile. Over the past few days I have spent an hour or two Googling and trying things then loosing my cool and giving up.
I am just learning Flutter and love the concept but can find no video training courses (Lynda.com, uDemy.com etc). I have read through the relevant documentation but cannot get rid of all the red lines that appear when I try to apply them to my code.
There must be logic in the syntax but after 2 weeks I have not worked it out yet.
Back to the problem, I have tried
List<Widget> list = <Widget>[
new ListTile(
new child: Center (
title:
new Text('Title 1',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
List<Widget> list = <Widget>[
new ListTile(
title:
new child: Center (
new Text('Title 2',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
List<Widget> list = <Widget>[
new ListTile(
child: Center
title: (
new Text('Title 3',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
List<Widget> list = <Widget>[
new ListTile(
title: Center
new Text('Title 4',
style: new TextStyle(
fontWeight: FontWeight.w500,
color: Colors.deepOrangeAccent,
fontSize: 25.0)),
)
),
];
Please help me with this problem and also where to find a video course on Flutter?
On the upside, if this continues I will no longer be grey, I will be bald instead.
I thought I worked it out when I added 'textAlign: TextAlign.center,' to the text object. There were no red lines but the text was still left aligned.
I am not sure what have you tried, but you in order to center the title of the ListTile you can use a center widget like you did in your code, or wrap your text within a Row widget and set mainAxisAlignment: MainAxisAlignment.center.
Using Center widget:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("ListTile Example"),),
body: new ListView(
children: new List.generate(7, (int index) {
return new ListTile(
title: new Center(child: new Text("Centered Title#$index",
style: new TextStyle(
fontWeight: FontWeight.w500, fontSize: 25.0),)),
subtitle: new Text("My title is centered"),
);
}),
),
);
}
Using Row widget:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("ListTile Example"),),
body: new ListView(
children: new List.generate(7, (int index) {
return new ListTile(
title: new Row(children: <Widget>[new Text("Centered Title#$index",
style: new TextStyle(
fontWeight: FontWeight.w500, fontSize: 25.0),)
], mainAxisAlignment: MainAxisAlignment.center,),
subtitle: new Text("My title is centered"),
);
}),
),
);
}
However, your problem is not about centering the title, it is about you are trying to insert too big of a Text inside a small area, that is why you are getting the red lines, so one solution is choose a smaller fontSize, a better solution is to get rid of ListTile and build your own custom widget, since a ListTile is
A single fixed-height row that typically contains some text as well as
a leading or trailing icon.
So it should not be used if you are using bigger widgets.
This is simple example of how to create a custom widget that resembles ListTile, but is more flexible and customizable when dealing with larger items:
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text("ListTile Example"),),
body: new ListView(
children: new List.generate(7, (int index) {
return new Container(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: new Column(
children: <Widget>[
new Align (child: new Text("Centered Title $index",
style: new TextStyle(fontSize: 40.0),), //so big text
alignment: FractionalOffset.topLeft,),
new Divider(color: Colors.blue,),
new Align (child: new Text("Subtitle $index"),
alignment: FractionalOffset.topLeft,),
new Divider(color: Colors.blue,),
new Align (child: new Text("More stuff $index"),
alignment: FractionalOffset.topLeft,),
new Row(mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ //add some actions, icons...etc
new FlatButton(onPressed: () {}, child: new Text("EDIT")),
new FlatButton(onPressed: () {},
child: new Text("DELETE",
style: new TextStyle(color: Colors.redAccent),))
],),
],
),
);
}),
)
);
}
You can change the alignment of the text by using textAlign
Use this to center the Title of a ListTile:
ListTile(title: Text('YOUR TEXT', textAlign: TextAlign.center));
Here is my example of a three-row tile:
class ThreeRowTile extends StatelessWidget {
final Widget title;
final Widget detail;
final String utility1;
final String utility1Help;
final String utility2Help;
final String utility2;
final Icon icon;
final String cell;
final String home;
final String office;
final String email;
final VoidCallback cellTapped;
final VoidCallback cellLongPressed;
final VoidCallback iconTapped;
ThreeRowTile({
this.title,
this.icon,
this.detail,
this.utility1,
this.utility1Help,
this.utility2,
this.utility2Help,
this.cellTapped,
this.home,
this.email,
this.cell,
this.office,
this.cellLongPressed,
this.iconTapped,
});
#override
Widget build(BuildContext context) {
List<Widget> buildChildren() {
List<Widget> builder = [];
if (cell.isNotEmpty && !cell.toString().contains("--")) {
builder.add(ListTile(
leading: const Icon(Icons.phone),
title: Text(
'Cell',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
cell.toString().length > 0 ? cell : "No Number Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: cell.toString().contains("--")
? null
: () {
globals.Utility.makePhoneCall(context, cell);
},
));
}
if (office.isNotEmpty && !office.toString().contains("--")) {
builder.add(ListTile(
leading: const Icon(Icons.work),
title: Text(
'Office',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
office.toString().length > 0 ? office : "No Number Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: office.toString().contains("--")
? null
: () {
globals.Utility.makePhoneCall(context, office);
},
));
}
if (home.isNotEmpty && !home.toString().contains("--")) {
builder.add(ListTile(
leading: const Icon(Icons.home),
title: Text(
'Home',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
home.toString().length > 0 ? home : "No Number Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: home.toString().contains("--")
? null
: () {
globals.Utility.makePhoneCall(context, home);
},
));
}
if (email.isNotEmpty && !email.contains('No Email Address')) {
builder.add(ListTile(
leading: const Icon(Icons.email),
title: Text(
'Email',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
email.toString().length > 0 ? email : "No Email Found",
textScaleFactor: globals.textScaleFactor,
),
onTap: email.toString().isEmpty
? null
: () {
globals.Utility.sendEmail(context, email);
},
));
}
if (builder.isEmpty) {
builder.add(
ListTile(
leading: const Icon(Icons.info),
title: Text(
'No Contact Information Found',
textScaleFactor: globals.textScaleFactor,
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
);
}
return builder;
}
String _utility1 =
utility1 == null || utility1.contains("1-1-1800") ? "" : utility1;
String _utility2 =
utility2 == null || utility2.contains("1-1-1800") ? "" : utility2;
var rowCard = Container(
decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey[300]))),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 5.0),
child: new Column(
children: <Widget>[
Row(
children: <Widget>[
Align(
child: IconButton(
icon: icon,
onPressed: iconTapped,
),
alignment: FractionalOffset.centerLeft,
),
Expanded(
child: Column(
children: <Widget>[
new Align(
child: title, //so big text
alignment: FractionalOffset.topLeft,
),
// new Divider(),
new Align(
child: detail,
alignment: FractionalOffset.topLeft,
),
// new Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: Container(
margin: const EdgeInsets.all(3.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(
color: _utility1.length > 1
? Colors.grey
: Colors.transparent)),
child: Tooltip(
message:
utility1Help == null ? "" : utility1Help,
child: Text(
_utility1,
maxLines: 1,
textAlign: TextAlign.center,
textScaleFactor: globals.textScaleFactor,
),
),
),
),
Expanded(
child: Container(
margin: const EdgeInsets.all(3.0),
padding: const EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(
color: _utility2.length > 1
? Colors.grey
: Colors.transparent)),
child: Tooltip(
message: utility2 == null ? "" : utility2,
child: Text(
_utility2,
maxLines: 1,
textAlign: TextAlign.center,
textScaleFactor: globals.textScaleFactor,
),
),
),
),
],
),
],
),
),
Align(
child: IconButton(
icon: Icon(Icons.arrow_drop_down),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
child: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: buildChildren()),
),
));
});
},
),
alignment: FractionalOffset.centerRight,
),
],
),
],
),
),
// color: globals.isDarkTheme ? Colors.black45 : Colors.white,
);
return (rowCard);
}
}
And it can be used like this:
ThreeRowTile(
icon: Icon(Icons.person),
title: _contacts?.items[index]?.lastName.toString().isEmpty &&
_contacts?.items[index]?.firstName.toString().isEmpty
? null
: Text(
(_contacts?.items[index]?.lastName ?? "") +
", " +
(_contacts?.items[index]?.firstName ?? ""),
textScaleFactor: globals.textScaleFactor,
),
detail: Text(
_contacts?.items[index]?.lastActivity,
textScaleFactor: globals.textScaleFactor,
),
utility1: _contacts?.items[index]?.dateCreated,
utility1Help: 'Date Created',
utility2: _contacts?.items[index]?.dateModified,
utility2Help: "Date Modified",
cell: _contacts?.items[index]?.cell,
home: _contacts?.items[index]?.home,
office: _contacts?.items[index]?.office,
email: _contacts?.items[index]?.email,
cellTapped: () {
globals.contactID = _contacts?.items[index]?.contactID;
Navigator.of(context).pushNamed("/contact_details").then((value) {
if (globals.infoChanged) {
_getData("", false).then((newitems) {
setState(() {
_contacts = newitems;
});
});
}
});
},
);