Convenient way to share image + text + url in flutter - dart

I know official package to sharing from flutter app.
https://pub.dartlang.org/packages/share
Its easy to share text and url but I want to share image that is coming from server means its in URL format so may be first I have to convert url to image and then I have to convert image to base64 then I think I can share image But I'm looking for easy way to share image+text+website.
How can I do by official share package? Any other package that maintained well?

The official share package added support for sharing files in v0.6.5, so now you can save the image to a file and share that file. See below an example with an image downloaded from Internet:
import 'package:http/http.dart';
import 'package:share/share.dart';
import 'package:path_provider/path_provider.dart';
void shareImage() async {
final response = await get(imageUrl);
final bytes = response.bodyBytes;
final Directory temp = await getTemporaryDirectory();
final File imageFile = File('${temp.path}/tempImage');
imageFile.writeAsBytesSync(response.bodyBytes);
Share.shareFiles(['${temp.path}/tempImage'], text: 'text to share',);
}

Simple Share seems to be what you're looking for:
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:simple_share/simple_share.dart';
import 'package:flutter/services.dart';
void main() => runApp(SimpleShareApp());
class SimpleShareApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
showPerformanceOverlay: false,
title: 'Simple Share App',
home: MyHomePage()
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<String> getFilePath() async {
try {
String filePath = await FilePicker.getFilePath(type: FileType.ANY);
if (filePath == '') {
return "";
}
print("File path: " + filePath);
return filePath;
} on PlatformException catch (e) {
print("Error while picking the file: " + e.toString());
return null;
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('File Picker Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () {
SimpleShare.share(
title: "Share my message",
msg:
"Lorem ipsum dolor sit amet, consectetur adipisci elit, sed eiusmod " +
"tempor incidunt ut labore et dolore magna aliqua.",
);
},
child: Text('Share text!'),
),
RaisedButton(
onPressed: () async {
final path = await getFilePath();
if (path != null && path.isNotEmpty) {
final uri = Uri.file(path);
SimpleShare.share(
uri: uri.toString(),
title: "Share my file",
msg: "My message");
}
},
child: Text('Share file!'),
),
],
),
),
);
}
}
Source

Related

Blocking ads (pop ups or that redirects to other websites) in flutter in app webview plugin

i am making an app that contains a button which when pressed will open a website that streams video . i have used flutter inappwebview plugin and i want to use content blockers too in my code.after searching i got some codes but i am getting errors that says some part in my code isnt define.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
final Uri _url = Uri.parse('https://zoro.to');
Future<void> _launchUrl() async {
if (!await launchUrl(_url)) {
throw Exception('Could not launch $_url');
}
}
// Future main() async {
// WidgetsFlutterBinding.ensureInitialized();
//
// if (Platform.isAndroid) {
// await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
// }
//
// runApp(new animflix());
// }
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb &&
kDebugMode &&
defaultTargetPlatform == TargetPlatform.android) {
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(
kDebugMode);
}
runApp(const MaterialApp(home: animflix()));
}
// void main() {
// runApp(const animflix());
// }
class animflix extends StatelessWidget {
const animflix({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'anime',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: anime(),
);
}
}
class anime extends StatefulWidget {
const anime({Key? key}) : super(key: key);
#override
State<anime> createState() => _animeState();
}
class _animeState extends State<anime> {
final GlobalKey webViewKey = GlobalKey();
final adUrlFilters = [
".*.doubleclick.net/.*",
".*.ads.pubmatic.com/.*",
".*.googlesyndication.com/.*",
".*.google-analytics.com/.*",
".*.adservice.google.*/.*",
".*.adbrite.com/.*",
".*.exponential.com/.*",
".*.quantserve.com/.*",
".*.scorecardresearch.com/.*",
".*.zedo.com/.*",
".*.adsafeprotected.com/.*",
".*.teads.tv/.*",
".*.outbrain.com/.*"
];
final List<ContentBlocker> contentBlockers = [];
var contentBlockerEnabled = true;
InAppWebViewController? webViewController;
#override
void initState() {
super.initState();
// for each ad URL filter, add a Content Blocker to block its loading
for (final adUrlFilter in adUrlFilters) {
contentBlockers.add(ContentBlocker(
trigger: ContentBlockerTrigger(
urlFilter: adUrlFilter,
),
action: ContentBlockerAction(
type: ContentBlockerActionType.BLOCK,
)));
}
// apply the "display: none" style to some HTML elements
contentBlockers.add(ContentBlocker(
trigger: ContentBlockerTrigger(
urlFilter: ".*",
),
action: ContentBlockerAction(
type: ContentBlockerActionType.CSS_DISPLAY_NONE,
selector: ".banner, .banners, .ads, .ad, .advert")));
}
adblock() async {
contentBlockerEnabled = !contentBlockerEnabled;
if (contentBlockerEnabled) {
await webViewController?.setSettings(
settings: InAppWebViewSettings(contentBlockers: contentBlockers));
} else {
await webViewController?.setSettings(
settings: InAppWebViewSettings(contentBlockers: []));
}
webViewController?.reload();
setState(() {});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: Scaffold(
appBar: AppBar(title: Text("Anime market")),
body: Center(
child: Column(
children: <Widget>[
Container(
child: ElevatedButton(
onPressed: () {
setState(() {
InAppWebView(
key: webViewKey,
initialUrlRequest: URLRequest(
url: Uri.parse('https://www.tomshardware.com/')),
initialData: InAppWebViewSettings(
contentBlockers: contentBlockers),
onWebViewCreated: (controller) {
webViewController = controller;
},
);
});
},
child: Text("sflix"),
),
)
],
)),
),
);
}
}
"InAppWebviewSettings" throughs an error which says it isnt defined.

how to redirect to whatsapp on iOS in flutter

What happens is that I made an app with a button that redirects to whatsapp the problem is that in Android if it works and not in iOS, I have done it with the normal method, I think you have to put something in an iOS file but I don't know That is,
Thanks.
ListTile(
leading: Icon(FontAwesomeIcons.headset,color: Colors.black,),
title: Text('Centro de ayuda '),
onTap: () async => await launch("https://wa.me/${numero}?text=Hola mi nombre es "+prefs.name+' y necesito ayuda con mi orden de Timugo')
)
You can add Flutter launch WhatsApp.
INSTALLATION:
First, add flutter_launch_whatsapp as a dependency in your pubspec.yaml file.
In iOS add the following Info.plist :
<key>LSApplicationQueriesSchemes</key>
<array>
<string>whatsapp</string>
</array>
Example:
import 'package:flutter/material.dart';
import 'package:flutter_launch/flutter_launch.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
initState() {
super.initState();
}
void whatsAppOpen() async {
await FlutterLaunch.launchWathsApp(phone: "5534992016545", message: "Hello");
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('Plugin example app'),
),
body: new Center(
child: FlatButton(
child: Text("Open WhatsApp"),
onPressed: () {
whatsAppOpen();
},
)
),
),
);
}
}
Above reference from:
https://pub.dev/packages/flutter_launch
OR
You can try below code:
var whatsappUrl ="whatsapp://send?phone=$phone";
await canLaunch(whatsappUrl)? launch(whatsappUrl):print("open whatsapp app link or do a snackbar with notification that there is no whatsapp installed");

Flutter setState() function being called but not doing anything

Managed to create a simple reproduction of an error I've come across in my real program, and I'm not sure why this kind of a thing happens. I think if I can understand this, it might help me.
The key here is that I HAVE to have the two pieces of the program separated in this manner, and they need to communicate, but that communication isn't happening the way I would expect. (So please don't suggest I put the timer function inside the rest of the program).
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool textBool = false;
void textChanger() {
if (textBool) {
setState(() {
textBool = false;
});
} else {
setState(() {
textBool = true;
});
}
}
Text myText() {
if (textBool) {
Text newText = new Text('Original Text');
return newText;
} else {
Text newText = new Text('New Text');
return newText;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: myText(),
),
floatingActionButton: FloatingActionButton(
onPressed: stateModify,
tooltip: 'Change Text',
),
);
}
}
Future<void> stateModify() {
Duration waitTimer = new Duration(seconds: 5);
new Timer.periodic(waitTimer, (timer) {
_MyHomePageState().textChanger();
timer.cancel();
});
}
Expected functionality: Click the button and 5 seconds later it should change to the second set of text. Then I should be able to click the button again and switch it back.
Instead in this example I receive the following error:
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: setState() called in constructor: _MyHomePageState#a5177(lifecycle state: created, no widget, not mounted)
And google doesn't seem to be super helpful on this particular issue.
Any suggestions?
Your stateModify function is not a method of _MyHomePageState. Also when you are accessing the _MyHomePageState().textChanger() in stateModify you are eventually creating a new object of _MyHomePageState() but not inserting in render tree.
You should use Timer instead of Timer.periodic. The Timer.periodic will repeat the task until the Timer.cancel is called. Timer will do a callback after the given time period which you require.
Pass the function textChanger when you are calling stateModify that way you will be able to call the function of _MyHomePageState without creating a new object.
Do the following changes.
floatingActionButton: FloatingActionButton(
onPressed: ()=> stateModify(textChanger),
tooltip: 'Change Text',
),
stateModify(dynamic function) {
Timer(Duration(seconds: 5), function);
}

Flutter: Using Shared Preferences to Save Locale Choice

I built an app to use Shared Preferences package to store a user's chosen locale that will override whatever is the current locale by following this example.
The example worked as it should but currently I am trying to find a way to combine the shared preferences package with the tutorial so that users could save their language of choice.
This is the current code:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_localization_intl/locale/locales.dart';
import 'dart:async';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
MyAppState createState() {
return new MyAppState();
}
}
Future<bool> saveLocalePreference(SpecifiedLocalizationDelegate delegate) async{
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.setString("delegate", delegate.toString());
return preferences.commit();
}
class MyAppState extends State<MyApp> {
bool isSaved = false;
SpecifiedLocalizationDelegate _localeOverrideDelegate;
#override
void initState() {
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(null);
super.initState();
}
onLocaleChange(Locale locale) {
setState(() {
_localeOverrideDelegate = new SpecifiedLocalizationDelegate(locale);
saveLanguage(_localeOverrideDelegate);
});
}
void makeDialog(){
showDialog(
context: context,
builder: (_) => new AlertDialog(
content: new Text("Locale has been Saved!")
)
);
}
void saveLanguage(SpecifiedLocalizationDelegate delegate){
saveLocalePreference(delegate).then((bool commited){
isSaved = commited;
setState(() {
commited = true;
print(commited);
});
makeDialog();
});
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
localizationsDelegates: [
_localeOverrideDelegate,
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
Locale('en', ""),
Locale('es', ""),
Locale('fr', "")
],
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(onLocaleChange: onLocaleChange),
);
}
}
typedef void LocaleChangeCallback(Locale locale);
class MyHomePage extends StatefulWidget {
final LocaleChangeCallback onLocaleChange;
MyHomePage({Key key, this.onLocaleChange}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
Locale myLocale = Localizations.localeOf(context);
print(myLocale);
return new Scaffold(
appBar: new AppBar(
title: new Text(
AppLocalizations.of(context).title
),
),
body: new Center(
child: new Column(
children: <Widget>[
new MaterialButton(
child: new Text(AppLocalizations.of(context).buttonText),
onPressed: (){}),
new MaterialButton(
child: new Text("ENGLISH"),
onPressed: (){
widget.onLocaleChange(const Locale("en", ""));
}),
new MaterialButton(
child: new Text("SPANISH"),
onPressed: (){
widget.onLocaleChange(const Locale("es", ""));
}),
new MaterialButton(
child: new Text("FRENCH"),
onPressed: (){
widget.onLocaleChange(const Locale("fr", ""));
}),
new MaterialButton(
child: new Text("DEFAULT"),
onPressed: (){
widget.onLocaleChange(null);
}),
],
),
),
);
}
}
The problem is:
The shared preferences does not seem to work as it will still go back to the default language whenever the app restarts. I tried removing the initState() but it will return this error -
I/flutter ( 5254): The getter 'type' was called on null.
I/flutter ( 5254): Receiver: null
What can I do to make this work?
did you try ?
if(delegate!=null){
preferences.setString("delegate", delegate.toString());
}

Flutter WebviewPlugin remove header and footer of website

By implementation of FlutterWebviewPlugin, I want to show a particular website in a widget but without header and footer.
is this possible in Flutter?
I guess there is a function in FlutterWebviewPlugin class .evalJavascript('some code') but don't know how to use this function. can I add javascript code to this?
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
String url = "https://flutter.io/";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Webview Example',
theme: ThemeData.dark(),
routes: {
"/": (_) => Home(),
"/webview": (_) => WebviewScaffold(
url: url,
withJavascript: true,
withLocalStorage: true,
withZoom: true,
)
},
);
}
}
class Home extends StatefulWidget {
#override
HomeState createState() => HomeState();
}
class HomeState extends State<Home> {
final webView = FlutterWebviewPlugin();
TextEditingController controller = TextEditingController(text: url);
#override
void initState() {
super.initState();
webView.close();
controller.addListener(() {
url = controller.text;
});
}
#override
void dispose() {
webView.dispose();
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("WebView"),
),
body: Center(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10.0),
child: TextField(
controller: controller,
),
),
RaisedButton(
child: Text("Open Webview"),
onPressed: () {
Navigator.of(context).pushNamed("/webview");
},
)
],
),
)
);
}
}
I suggest using Flutter's official WebView plugin: webview_flutter
The plugin also has a method that can run Javascript using WebViewController.evaluateJavascript(String). This method is recommended to be run after WebView.onPageFinished callback.
Your WebView widget should look like this.
WebView(
initialUrl: 'https://flutter.dev',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_webViewController = webViewController;
_controller.complete(webViewController);
},
onProgress: (int progress) {
print("WebView is loading (progress : $progress%)");
},
onPageStarted: (String url) {
print('Page started loading: $url');
},
onPageFinished: (String url) {
print('Page finished loading: $url');
// Removes header and footer from page
_webViewController
.evaluateJavascript("javascript:(function() { " +
"var head = document.getElementsByTagName('header')[0];" +
"head.parentNode.removeChild(head);" +
"var footer = document.getElementsByTagName('footer')[0];" +
"footer.parentNode.removeChild(footer);" +
"})()")
.then((value) => debugPrint('Page finished loading Javascript'))
.catchError((onError) => debugPrint('$onError'));
},
);
Here's a complete sample that you can try.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
WebViewController _webViewController;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: 'https://flutter.dev',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_webViewController = webViewController;
_controller.complete(webViewController);
},
onProgress: (int progress) {
print("WebView is loading (progress : $progress%)");
},
javascriptChannels: <JavascriptChannel>{
_toasterJavascriptChannel(context),
},
navigationDelegate: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
print('blocking navigation to $request}');
return NavigationDecision.prevent;
}
print('allowing navigation to $request');
return NavigationDecision.navigate;
},
onPageStarted: (String url) {
print('Page started loading: $url');
},
onPageFinished: (String url) {
print('Page finished loading: $url');
_webViewController
.evaluateJavascript("javascript:(function() { " +
"var head = document.getElementsByTagName('header')[0];" +
"head.parentNode.removeChild(head);" +
"var footer = document.getElementsByTagName('footer')[0];" +
"footer.parentNode.removeChild(footer);" +
"})()")
.then((value) => debugPrint('Page finished loading Javascript'))
.catchError((onError) => debugPrint('$onError'));
},
gestureNavigationEnabled: true,
);
}),
);
}
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toaster',
onMessageReceived: (JavascriptMessage message) {
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
}
How the app looks running
_webViewController.runJavascript(
"document.getElementsByTagName('header')[0].style.display='none'");
_webViewController.runJavascript(
"document.getElementsByTagName('footer')[0].style.display='none'");
You can use the flutter_inappwebview plugin (I'm the author) and inject an UserScript at UserScriptInjectionTime.AT_DOCUMENT_START to hide or remove HTML elements when the web page loads (check JavaScript - User Scripts official docs for User Scripts details).
As I have already answered here for a similar issue, here is a code example using the current latest version 6 (6.0.0-beta.18) with URL https://getmobie.de/impressum that removes the header and footer HTML elements:
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb &&
kDebugMode &&
defaultTargetPlatform == TargetPlatform.android) {
await InAppWebViewController.setWebContentsDebuggingEnabled(kDebugMode);
}
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey webViewKey = GlobalKey();
InAppWebViewController? webViewController;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("InAppWebView test"),
),
body: Column(children: <Widget>[
Expanded(
child: InAppWebView(
key: webViewKey,
initialUrlRequest:
URLRequest(url: WebUri("https://getmobie.de/impressum")),
initialUserScripts: UnmodifiableListView([
UserScript(source: """
window.addEventListener('DOMContentLoaded', function(event) {
var header = document.querySelector('.elementor-location-header'); // use here the correct CSS selector for your use case
if (header != null) {
header.remove(); // remove the HTML element. Instead, to simply hide the HTML element, use header.style.display = 'none';
}
var footer = document.querySelector('.elementor-location-footer'); // use here the correct CSS selector for your use case
if (footer != null) {
footer.remove(); // remove the HTML element. Instead, to simply hide the HTML element, use footer.style.display = 'none';
}
});
""", injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START)
]),
onWebViewCreated: (controller) {
webViewController = controller;
},
),
),
]));
}
}
For your use case, use the right CSS selector inside the user script js source to correctly get and remove the header and footer HTML elements from your web page!

Resources