I would like to add a hyperlink at the bottom of the screen where the Markdown widget is read.
I tried to include the hyperlink in the markdown file but flutter is not launching it.
Then I tried this:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Protective measures'),
),
body: Column(
children: <Widget>[
Flexible(
child: FutureBuilder(
future: DefaultAssetBundle.of(context)
.loadString("assets/docs/protective_measures.md"),
builder:
(BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return Markdown(
data: snapshot.data,
styleSheet: MarkdownStyleSheet(
textAlign: WrapAlignment.start,
p: TextStyle(
fontSize: 16,
color: isDark ? Colors.white : Colors.black,
),
h2: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: isDark ? Colors.white : Colors.black,
),
h1: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
color: isDark ? Colors.white : Colors.black,
),
),
);
}
return Center(
child: CircularProgressIndicator(),
);
},
),
),
InkWell(
child: Text(
'My Hyperlink',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.blue,
decoration: TextDecoration.underline
),
),
onTap: () => launch('https://stackoverflow.com'),
),
],
),
);
}
The result is not really what I wanted. I want a hypertext at the bottom of the screen, just after the Markdown. I also tried with ListView instead of Column but it's not working.
Any hint ?
For plugin flutter_markdown you can do like this
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:url_launcher/url_launcher.dart';
final String _markdownData = "-This is [Google link](https://www.google.com)";
// view
MarkdownBody(
data: _markdownData,
onTapLink: (text, url, title){
launch(url);
},
)
Update for flutter_markdown version 0.5.1 or lower:
MarkdownBody(
data: _markdownData,
onTapLink: (url) {
launch(url);
},
)
I got it. The Markdown() widget has a onTapLink method and I just need to do:
onTapLink(url){
launch(url);
}
It is always good to do a null reference check to:
MarkdownBody(
data: privacyPolicy._privacyPolicy,
onTapLink: (text, url, title){
launch(url!);
},
Expanding upon the code written by: Azamat Mirvosiqov
Related
when i click on the link in drawer it show me different error.
when i click on any drawer link it stuck and give me error message and took me to other error page.
_///////////////////////////////////////////////////////
_///////////////////////////////////////////////////////
_///////////////////////////////////////////////////////
_///////////////////////////////////////////////////////
class MainDrawer extends StatelessWidget {
const MainDrawer({super.key});
Widget buildListTitle(String title, IconData icon, Function function) {
return ListTile(
leading: Icon(
icon,
size: 20,
),
title: Text(
title,
style: TextStyle(
fontFamily: 'RobotoCondensed',
fontSize: 24,
fontWeight: FontWeight.bold),
),
onTap: function(),
);
}
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: [
Container(
height: 120,
width: double.infinity,
padding: EdgeInsets.all(20),
alignment: Alignment.centerLeft,
color: Theme.of(context).accentColor,
child: Text(
'cooking up',
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 30,
color: Theme.of(context).primaryColor,
),
),
),
SizedBox(
height: 20,
),
buildListTitle("Meal", Icons.restaurant, () {
Navigator.of(context).pushNamed("/");
}),
buildListTitle("Meal", Icons.restaurant, () {
Navigator.of(context).pushNamed(FilterScreen.routeName);
}),
],
),
);
}
}
On your buildListTitle change the onTap: function() to onTap: function
So as you can see here's my profile page i just want to create an update method here. Is it possible to do inside this page for the update method? I'm still new with flutter development here. So if there's any method that can update inside this page it would be really helpful for me thank you. Because usually I only see that people would create a new page as for the database page but what I do with the login and register is that I do inside the page. So I just tryna see if there's a way to create update method inside a profile page
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_user_profile/model/parking.dart';
class ParkingPage extends StatefulWidget {
#override
State<ParkingPage> createState() => _ParkingPageState();
}
class _ParkingPageState extends State<ParkingPage> {
User? user = FirebaseAuth.instance.currentUser;
Parking loginuser = Parking();
#override
void initState(){
super.initState();
FirebaseFirestore.instance
.collection('parkingTech')
.doc(user!.uid)
.get()
.then((value){
this.loginuser = Parking.fromMap(value.data());
setState(() {});
});
}
// #override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF121212),
appBar: AppBar(
backgroundColor: Color(0xFF121212),
elevation: 0.0,
title: Text('Parking Tech',
style:TextStyle(
color: Color(0xFFFFFFFF),
fontWeight: FontWeight.bold,
),
),
centerTitle:true,
actions: [
// Icon(Icons.menu,
// color:Colors.amber,
// size:40,
// )
]
),
body: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:[
Row(
mainAxisAlignment: MainAxisAlignment.center ,
children:[
CircleAvatar(
backgroundColor: Colors.amber,
radius: 100.0,
child: Center(
child: Text('P',
style:TextStyle(
fontSize: 80,
color: Color(0xFF121212),
fontWeight: FontWeight.bold,
),
),
)
),
],
),
SizedBox(height: 15),
Text("Parking time : ${loginuser.name} ",
style:TextStyle(
fontSize: 20,
color: Colors.grey,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10),
Text('00 : 56 : 05',
style:TextStyle(
fontSize: 50,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 15),
Text('P15 AED',
style:TextStyle(
fontSize: 30,
color: Colors.blueGrey,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 15),
Text('On Parking ',
style:TextStyle(
fontSize: 15,
color: Colors.amber,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 15),
Text('End Parking',
style:TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 12),
Text('Extend Parking',
style:TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 12),
],
),
),
);
}
}
If I understand your use case correctly, you want to update your widget whenever the user object changes? That is what I suspect since you are calling it a 'profile page', and it seems like the data in this widget is dependent on the user.
You could listen to changes to the Firebase user object, and in the callback, you could then rebuild your widget. Here is the relevant snippet from the documentation, adapted to your use case (untested):
#override
void initState() {
super.initState();
FirebaseAuth.instance.userChanges().asyncMap((User? user) =>
FirebaseFirestore.instance
.collection('parkingTech')
.doc(user!.uid)
.get()
.then((value) {
this.loginuser = Parking.fromMap(value.data());
setState(() {});
}));
}
I want to show PopupMenu with dynamic data which will I got from API response. I tried with listview.builder inside PopupMenu child but it not works.
My code of showmenu()
void showMemberMenu() async {
await showMenu(
context: context,
position: RelativeRect.fromLTRB(200, 150, 100, 100),
items: [
PopupMenuItem(
value: 1,
child: Text(
"ROHIT",
style: TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
color: green3),
),
),
PopupMenuItem(
value: 2,
child: Text(
"REKHA",
style: TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
color: green3),
),
),
PopupMenuItem(
value: 3,
child: Text(
"DHRUV",
style: TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
color: green3),
),
),
],
elevation: 8.0,
).then((value) {
if (value != null) print(value);
});
}
Please help to get out from this.
You can use List.generate method to generate the dynamic length of the list using the existing list you get from the API response.
Below is an example of how you can achieve it.
void showMemberMenu() async {
final List<String> popList = ['ROHIT', 'REKHA', 'DHRUV'];
await showMenu(
context: context,
position: RelativeRect.fromLTRB(200, 150, 100, 100),
items: List.generate(
popList.length,
(index) => PopupMenuItem(
value: 1,
child: Text(
popList[index],
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
),
),
elevation: 8.0,
).then((value) {
if (value != null) print(value);
});
}
I've added final List<String> popList = ['ROHIT', 'REKHA', 'DHRUV'];
just for the testing purpose, and you can replace it with your list
you get from API response.
Try this:
call the api and put the value in PopupMenuItem
class PopupMenu {
PopupMenu({#required this.title, #required this.onTap});
final String title;
final VoidCallback onTap;
static PopupMenuButton<String> createPopup(List<PopupMenu> popupItems) {
return PopupMenuButton<String>(
onSelected: (value) {
popupItems.firstWhere((e) => e.title == value).onTap();
},
itemBuilder: (context) => popupItems
.map((item) => PopupMenuItem<String>(
value: item.title,
child: Text(
item.title,
),
))
.toList(),
);
}
}
you can try to do something like this:
https://dartpad.dev/?id=a3f9002a37cbacc2cfae46174cbd2eba
you can add any state management to replace the FutureBuilder but this is the logical approach.
I hope it is helpful.
I want when the Sign Up is clicked, the browser be open and go to my website but i dont know how to do that.
here is my code, when i tap on Sign Up it doesn't work:
return Container(
child: GestureDetector(
onTap: () => launch("https://my.drclubs.ir/"),
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "Don\`t have an Account?",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500),
),
TextSpan(
text: "Sign Up",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold),
),
],
),
),
),
);
}
You can use a package called url_launcher here.
Example:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
const _url = 'https://flutter.dev'; /// Put your custom url here.
void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: RaisedButton(
onPressed: _launchURL,
child: Text('Show Flutter homepage'),
),
),
),
),
);
void _launchURL() async =>
await canLaunch(_url) ? await launch(_url) : throw 'Could not launch $_url';
You can try this:
return Container(
child: GestureDetector(
onTap: _launchURL,
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "Don\`t have an Account?",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500),
),
TextSpan(
text: "Sign Up",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold),
),
],
),
),
),
);
I'm using url_launcher: ^5.4.10 for launching different url scheme but is that external link is working fine on ios simulator but not working opening phone dialpad and default email address while its working fine on android devices
i tested it on ios simulator not real device
if i try to open dialpad here is exception
{PTS: 6.000 s, decode: 32.021 ms},
]
flutter: could not launch tel:+18002509646
when i try open email box here is exception i received
*** First throw call stack:
(
0 CoreFoundation 0x00000001084f4a2a __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00000001083874ce objc_exception_throw + 48
2 Foundation 0x0000000107f2e808 -[__NSConcreteURLComponents initWithString:] + 0
3 CoreServices 0x000000010f7c2db2 -[_LSURLOverride initWithOriginalURL:checkingForAvailableApplications:] + 136
4 CoreServices 0x000000010f7c35b5 -[_LSURLOverride initWithOriginalURL:] + 22
5 CoreServices 0x000000010f7c3d97 _ZN14LaunchServices12URLOverridesL20getURLOverrideCommonEP5NSURL + 374
6 CoreServices 0x000000010f7c3c10 -[LSApplicationWorkspace(LSURLOverride) URLOverrideForURL:] + 12
7 UIKitCore <…>
my code url launcher
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
class Contactcus extends StatelessWidget {
void customLaunch(command) async {
if (await canLaunch(command)) {
await launch(command);
} else {
print(' could not launch $command');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 10),
child: Container(
child: Column(
children: <Widget>[
Text(
'Contact us'.toUpperCase(),
style: TextStyle(
fontFamily: 'TT NORMS',
fontWeight: FontWeight.w100,
fontSize: 25,
),
),
Padding(
padding: EdgeInsets.only(left: 0),
child: Row(
children: <Widget>[
Expanded(
child: SizedBox(
child: ListTile(
leading: Icon(Icons.phone,
size: 25, color: Colors.black87),
onTap: () {
customLaunch('tel:+18001569647');
},
title: Text(
'Phone'.toUpperCase(),
style: TextStyle(
fontFamily: 'TT NORMS',
fontSize: 20,
fontWeight: FontWeight.w100,
),
),
subtitle: Text(
'1 (800) 250-9646 ',
style: TextStyle(
color: Colors.black87,
),
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(left: 0),
child: Row(
children: <Widget>[
Expanded(
child: SizedBox(
child: ListTile(
leading: Icon(Icons.email,
size: 25, color: Colors.black87),
onTap: () {
customLaunch(
'mailto:livinghopetv#cornerstoneasianchurch.com?subject=Feed%20back&body=Write your%20feedback');
},
title: Text(
'Email',
style: TextStyle(
fontFamily: 'TT NORMS',
fontWeight: FontWeight.w100,
fontSize: 20
),
),
subtitle: Text(
'livinghopetv#cornerstoneasianchurch.com',
style: TextStyle(color: Colors.black87,
),
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(left: 0),
child: Row(
children: <Widget>[
Expanded(
child: SizedBox(
child: ListTile(
leading: Icon(Icons.location_on,
size: 28, color: Colors.black87),
onTap:(){
customLaunch('https://www.google.ca/maps/place/3434+Cawthra+Rd,+Mississauga,+ON+L5A+2X7/#43.6025224,-79.6147441,17z/data=!3m1!4b1!4m5!3m4!1s0x882b470c94e668ff:0x62c956c363a795d9!8m2!3d43.6025185!4d-79.6125554');
},
title: Text(
'MAILING ADDRESS',
style: TextStyle(
fontFamily: 'TT NORMS',
fontWeight: FontWeight.w100,
fontSize: 20
),
),
subtitle: Text(
'Att: Living Hope TV\n'
'Cornerstone Asian Church\n'
'3434 Cawthra Rd\n'
'Mississauga, ON L5A 2X7\n'
'Canada',
style: TextStyle(
color: Colors.black87,
),
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 70),
child: Row(
mainAxisAlignment:MainAxisAlignment.center,
children: <Widget>[
IconButton(
icon: Image.asset('images/youtube.png'),
iconSize: 30,
onPressed: () {
customLaunch('https://www.youtube.com/channel/UCsnohhaCJvkT3prNnMwlvnA');
},
),
IconButton(
icon: Image.asset('images/twitter.png'),
iconSize:30,
onPressed: () {
customLaunch('https://twitter.com/livinghopetv1');
},
),
IconButton(
icon: Image.asset('images/instagram.png'),
iconSize: 30,
onPressed: () {
customLaunch('https://www.instagram.com/livinghopetv/');
},
),
IconButton(
icon: Image.asset('images/facebook.png'),
iconSize: 30,
onPressed: () {
customLaunch('https://www.facebook.com/livinghopetelevision');
},
),
IconButton(
icon: Image.asset('images/web.png'),
iconSize: 30,
onPressed: () {
customLaunch('https://www.livinghopetv.org');
},
),
],
),
)
],
),
),
),
],
),
),
);
}
}
I have a suggestion to make, can you try giving the command like this:
Checks
1. Code Check
command = "tel://214324234"
// Also, try using Future in place of void
Future<void> customLaunch(command) async {
if (await canLaunch(command)) {
await launch(command);
} else {
print(' could not launch $command');
}
}
2. Formatting Check: Do check, if there is no space between tel: and the <phone number>, it has to be written without space, that is, tel:<phone_number>
3. Update Check: Also, there is a new update, that is, 5.5.0, please upgrade your packages accordingly in your pubspec.yaml file. Why, am I telling you cos, sometimes, previous version does not support some functionalities in your Mobile Platform
4. Real Device Check: Sometimes what happens is, the simulator does not support some functionalities. I would request you to please get a real iOS Device, and check it. If the above doesn't solve your issue, this might do the job
Add these lines to your myproject/ios/Runner/Info.plist file if you want to use external links.
<key>LSApplicationQueriesSchemes</key>
<array>
<string>http</string>
<string>https</string>
</array>
This work for me:
import 'dart:io' show Platform;
/// Dial
Future<void> contactDial(String number) async {
await _launchCaller(number);
}
_launchCaller(String number) async {
String url = Platform.isIOS ? 'tel://$number' : 'tel:$number';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}