44import android .graphics .drawable .GradientDrawable ;
55import android .os .Build ;
66import android .os .CountDownTimer ;
7+ import android .text .Html ;
78import android .text .Layout ;
89import android .text .Spannable ;
910import android .text .SpannableString ;
11+ import android .text .Spanned ;
1012import android .text .style .AlignmentSpan ;
1113import android .view .Gravity ;
1214import android .view .MotionEvent ;
@@ -36,7 +38,7 @@ public class Toast extends CordovaPlugin {
3638 private ViewGroup viewGroup ;
3739
3840 private static final boolean IS_AT_LEAST_LOLLIPOP = Build .VERSION .SDK_INT >= 21 ;
39- private static final boolean IS_AT_LEAST_PIE = Build .VERSION .SDK_INT >= 28 ;
41+ private static final boolean IS_AT_LEAST_ANDROID_11 = Build .VERSION .SDK_INT >= Build . VERSION_CODES . R ;
4042
4143 // note that webView.isPaused() is not Xwalk compatible, so tracking it poor-man style
4244 private boolean isPaused ;
@@ -59,23 +61,22 @@ public boolean execute(String action, JSONArray args, final CallbackContext call
5961 }
6062
6163 final JSONObject options = args .getJSONObject (0 );
62- final String msg = options .getString ("message" );
63- final Spannable message = new SpannableString (msg );
64- message .setSpan (
65- new AlignmentSpan .Standard (Layout .Alignment .ALIGN_CENTER ),
66- 0 ,
67- msg .length () - 1 ,
68- Spannable .SPAN_INCLUSIVE_INCLUSIVE );
69-
7064 final String duration = options .getString ("duration" );
7165 final String position = options .getString ("position" );
7266 final int addPixelsY = options .has ("addPixelsY" ) ? options .getInt ("addPixelsY" ) : 0 ;
7367 final JSONObject data = options .has ("data" ) ? options .getJSONObject ("data" ) : null ;
74- final JSONObject styling = options .optJSONObject ("styling" );
75-
68+ JSONObject styling = options .optJSONObject ("styling" );
69+ final String msg = options . getString ( "message" );
7670 currentMessage = msg ;
7771 currentData = data ;
7872
73+ String _msg = msg ;
74+ if (styling != null ){
75+ final String textColor = styling .optString ("textColor" , "#000000" );
76+ _msg = "<font color='" +textColor +"' ><b>" + _msg + "</b></font>" ;
77+ }
78+ final String html = _msg ;
79+
7980 cordova .getActivity ().runOnUiThread (new Runnable () {
8081 public void run () {
8182 int hideAfterMs ;
@@ -87,10 +88,20 @@ public void run() {
8788 // assuming a number of ms
8889 hideAfterMs = Integer .parseInt (duration );
8990 }
91+
92+ Spanned message ;
93+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N ) {
94+ // FROM_HTML_MODE_LEGACY is the behaviour that was used for versions below android N
95+ // we are using this flag to give a consistent behaviour
96+ message = Html .fromHtml (html , Html .FROM_HTML_MODE_LEGACY );
97+ } else {
98+ message = Html .fromHtml (html );
99+ }
100+
90101 final android .widget .Toast toast = android .widget .Toast .makeText (
91- IS_AT_LEAST_LOLLIPOP ? cordova .getActivity ().getWindow ().getContext () : cordova .getActivity ().getApplicationContext (),
92- message ,
93- "short" .equalsIgnoreCase (duration ) ? android .widget .Toast .LENGTH_SHORT : android .widget .Toast .LENGTH_LONG
102+ IS_AT_LEAST_LOLLIPOP ? cordova .getActivity ().getWindow ().getContext () : cordova .getActivity ().getApplicationContext (),
103+ message ,
104+ "short" .equalsIgnoreCase (duration ) ? android .widget .Toast .LENGTH_SHORT : android .widget .Toast .LENGTH_LONG
94105 );
95106
96107 if ("top" .equals (position )) {
@@ -104,85 +115,62 @@ public void run() {
104115 return ;
105116 }
106117
107- // if one of the custom layout options have been passed in, draw our own shape
108- if (styling != null && Build .VERSION .SDK_INT >= 16 ) {
109-
110- // the defaults mimic the default toast as close as possible
111- final String backgroundColor = styling .optString ("backgroundColor" , "#333333" );
112- final String textColor = styling .optString ("textColor" , "#ffffff" );
113- final Double textSize = styling .optDouble ("textSize" , -1 );
114- final double opacity = styling .optDouble ("opacity" , 0.8 );
115- final int cornerRadius = styling .optInt ("cornerRadius" , 100 );
116- final int horizontalPadding = styling .optInt ("horizontalPadding" , 50 );
117- final int verticalPadding = styling .optInt ("verticalPadding" , 30 );
118-
119- GradientDrawable shape = new GradientDrawable ();
120- shape .setCornerRadius (cornerRadius );
121- shape .setAlpha ((int )(opacity * 255 )); // 0-255, where 0 is an invisible background
122- shape .setColor (Color .parseColor (backgroundColor ));
123- toast .getView ().setBackground (shape );
124-
125- final TextView toastTextView ;
126- toastTextView = (TextView ) toast .getView ().findViewById (android .R .id .message );
127- toastTextView .setTextColor (Color .parseColor (textColor ));
128- if (textSize > -1 ) {
129- toastTextView .setTextSize (textSize .floatValue ());
130- }
131-
132- toast .getView ().setPadding (horizontalPadding , verticalPadding , horizontalPadding , verticalPadding );
133-
134- // this gives the toast a very subtle shadow on newer devices
135- if (Build .VERSION .SDK_INT >= 21 ) {
136- toast .getView ().setElevation (6 );
137- }
138- }
139-
140118 // On Android >= 5 you can no longer rely on the 'toast.getView().setOnTouchListener',
141119 // so created something funky that compares the Toast position to the tap coordinates.
142120 if (IS_AT_LEAST_LOLLIPOP ) {
143- getViewGroup ().setOnTouchListener (new View .OnTouchListener () {
144- @ Override
145- public boolean onTouch (View view , MotionEvent motionEvent ) {
146- if (motionEvent .getAction () != MotionEvent .ACTION_DOWN ) {
147- return false ;
148- }
149- if (mostRecentToast == null || !mostRecentToast .getView ().isShown ()) {
150- getViewGroup ().setOnTouchListener (null );
151- return false ;
121+ if (IS_AT_LEAST_ANDROID_11 ) {
122+ toast .addCallback (new android .widget .Toast .Callback (){
123+ public void onToastShown () {}
124+ public void onToastHidden () {
125+ returnTapEvent ("hide" , msg , data , callbackContext );
152126 }
153-
154- float w = mostRecentToast .getView ().getWidth ();
155- float startX = (view .getWidth () / 2 ) - (w / 2 );
156- float endX = (view .getWidth () / 2 ) + (w / 2 );
157-
158- float startY ;
159- float endY ;
160-
161- float g = mostRecentToast .getGravity ();
162- float y = mostRecentToast .getYOffset ();
163- float h = mostRecentToast .getView ().getHeight ();
164-
165- if (g == GRAVITY_BOTTOM ) {
166- startY = view .getHeight () - y - h ;
167- endY = view .getHeight () - y ;
168- } else if (g == GRAVITY_CENTER ) {
169- startY = (view .getHeight () / 2 ) + y - (h / 2 );
170- endY = (view .getHeight () / 2 ) + y + (h / 2 );
171- } else {
172- // top
173- startY = y ;
174- endY = y + h ;
127+ });
128+ } else {
129+ getViewGroup ().setOnTouchListener (new View .OnTouchListener () {
130+ @ Override
131+ public boolean onTouch (View view , MotionEvent motionEvent ) {
132+ if (motionEvent .getAction () != MotionEvent .ACTION_DOWN ) {
133+ return false ;
134+ }
135+ if (mostRecentToast == null || !mostRecentToast .getView ().isShown ()) {
136+ getViewGroup ().setOnTouchListener (null );
137+ return false ;
138+ }
139+
140+ float w = mostRecentToast .getView ().getWidth ();
141+ float startX = (view .getWidth () / 2 ) - (w / 2 );
142+ float endX = (view .getWidth () / 2 ) + (w / 2 );
143+
144+ float startY ;
145+ float endY ;
146+
147+ float g = mostRecentToast .getGravity ();
148+ float y = mostRecentToast .getYOffset ();
149+ float h = mostRecentToast .getView ().getHeight ();
150+
151+ if (g == GRAVITY_BOTTOM ) {
152+ startY = view .getHeight () - y - h ;
153+ endY = view .getHeight () - y ;
154+ } else if (g == GRAVITY_CENTER ) {
155+ startY = (view .getHeight () / 2 ) + y - (h / 2 );
156+ endY = (view .getHeight () / 2 ) + y + (h / 2 );
157+ } else {
158+ // top
159+ startY = y ;
160+ endY = y + h ;
161+ }
162+
163+ float tapX = motionEvent .getX ();
164+ float tapY = motionEvent .getY ();
165+
166+ final boolean tapped = tapX >= startX && tapX <= endX &&
167+ tapY >= startY && tapY <= endY ;
168+
169+ return tapped && returnTapEvent ("touch" , msg , data , callbackContext );
175170 }
171+ });
172+ }
176173
177- float tapX = motionEvent .getX ();
178- float tapY = motionEvent .getY ();
179-
180- final boolean tapped = tapX >= startX && tapX <= endX &&
181- tapY >= startY && tapY <= endY ;
182-
183- return tapped && returnTapEvent ("touch" , msg , data , callbackContext );
184- }
185- });
186174 } else {
187175 toast .getView ().setOnTouchListener (new View .OnTouchListener () {
188176 @ Override
@@ -265,3 +253,4 @@ public void onResume(boolean multitasking) {
265253 this .isPaused = false ;
266254 }
267255}
256+
0 commit comments