Commit 2efec9ce by Karthik Ponnam

Uses Overlay

parent 74b61285
# [fluttertoast](https://pub.dartlang.org/packages/fluttertoast)
Android and iOS Toast Library for Flutter
Flutter Toast Library for Flutter
> Supported Platforms
>
> - Android
> - IOS
> - Web (Uses [Toastify-JS](https://github.com/apvarun/toastify-js))
> - ALL
If you dont want to use androidx then use `fluttertoast` version `2.2.11`
## Notice
This update has changes complete plugin to new one
Previously this plugin used to interact with native platform which now removed.
## Features
1 - Full Controll of the Toast
2 - Toasts will be queued
3 - Remove a toast
4 - Clear the queue
## How to Use
```yaml
# add this line to your dependencies
fluttertoast: ^5.0.1
fluttertoast: ^6.0.0
```
```dart
import 'package:fluttertoast/fluttertoast.dart';
```
```dart
FlutterToast.showToast(
msg: "This is Center Short Toast",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
```dart
FlutterToast flutterToast;
@override
void initState() {
super.initState();
flutterToast = FlutterToast(context);
}
_showToast() {
Widget toast = Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.greenAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.check),
SizedBox(
width: 12.0,
),
Text("This is a Custom Toast"),
],
),
);
flutterToast.showToast(
child: toast,
gravity: ToastGravity.BOTTOM,
toastDuration: Duration(seconds: 2),
);
}
```
Now Call `_showToast()`
For more details check `example` project
| property | description | default |
| --------------- | ------------------------------------------------------------------ |------------|
| msg | String (Not Null)(required) |required |
| toastLength | Toast.LENGTH_SHORT or Toast.LENGTH_LONG (optional) |Toast.LENGTH_SHORT |
| gravity | ToastGravity.TOP (or) ToastGravity.CENTER (or) ToastGravity.BOTTOM (Web Only supports top, bottom) | ToastGravity.BOTTOM |
| timeInSecForIosWeb | int (only for ios) | 1 |
| backgroundColor | Colors.red |Colors.black |
| textcolor | Colors.white |Colors.white |
| fontSize | 16.0 (float) | 16.0 |
| webShowClose | false (bool) | false |
| webBgColor | String (hex Color) | linear-gradient(to right, #00b09b, #96c93d) |
| webPosition | String (`left`, `center` or `right`) | right |
| child | Widget (Not Null)(required) |required |
| toastDuration | Duration (optional) | |
| gravity | ToastGravity.* | |
### To cancel all the toasts call
```dart
FlutterToast.cancel()
```
### Custom Toast For Android
Create a file named `toast_custom.xml` in your project `app/res/layout` folder and do custom styling
```xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="50dp"
android:background="@drawable/corner"
android:layout_marginEnd="50dp">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#CC000000"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:paddingEnd="16dp"
android:paddingBottom="10dp"
android:textStyle="bold"
android:textColor="#FFFFFF"
tools:text="Toast should be short." />
</FrameLayout>
// To remove present shwoing toast
flutterToast.removeCustomToast()
// To clear the queue
flutterToast.removeQueuedCustomToasts();
```
## Preview Images
<img src="https://raw.githubusercontent.com/PonnamKarthik/FlutterToast/master/screenshot/1.png" width="320px" />
<img src="https://raw.githubusercontent.com/PonnamKarthik/FlutterToast/master/screenshot/2.png" width="320px" />
<img src="https://raw.githubusercontent.com/PonnamKarthik/FlutterToast/master/screenshot/3.png" width="320px" />
<img src="https://raw.githubusercontent.com/PonnamKarthik/FlutterToast/master/screenshot/4.png" width="320px" />
## Announcement Regarding iOS
Needs contributor for iOS Development can reach me over [my mail](mailto:ponnamkarthik3@gmail.com)
<img src="https://raw.githubusercontent.com/PonnamKarthik/FlutterToast/master/screenshot/1.png" width="320px" />
## If you need any features suggest
\ No newline at end of file
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State />
<State>
<id>Error handlingJava</id>
</State>
<State>
<id>JVM languages</id>
</State>
<State>
<id>Java</id>
</State>
</expanded-state>
<selected-state>
<State>
<id>Android</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
</project>
\ No newline at end of file
FlutterToast
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/FlutterToast.iml" filepath="$PROJECT_DIR$/.idea/modules/FlutterToast.iml" group="FlutterToast" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ No newline at end of file
group 'com.example.FlutterToast'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
}
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 16
}
lintOptions {
disable 'InvalidPackage'
}
}
dependencies {
// implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
rootProject.name = 'FlutterToast'
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.ponnamkarthik.toast.fluttertoast">
</manifest>
package io.github.ponnamkarthik.toast.fluttertoast
import android.content.Context
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry.Registrar
/** FlutterToastPlugin */
public class FlutterToastPlugin: FlutterPlugin {
private var channel : MethodChannel? = null
companion object {
@JvmStatic
fun registerWith(registrar: Registrar) {
val plugin = FlutterToastPlugin()
plugin.setupChannel(registrar.messenger(), registrar.context())
}
}
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
setupChannel(binding.binaryMessenger, binding.applicationContext)
}
override fun onDetachedFromEngine(p0: FlutterPlugin.FlutterPluginBinding) {
teardownChannel();
}
fun setupChannel(messenger: BinaryMessenger, context: Context) {
channel = MethodChannel(messenger, "PonnamKarthik/fluttertoast")
val handler = MethodCallHandlerImpl(context)
channel?.setMethodCallHandler(handler)
}
private fun teardownChannel() {
channel?.setMethodCallHandler(null)
channel = null
}
}
package io.github.ponnamkarthik.toast.fluttertoast
import android.app.Activity
import android.content.Context
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.os.Build
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.TextView
import android.widget.Toast
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
internal class MethodCallHandlerImpl(var context: Context) : MethodCallHandler {
private lateinit var mToast: Toast
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"showToast" -> {
val mMessage = call.argument<Any>("msg").toString()
val length = call.argument<Any>("length").toString()
val gravity = call.argument<Any>("gravity").toString()
val bgcolor = call.argument<Number>("bgcolor")
val textcolor = call.argument<Number>("textcolor")
val textSize = call.argument<Number>("fontSize")
val mGravity: Int
mGravity = when (gravity) {
"top" -> Gravity.TOP
"center" -> Gravity.CENTER
else -> Gravity.BOTTOM
}
val mDuration: Int
mDuration = if (length == "long") {
Toast.LENGTH_LONG
} else {
Toast.LENGTH_SHORT
}
if (bgcolor != null || textcolor != null || textSize != null) {
val layout = (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(R.layout.toast_custom, null)
val text = layout.findViewById<TextView>(R.id.text)
text.text = mMessage
val gradientDrawable: Drawable = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
context.getDrawable(R.drawable.corner)!!
} else {
context.resources.getDrawable(R.drawable.corner)
}
if(bgcolor != null && gradientDrawable != null) {
gradientDrawable.setColorFilter(bgcolor.toInt(), PorterDuff.Mode.SRC_ATOP)
}
text.background = gradientDrawable
if(textSize != null) {
text.textSize = textSize.toFloat()
}
if(textcolor != null) {
text.setTextColor(textcolor.toInt())
}
mToast = Toast(context)
mToast.setDuration(mDuration)
mToast.setView(layout)
} else {
mToast = Toast.makeText(context, mMessage, mDuration)
}
if (mGravity == Gravity.CENTER) {
mToast.setGravity(mGravity, 0, 0)
} else if (mGravity == Gravity.TOP) {
mToast.setGravity(mGravity, 0, 100)
} else {
mToast.setGravity(mGravity, 0, 100)
}
if (context is Activity) {
(context as Activity).runOnUiThread { mToast.show() }
} else {
mToast.show()
}
result.success(true)
}
"cancel" -> {
if (mToast != null) {
mToast.cancel()
}
result.success(true)
}
else -> result.notImplemented()
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:bottomRightRadius="40dp"
android:bottomLeftRadius="40dp"
android:topLeftRadius="40dp"
android:topRightRadius="40dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners
android:radius="100dp">
</corners>
<solid
android:color="#000000">
</solid>
<padding
android:left="16dp"
android:top="12dp"
android:right="16dp"
android:bottom="12dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="50dp"
android:background="@drawable/corner"
android:layout_marginEnd="50dp">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#CC000000"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:gravity="center"
android:paddingEnd="16dp"
android:paddingBottom="10dp"
android:textColor="#FFFFFF"
tools:text="Toast should be short." />
</FrameLayout>
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"fluttertoast","path":"C:\\\\Users\\\\ponna\\\\Desktop\\\\my\\\\plugins\\\\fluttertoast\\\\","dependencies":[]}],"android":[{"name":"fluttertoast","path":"C:\\\\Users\\\\ponna\\\\Desktop\\\\my\\\\plugins\\\\fluttertoast\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[{"name":"fluttertoast","path":"C:\\\\Users\\\\ponna\\\\Desktop\\\\my\\\\plugins\\\\fluttertoast\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"fluttertoast","dependencies":[]}],"date_created":"2020-07-05 15:32:05.671138","version":"1.19.0-4.3.pre"}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() => runApp(new MyApp());
void main() => runApp(
MaterialApp(
home: MyApp(),
),
);
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
initState() {
super.initState();
}
FlutterToast flutterToast;
void showLongToast() {
FlutterToast.showToast(
msg: "This is Long Toast",
toastLength: Toast.LENGTH_LONG,
);
}
Widget toast = Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.greenAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.check),
SizedBox(
width: 12.0,
),
Text("This is a Custom Toast"),
],
),
);
void showWebColoredToast() {
FlutterToast.showToast(
msg: "This is Colored Toast with android duration of 5 Sec",
toastLength: Toast.LENGTH_SHORT,
webBgColor: "#e74c3c",
timeInSecForIosWeb: 5,
_showToast() {
flutterToast.showToast(
child: toast,
gravity: ToastGravity.BOTTOM,
toastDuration: Duration(seconds: 2),
);
}
void showColoredToast() {
FlutterToast.showToast(
msg: "This is Colored Toast with android duration of 5 Sec",
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.red,
textColor: Colors.white);
_showToastCancel() {
Widget toastWithButton = Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.redAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Text(
"This is a Custom Toast This is a Custom Toast This is a Custom Toast This is a Custom Toast This is a Custom Toast This is a Custom Toast",
softWrap: true,
style: TextStyle(
color: Colors.white,
),
),
),
IconButton(
icon: Icon(
Icons.close,
),
color: Colors.white,
onPressed: () {
flutterToast.removeCustomToast();
},
)
],
),
);
flutterToast.showToast(
child: toastWithButton,
gravity: ToastGravity.CENTER,
toastDuration: Duration(seconds: 50),
);
}
void showShortToast() {
FlutterToast.showToast(msg: "This is Short Toast", toastLength: Toast.LENGTH_SHORT, timeInSecForIosWeb: 1);
_queueToasts() {
flutterToast.showToast(
child: toast,
gravity: ToastGravity.CENTER,
toastDuration: Duration(seconds: 2),
);
flutterToast.showToast(
child: toast,
gravity: ToastGravity.BOTTOM,
toastDuration: Duration(seconds: 2),
);
flutterToast.showToast(
child: toast,
gravity: ToastGravity.TOP,
toastDuration: Duration(seconds: 2),
);
flutterToast.showToast(
child: toast,
gravity: ToastGravity.CENTER,
toastDuration: Duration(seconds: 2),
);
flutterToast.showToast(
child: toast,
gravity: ToastGravity.TOP,
toastDuration: Duration(seconds: 2),
);
}
void showTopShortToast() {
FlutterToast.showToast(msg: "This is Top Short Toast", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.TOP, timeInSecForIosWeb: 1);
_removeToast() {
flutterToast.removeCustomToast();
}
void showCenterShortToast() {
FlutterToast.showToast(msg: "This is Center Short Toast", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 1);
_removeAllQueuedToasts() {
flutterToast.removeQueuedCustomToasts();
}
void cancelToast() {
FlutterToast.cancel();
@override
void initState() {
super.initState();
flutterToast = FlutterToast(context);
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('Flutter Toast'),
),
body: new Center(
child: new Column(
children: <Widget>[
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(child: new Text('Show Long Toast'), onPressed: showLongToast),
),
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(child: new Text('Show Short Toast'), onPressed: showShortToast),
),
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(child: new Text('Show Center Short Toast'), onPressed: showCenterShortToast),
),
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(child: new Text('Show Top Short Toast'), onPressed: showTopShortToast),
),
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(child: new Text('Show Colored Toast'), onPressed: showColoredToast),
),
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(child: new Text('Show Web Colored Toast'), onPressed: showWebColoredToast),
),
new Padding(
padding: const EdgeInsets.all(10.0),
child: new RaisedButton(
child: new Text('Cancel Toasts'),
onPressed: cancelToast,
),
),
],
return Scaffold(
appBar: AppBar(
title: Text("Custom Toasts"),
),
body: Column(
children: [
SizedBox(
height: 24.0,
),
),
RaisedButton(
child: Text("Show Custom Toast"),
onPressed: () {
_showToast();
},
),
SizedBox(
height: 24.0,
),
RaisedButton(
child: Text("Custom Toast With Close Button"),
onPressed: () {
_showToastCancel();
},
),
SizedBox(
height: 24.0,
),
RaisedButton(
child: Text("Queue Toasts"),
onPressed: () {
_queueToasts();
},
),
SizedBox(
height: 24.0,
),
RaisedButton(
child: Text("Cancel Toast"),
onPressed: () {
_removeToast();
},
),
SizedBox(
height: 24.0,
),
RaisedButton(
child: Text("Remove Queued Toasts"),
onPressed: () {
_removeAllQueuedToasts();
},
),
],
),
);
}
......
......@@ -60,11 +60,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
fluttertoast:
dependency: "direct main"
description:
......
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/flutter_export_environment.sh
\ No newline at end of file
#import <Flutter/Flutter.h>
@interface FlutterToastPlugin : NSObject<FlutterPlugin>
@end
#import "FlutterToastPlugin.h"
@implementation FlutterToastPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"FlutterToast"
binaryMessenger:[registrar messenger]];
FlutterToastPlugin* instance = [[FlutterToastPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"getPlatformVersion" isEqualToString:call.method]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else {
result(FlutterMethodNotImplemented);
}
}
@end
#import <Flutter/Flutter.h>
@interface FluttertoastPlugin : NSObject<FlutterPlugin>
@end
#import "FluttertoastPlugin.h"
#import "UIView+Toast.h"
static NSString *const CHANNEL_NAME = @"PonnamKarthik/fluttertoast";
@interface FluttertoastPlugin ()
@property(nonatomic, retain) FlutterMethodChannel *channel;
@end
@implementation FluttertoastPlugin {
FlutterResult _result;
}
+ (void)registerWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:CHANNEL_NAME
binaryMessenger:[registrar messenger]];
UIViewController *viewController =
[UIApplication sharedApplication].delegate.window.rootViewController;
FluttertoastPlugin *instance = [[FluttertoastPlugin alloc] init];
instance.channel = channel;
[registrar addMethodCallDelegate:instance channel:channel];
}
- (UIColor*) colorWithHex: (NSUInteger)hex {
CGFloat red, green, blue, alpha;
red = ((CGFloat)((hex >> 16) & 0xFF)) / ((CGFloat)0xFF);
green = ((CGFloat)((hex >> 8) & 0xFF)) / ((CGFloat)0xFF);
blue = ((CGFloat)((hex >> 0) & 0xFF)) / ((CGFloat)0xFF);
alpha = hex > 0xFFFFFF ? ((CGFloat)((hex >> 24) & 0xFF)) / ((CGFloat)0xFF) : 1;
return [UIColor colorWithRed: red green:green blue:blue alpha:alpha];
}
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
if([@"cancel" isEqualToString:call.method]) {
[[UIApplication sharedApplication].delegate.window.rootViewController.view hideAllToasts];
result([NSNumber numberWithBool:true]);
} else if ([@"showToast" isEqualToString:call.method]) {
NSString *msg = call.arguments[@"msg"];
NSString *gravity = call.arguments[@"gravity"];
NSString *durationTime = call.arguments[@"time"];
NSNumber *bgcolor = call.arguments[@"bgcolor"];
NSNumber *textcolor = call.arguments[@"textcolor"];
NSNumber *size = call.arguments[@"size"];
NSNumber *fontSize = call.arguments[@"fontSize"];
CGFloat cgf = [fontSize doubleValue];
int time = 1;
@try {
time = [durationTime intValue];
} @catch (NSException *e) {
time = 3;
}
if (time > 10) time = 10;
else if (time < 1) time = 1;
CSToastStyle *style = [[CSToastStyle alloc] initWithDefaultStyle];
style.messageFont = [UIFont systemFontOfSize:cgf];
style.backgroundColor = [self colorWithHex:bgcolor.unsignedIntegerValue];
style.messageColor = [self colorWithHex:textcolor.unsignedIntegerValue];
if (@available(iOS 11.0, *)) {
UIWindow *window = UIApplication.sharedApplication.keyWindow;
CGFloat topPadding = window.safeAreaInsets.top;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
}
if ([gravity isEqualToString:@"top"]) {
[[self _readKeyWindow] makeToast:msg duration:time position:CSToastPositionTop style:style];
} else if ([gravity isEqualToString:@"center"]) {
[[self _readKeyWindow] makeToast:msg duration:time position:CSToastPositionCenter style:style];
} else {
[[self _readKeyWindow] makeToast:msg duration:time position:CSToastPositionBottom style:style];
}
result([NSNumber numberWithBool:true]);
} else {
result(FlutterMethodNotImplemented);
}
}
#pragma mark - read the key window
- (UIWindow *)_readKeyWindow {
for (UIWindow *window in UIApplication.sharedApplication.windows) {
if ([window isKindOfClass:UIWindow.class] && window.isKeyWindow && window.windowLevel == UIWindowLevelNormal) {
return window;
}
}
return nil;
}
@end
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint FlutterToast.podspec' to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'FlutterToast'
s.version = '0.0.1'
s.summary = 'Toast Library for Flutter, Easily create toast messages in single line of code'
s.description = <<-DESC
Toast Library for Flutter, Easily create toast messages in single line of code
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.platform = :ios, '8.0'
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
end
import 'dart:async';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/foundation.dart';
enum Toast { LENGTH_SHORT, LENGTH_LONG }
enum ToastGravity { TOP, BOTTOM, CENTER }
enum ToastGravity { TOP, BOTTOM, CENTER, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, CENTER_LEFT, CENTER_RIGHT }
class FlutterToast {
static const MethodChannel _channel = const MethodChannel('PonnamKarthik/fluttertoast');
BuildContext context;
static Future<bool> cancel() async {
bool res = await _channel.invokeMethod("cancel");
return res;
static final FlutterToast _instance = FlutterToast._internal();
factory FlutterToast(BuildContext context) {
_instance.context = context;
return _instance;
}
static Future<bool> showToast(
{@required String msg,
Toast toastLength,
int timeInSecForIosWeb = 1,
double fontSize,
ToastGravity gravity,
Color backgroundColor,
Color textColor,
bool webShowClose = false,
webBgColor: "linear-gradient(to right, #00b09b, #96c93d)",
webPosition: "right"
// Function(bool) didTap,
}) async {
// this.didTap = didTap;
String toast = "short";
if (toastLength == Toast.LENGTH_LONG) {
toast = "long";
}
FlutterToast._internal();
String gravityToast = "bottom";
if (gravity == ToastGravity.TOP) {
gravityToast = "top";
} else if (gravity == ToastGravity.CENTER) {
gravityToast = "center";
} else {
gravityToast = "bottom";
}
OverlayEntry _entry;
List<_ToastEntry> _overlayQueue = List();
Timer _timer;
if (backgroundColor == null && defaultTargetPlatform == TargetPlatform.iOS) {
backgroundColor = Colors.black;
}
if (textColor == null && defaultTargetPlatform == TargetPlatform.iOS) {
textColor = Colors.white;
_showOverlay() {
if (_overlayQueue.length == 0) {
_entry = null;
return;
}
final Map<String, dynamic> params = <String, dynamic>{
'msg': msg ?? "",
'length': toast,
'time': timeInSecForIosWeb,
'gravity': gravityToast,
'bgcolor': backgroundColor != null ? backgroundColor.value : null,
'textcolor': textColor != null ? textColor.value : null,
'fontSize': fontSize,
'webShowClose': webShowClose,
'webBgColor': webBgColor,
'webPosition': webPosition
};
_ToastEntry _toastEntry = _overlayQueue.removeAt(0);
_entry = _toastEntry.entry;
if (context == null) throw ("Error: Context is null");
Overlay.of(context).insert(_entry);
_timer = Timer(_toastEntry.duration, () {
removeCustomToast();
});
}
removeCustomToast() {
_timer?.cancel();
_timer = null;
if (_entry != null) _entry.remove();
_showOverlay();
}
bool res = await _channel.invokeMethod('showToast', params);
return res;
removeQueuedCustomToasts() {
_timer?.cancel();
_timer = null;
_overlayQueue.clear();
if (_entry != null) _entry.remove();
_entry = null;
}
void showToast({
@required Widget child,
Duration toastDuration,
ToastGravity gravity,
}) {
OverlayEntry newEntry = OverlayEntry(builder: (context) {
return _getPostionWidgetBasedOnGravity(child, gravity);
});
_overlayQueue.add(_ToastEntry(entry: newEntry, duration: toastDuration ?? Duration(seconds: 2)));
if (_timer == null) _showOverlay();
}
_getPostionWidgetBasedOnGravity(Widget child, ToastGravity gravity) {
Widget newChild = Center(
child: Material(
color: Colors.transparent,
child: child,
),
);
switch (gravity) {
case ToastGravity.TOP:
return Positioned(top: 100.0, left: 24.0, right: 24.0, child: newChild);
break;
case ToastGravity.TOP_LEFT:
return Positioned(top: 100.0, left: 24.0, child: newChild);
break;
case ToastGravity.TOP_RIGHT:
return Positioned(top: 100.0, right: 24.0, child: newChild);
break;
case ToastGravity.CENTER:
return Positioned(top: 50.0, bottom: 50.0, left: 24.0, right: 24.0, child: newChild);
break;
case ToastGravity.CENTER_LEFT:
return Positioned(top: 50.0, bottom: 50.0, left: 24.0, child: newChild);
break;
case ToastGravity.CENTER_RIGHT:
return Positioned(top: 50.0, bottom: 50.0, right: 24.0, child: newChild);
break;
case ToastGravity.BOTTOM_LEFT:
return Positioned(bottom: 50.0, left: 24.0, child: newChild);
break;
case ToastGravity.BOTTOM_RIGHT:
return Positioned(bottom: 50.0, right: 24.0, child: newChild);
break;
case ToastGravity.BOTTOM:
default:
return Positioned(bottom: 50.0, left: 24.0, right: 24.0, child: newChild);
}
}
}
class _ToastEntry {
final OverlayEntry entry;
final Duration duration;
_ToastEntry({this.entry, this.duration});
}
import 'dart:async';
import 'dart:html' as html;
import 'dart:ui' as ui;
import 'dart:js' as js;
import 'package:flutter/services.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
class FlutterToastWebPlugin {
FlutterToastWebPlugin() {
injectCssAndJSLibraries();
}
static void registerWith(Registrar registrar) {
final MethodChannel channel = MethodChannel('PonnamKarthik/fluttertoast', const StandardMethodCodec(), registrar.messenger);
final FlutterToastWebPlugin instance = FlutterToastWebPlugin();
channel.setMethodCallHandler(instance.handleMethodCall);
}
Future<dynamic> handleMethodCall(MethodCall call) async {
switch (call.method) {
case 'showToast':
showToast(call.arguments);
return true;
default:
throw PlatformException(
code: 'Unimplemented',
details: "The fluttertoast plugin for web doesn't implement "
"the method '${call.method}'");
}
}
Future<void> showToast(args) {
String msg = args['msg'];
String gravity = "top";
if (args['gravity'] == "top" || args['gravity'] == "bottom") {
gravity = args["gravity"];
}
String position = args['webPosition'] ?? 'right';
String bgColor = args['webBgColor'] ?? "linear-gradient(to right, #00b09b, #96c93d)";
int time = args['time'] == null ? 3000 : (int.parse(args['time'].toString()) * 1000);
bool showClose = args['webShowClose'] ?? false;
addHtmlToast(msg: msg, gravity: gravity, position: position, bgcolor: bgColor, showClose: showClose, time: time);
}
Future<void> injectCssAndJSLibraries() async {
final List<Future<void>> loading = <Future<void>>[];
final List<html.HtmlElement> tags = <html.HtmlElement>[];
final html.StyleElement css = html.StyleElement()
..id = 'toast-css'
..appendText("@import url('https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css');");
tags.add(css);
final html.ScriptElement script = html.ScriptElement()
..async = true
..defer = true
..src = "https://cdn.jsdelivr.net/npm/toastify-js";
loading.add(script.onLoad.first);
tags.add(script);
html.querySelector('head').children.addAll(tags);
await Future.wait(loading);
}
addHtmlToast(
{String msg = "",
String gravity = "top",
String position = "right",
String bgcolor = "linear-gradient(to right, #00b09b, #96c93d)",
int time = 3000,
bool showClose = false}) {
print(html.querySelector("#toast-content"));
html.Element ele = html.querySelector("#toast-content");
String content = """
var toastElement = Toastify({
text: '$msg',
gravity: '$gravity',
position: '$position',
duration: $time,
close: $showClose,
backgroundColor: "$bgcolor",
});
toastElement.showToast();
""";
if (html.querySelector("#toast-content") != null) {
ele.remove();
}
final html.ScriptElement scriptText = html.ScriptElement()
..id = "toast-content"
..innerHtml = content;
html.querySelector('head').children.add(scriptText);
}
}
......@@ -13,11 +13,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
meta:
dependency: transitive
description:
......
......@@ -2,6 +2,7 @@ name: fluttertoast
description: Toast Library for Flutter, Easily create toast messages in single line of code
version: 5.0.1
homepage: https://github.com/PonnamKarthik/FlutterToast
issue_tracker: https://github.com/ponnamkarthik/FlutterToast/issues
environment:
sdk: ">=2.7.0 <3.0.0"
......@@ -9,18 +10,4 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_web_plugins:
sdk: flutter
flutter:
plugin:
platforms:
android:
package: io.github.ponnamkarthik.toast.fluttertoast
pluginClass: FlutterToastPlugin
ios:
pluginClass: FluttertoastPlugin
web:
pluginClass: FluttertoastWebPlugin
fileName: fluttertoast_web.dart
\ No newline at end of file
sdk: flutter
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment