MAUI Android 自定义弹窗

MAUI Android 自定义弹窗
  MAUI在Android平台自定义弹窗教程。
        

  一、定义一个DialogCustomer.cs

1  public partial class DialogCustomer
2     {
3         public partial Task<bool> CustomerAlertAsync(string title, string subTitle, string confirmMsg = "OK", string cancelMsg = "", string subTitle2 = "", string img = "", string textAlignment = "Center", int imgWidth = 0, int imgHeight = 0);
4     }
View Code

  二、在Platforms/Android下定义一个DialogCustorer.cs

  1 public partial class DialogCustomer
  2     {
  3         public partial Task<bool> CustomerAlertAsync(string title, string subTitle, string confirmMsg = "OK", string cancelMsg = "", string subTitle2 = "", string img = "", string textAlignment = "Center", int imgWidth = 0, int imgHeight = 0)
  4         {
  5             try
  6             {
  7                 var tcs = new TaskCompletionSource<bool>();
  8                 var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
  9                 var density = mainDisplayInfo.Density;
 10 
 11                 //Activity activity = (Activity)Android.App.Application.Context;
 12                 //Android.App.Application.Context
 13                 Activity activity = (Activity)MainActivity.Instance;
 14                 Display display = activity.WindowManager.DefaultDisplay;
 15 
 16                 // 获取Dialog布局
 17                 Android.Views.View view = LayoutInflater.From(activity).Inflate(Resource.Layout.customerConfirmAlert, null);
 18 
 19                 // 获取自定义Dialog布局中的控件
 20                 var layDialogWrap = view.FindViewById<LinearLayout>(Resource.Id.custom_confirmdialog_wrap);
 21 
 22                 Dialog myDialog = new Dialog(activity, Resource.Style.AlertDialogStyle);
 23                 //设置点击Dialog外部任意区域不能关闭Dialog
 24                 myDialog.SetCanceledOnTouchOutside(false);
 25                 //设置自定义弹出框内容
 26                 myDialog.SetContentView(view);
 27 
 28                 if (Device.Idiom == TargetIdiom.Tablet)
 29                 {
 30                     layDialogWrap.LayoutParameters = new FrameLayout.LayoutParams((int)(activity.WindowManager.DefaultDisplay.Width * 0.64), ViewGroup.LayoutParams.WrapContent);
 31                 }
 32                 else
 33                 {
 34                     layDialogWrap.LayoutParameters = new FrameLayout.LayoutParams((int)(activity.WindowManager.DefaultDisplay.Width * 0.94), ViewGroup.LayoutParams.WrapContent);
 35                 }
 36 
 37                 var btnClose = view.FindViewById<Android.Widget.Button>(Resource.Id.custom_confirmdialog_close);
 38                 btnClose.SetTextColor(GetBlackBtnBackgroundColor());
 39                 btnClose.Click += (s, e) =>
 40                 {
 41                     myDialog.Dismiss();
 42                     tcs.SetResult(false);
 43                 };
 44 
 45                 //弹出框标题
 46                 var tvTitle = view.FindViewById<TextView>(Resource.Id.custom_confirmdialog_title);
 47                 //SetAndroidTextViewFontFamily(tvTitle, true);
 48                 tvTitle.Text = title;
 49                 if (string.IsNullOrEmpty(title))
 50                 {
 51                     tvTitle.Visibility = ViewStates.Gone;
 52                 }
 53 
 54                 //弹出框副标题
 55                 var tvSubtitle2 = view.FindViewById<TextView>(Resource.Id.custom_confirmdialog_subtitle2);
 56                 //SetAndroidTextViewFontFamily(tvSubtitle2, false);
 57                 tvSubtitle2.Text = subTitle2;
 58                 if (string.IsNullOrEmpty(subTitle2))
 59                 {
 60                     tvSubtitle2.Visibility = ViewStates.Gone;
 61                 }
 62                 switch (textAlignment)
 63                 {
 64                     case "Left":
 65                         tvSubtitle2.TextAlignment = Android.Views.TextAlignment.TextStart;
 66                         tvSubtitle2.Gravity = GravityFlags.Left;
 67                         break;
 68                     case "Right":
 69                         tvSubtitle2.TextAlignment = Android.Views.TextAlignment.TextEnd;
 70                         tvSubtitle2.Gravity = GravityFlags.Right;
 71                         break;
 72                     default:
 73                         tvSubtitle2.TextAlignment = Android.Views.TextAlignment.Center;
 74                         break;
 75                 }
 76 
 77                 var imgView = view.FindViewById<ImageView>(Resource.Id.custom_confirmdialog_img);
 78                 if (string.IsNullOrEmpty(img))
 79                 {
 80                     imgView.Visibility = ViewStates.Gone;
 81                 }
 82                 else
 83                 {
 84                     setimg(activity, imgView, img);
 85                     if (imgWidth > 0 && imgHeight > 0)
 86                     {
 87                         var imgX = (display.Width - 16 * (int)density - imgWidth * (int)density) / 2;
 88                         if (Device.Idiom == TargetIdiom.Tablet)
 89                         {
 90                             imgX = (int)((display.Width * 0.64) - 16 * (int)density - imgWidth * (int)density) / 2;
 91                         }
 92 
 93                         imgView.LayoutParameters = new LinearLayout.LayoutParams(imgWidth * (int)density, imgHeight * (int)density);
 94                         var imagelp = (LinearLayout.LayoutParams)imgView.LayoutParameters;
 95                         imagelp.SetMargins(imgX, 0, 22, 24 * (int)density);
 96                     }
 97 
 98                     //imgView.SetImageBitmap(imgBitmap);
 99                     //imgView.SetImageResource(Resource.Drawable.GW_close_eye);
100                     //imgView.SetImageURI(Android.Net.Uri.FromFile(new Java.IO.File(img)));
101                 }
102 
103                 //弹出框副标题
104                 var tvSubtitle = view.FindViewById<TextView>(Resource.Id.custom_confirmdialog_subtitle);
105                 //SetAndroidTextViewFontFamily(tvSubtitle, false);
106                 tvSubtitle.Text = subTitle;
107                 if (string.IsNullOrEmpty(subTitle))
108                 {
109                     tvSubtitle.Visibility = ViewStates.Gone;
110                 }
111                 switch (textAlignment)
112                 {
113                     case "Left":
114                         tvSubtitle.TextAlignment = Android.Views.TextAlignment.TextStart;
115                         tvSubtitle.Gravity = GravityFlags.Left;
116                         break;
117                     case "Right":
118                         tvSubtitle.TextAlignment = Android.Views.TextAlignment.TextEnd;
119                         tvSubtitle.Gravity = GravityFlags.Right;
120                         break;
121                     default:
122                         tvSubtitle.TextAlignment = Android.Views.TextAlignment.Center;
123                         break;
124                 }
125 
126 
127                 //display.Height-
128                 var tvScrollView = view.FindViewById<MaxHeightScrollView>(Resource.Id.custom_confirmdialog_scroll);
129                 tvScrollView.maxHeight = display.Height - (tvTitle.LineHeight + 300) * 2;
130 
131                 //确定按钮
132                 var btnOk = view.FindViewById<Android.Widget.Button>(Resource.Id.custom_confirmdialog_okbtn);
133                 SetBlackBtnBg(btnOk);
134                 btnOk.Text = confirmMsg == "OK" ? AppLanguage.OK : confirmMsg;
135                 btnOk.Click += (s, e) =>
136                 {
137                     myDialog.Dismiss();
138                     tcs.SetResult(true);
139                 };
140 
141                 //取消按键
142                 var btnCancel = (Android.Widget.Button)view.FindViewById(Resource.Id.custom_confirmdialog_canclebtn);
143                 SetWhiteBtnBg(btnCancel);
144                 btnCancel.Text = cancelMsg;
145                 btnCancel.Click += (s, e) =>
146                 {
147                     myDialog.Dismiss();
148                     tcs.SetResult(false);
149                 };
150 
151                 var btnComfirm = view.FindViewById<Android.Widget.Button>(Resource.Id.custom_confirmdialog_comfirmbtn);
152                 SetBlackBtnBg(btnComfirm);
153                 btnComfirm.Text = confirmMsg == "OK" ? AppLanguage.OK : confirmMsg;
154                 btnComfirm.Click += (s, e) =>
155                 {
156                     myDialog.Dismiss();
157                     tcs.SetResult(true);
158                 };
159 
160                 if (string.IsNullOrEmpty(cancelMsg))
161                 {
162                     btnOk.Visibility = ViewStates.Visible;
163                     btnCancel.Visibility = ViewStates.Gone;
164                     btnComfirm.Visibility = ViewStates.Gone;
165                 }
166                 else
167                 {
168                     btnOk.Visibility = ViewStates.Gone;
169                     btnCancel.Visibility = ViewStates.Visible;
170                     btnComfirm.Visibility = ViewStates.Visible;
171                 }
172 
173                 //显示弹出框
174                 myDialog.Show();
175 
176                 return tcs.Task;
177             }
178             catch (Exception ex)
179             {
180                 return null;
181             }
182         }
183 
184         private async void setimg(Activity activity, ImageView imageView, string imgUrl)
185         {
186             FileImageSource fileImageSource = (FileImageSource)ImageSource.FromFile(imgUrl);
187             var imgBitmap = await ImageHelper.GetBitmapFromImageSourceAsync(fileImageSource, activity);
188             imageView.SetImageBitmap(imgBitmap);
189         }
190 
191         private void SetAndroidTextViewFontFamily(Android.Widget.TextView textView, bool isBlod = false, AlertElementFontStyle alertElementFontStyle = AlertElementFontStyle.Normol)
192         {
193             //var context = Android.App.Application.Context;
194             var context = MainActivity.Instance;
195             AssetManager assetManager = context.Assets;
196             Typeface face = null;
197             if (isBlod)
198             {
199                 face = Typeface.CreateFromAsset(assetManager, "SFProDisplay-Bold.ttf");
200             }
201             else
202             {
203                 face = Typeface.CreateFromAsset(assetManager, "SFProDisplay-Regular.ttf");
204                 switch (alertElementFontStyle)
205                 {
206                     case AlertElementFontStyle.Normol:
207                         face = Typeface.CreateFromAsset(assetManager, "SFProDisplay-Regular.ttf");
208                         break;
209                     case AlertElementFontStyle.Bold:
210                         face = Typeface.CreateFromAsset(assetManager, "SFProDisplay-Bold.ttf");
211                         break;
212                     case AlertElementFontStyle.Italic:
213                         face = Typeface.Create(Typeface.SansSerif, TypefaceStyle.Italic);
214                         break;
215                     default:
216                         break;
217                 }
218             }
219             textView.Typeface = face;
220         }
221 
222         private void SetAndroidButtonFontFamily(Android.Widget.Button button, bool isBlod = false)
223         {
224             //var context = Android.App.Application.Context;
225             var context = MainActivity.Instance;
226             AssetManager assetManager = context.Assets;
227             Typeface face = null;
228             if (isBlod)
229             {
230                 face = Typeface.CreateFromAsset(assetManager, "SFProDisplay-Bold.ttf");
231             }
232             else
233             {
234                 face = Typeface.CreateFromAsset(assetManager, "SFProDisplay-Regular.ttf");
235             }
236             button.Typeface = face;
237         }
238 
239         //private SpannableString GetHigHLightSpannableString(PartColorText[] partColorTexts, string text)
240         //{
241         //    var spannableString = new SpannableString(text);
242         //    foreach (var partColorText in partColorTexts)
243         //    {
244         //        //1. Method1
245         //        //Java.Util.Regex.Pattern pattern = Java.Util.Regex.Pattern.Compile(partColorText.AlertText);
246         //        //Matcher matcher = pattern.Matcher(text);
247         //        //while (matcher.Find())
248         //        //{
249         //        //    Android.Text.Style.ForegroundColorSpan span = new Android.Text.Style.ForegroundColorSpan(Xamarin.Forms.Color.FromHex(partColorText.AlertColor).ToAndroid());
250         //        //    spannableString.SetSpan(span, matcher.Start() - 0, matcher.End() + 0, SpanTypes.ExclusiveExclusive);
251         //        //}
252         //        //1. Method2
253         //        var span = new Android.Text.Style.ForegroundColorSpan(Xamarin.Forms.Color.FromHex(partColorText.AlertColor).ToAndroid());
254         //        spannableString.SetSpan(span, partColorText.Index, partColorText.Index + partColorText.AlertText.Length, SpanTypes.ExclusiveExclusive);
255         //    }
256         //    return spannableString;
257         //}
258 
259         private Android.Graphics.Color GetBlackBtnBackgroundColor()
260         {
261             
262             return Android.Graphics.Color.Rgb(254, 254, 254);
263         }
264 
265         private void SetBlackBtnBg(Android.Widget.Button button)
266         {
267 
268             //button.SetBackgroundResource(Resource.Drawable.setbar_black_btn_bg);
269             //button.SetBackgroundColor(GetBlackBtnBackgroundColor());
270         }
271 
272         private void SetWhiteBtnBg(Android.Widget.Button button)
273         {
274 
275             //button.SetBackgroundResource(Resource.Drawable.setbar_white_btn_bg);
276             //button.SetBackgroundColor(GetBlackBtnBackgroundColor());
277         }
278 
279         private Android.Widget.Button CreateBlackBtn(Activity activity)
280         {
281 
282             return (Android.Widget.Button)LayoutInflater.From(activity).Inflate(Resource.Layout.customerButtonBlack, null);
283 
284         }
285 
286         private Android.Widget.Button CreateWhiteBtn(Activity activity)
287         {
288             return (Android.Widget.Button)LayoutInflater.From(activity).Inflate(Resource.Layout.customerButtonWhite, null);
289         }
290 
291     }
292 
293     public static class ImageHelper
294     {
295         public static IImageSourceHandler GetHandler(this ImageSource source)
296         {
297             //Image source handler to return 
298             IImageSourceHandler returnValue = null;
299             //check the specific source type and return the correct image source handler 
300             if (source is UriImageSource)
301             {
302                 returnValue = new ImageLoaderSourceHandler();
303             }
304             else if (source is FileImageSource)
305             {
306                 returnValue = new FileImageSourceHandler();
307             }
308             else if (source is StreamImageSource)
309             {
310                 returnValue = new StreamImagesourceHandler();
311             }
312             return returnValue;
313         }
314 
315         public static async Task<Bitmap> GetBitmapFromImageSourceAsync(ImageSource source, Context context)
316         {
317             var handler = GetHandler(source);
318             var returnValue = (Bitmap)null;
319             returnValue = await handler.LoadImageAsync(source, context);
320             return returnValue;
321         }
322     }
323 
324     public class BrandColorHelper
325     {
326 
327         public const string POWERWORKS = "POWERWORKS";
328         public const string GREENWORKS = "GREENWORKS";
329         public const string CRAMER = "CRAMER";
330         public const string ZTR = "ZTR";
331         public const string DEVELOPER = "DEVELOPER";
332 
333         public static string GetBrand()
334         {
335 #if GREENWORKS
336             return GREENWORKS;
337 #elif POWERWORKS
338             return POWERWORKS;
339 #elif CRAMER
340             return CRAMER;
341 #elif ZTR
342             return ZTR;
343 #else //DEVELOPER
344             return DEVELOPER;
345 #endif
346         }
347     }
348 
349     public class MaxHeightScrollView : Android.Widget.ScrollView
350     {
351         public int maxHeight;
352         protected Context _context;
353         public MaxHeightScrollView(Context context) : base(context)
354         {
355             //base(context, null);
356         }
357         public MaxHeightScrollView(Context context, Android.Util.IAttributeSet attrs) : base(context, attrs)
358         {
359             _context = context;
360             //base.(context, attrs, defStyleAttr);
361             initialize(context, attrs);
362         }
363         public MaxHeightScrollView(Context context, Android.Util.IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
364         {
365             _context = context;
366             //base.(context, attrs, defStyleAttr);
367             initialize(context, attrs);
368         }
369 
370         private void initialize(Context context, Android.Util.IAttributeSet attrs)
371         {
372             Android.Content.Res.TypedArray typedArray = context.ObtainStyledAttributes(attrs, Resource.Styleable.MaxHeightScrollView);
373             maxHeight = typedArray.GetLayoutDimension(Resource.Styleable.MaxHeightScrollView_maxHeight, maxHeight);
374             typedArray.Recycle();
375         }
376 
377         protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
378         {
379             try
380             {
381                 //Display display = ((Activity)_context).WindowManager.DefaultDisplay;
382                 //heightMeasureSpec = display.Height - 200;
383 
384                 heightMeasureSpec = MeasureSpec.MakeMeasureSpec(maxHeight, MeasureSpecMode.AtMost);
385             }
386             catch (Exception ex)
387             {
388 
389             }
390             base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
391         }
392 
393     }
View Code

  三、在Platforms/Android/Resources/layout下添加一个customerConfirmAlert.xml

  1 <?xml version="1.0" encoding="UTF-8" ?>
  2     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3     android:id="@+id/custom_confirmdialog_wrap"
  4     xmlns:app="http://schemas.android.com/apk/res-auto"
  5     android:orientation="vertical"
  6     android:layout_width="match_parent"
  7     android:layout_height="wrap_content"
  8     android:background="@drawable/setbar_warp_bg">
  9     <LinearLayout
 10         android:layout_width="match_parent"
 11         android:layout_height="50dp"
 12         android:orientation="horizontal">
 13         <View
 14             android:layout_width="wrap_content"
 15             android:layout_height="50dp"
 16             android:layout_weight="1"/>
 17         <Button
 18             android:id="@+id/custom_confirmdialog_close"
 19             android:layout_width="22dp"
 20             android:layout_height="22dp"
 21             android:layout_weight="0"
 22             android:layout_marginTop="20dp"
 23             android:layout_marginRight="16dp"
 24             android:background="@drawable/gw_alert_close"/>
 25     </LinearLayout>
 26     <TextView
 27         android:id="@+id/custom_confirmdialog_title"
 28         android:layout_width="match_parent"
 29         android:layout_height="wrap_content"
 30         android:layout_marginTop="20dp"
 31         android:layout_marginBottom="32dp"
 32         android:layout_margin="22dp"
 33         android:gravity="center"
 34         android:textSize="24sp"
 35         android:textColor="@color/black"
 36         android:textStyle="bold"
 37         android:text="@string/pin_title"/>
 38     <GLBMaui.DenpendencyServices.MaxHeightScrollView
 39         android:id="@+id/custom_confirmdialog_scroll"
 40         android:layout_width="match_parent"
 41         android:layout_height="wrap_content"
 42         android:fillViewport ="true"
 43         android:overScrollMode="never"
 44         android:scrollbars="vertical"
 45         app:maxHeight="300dp"
 46         >
 47         <LinearLayout
 48             android:layout_width="match_parent"
 49             android:layout_height="wrap_content"
 50             android:orientation="vertical">
 51             <TextView
 52                 android:id="@+id/custom_confirmdialog_subtitle2"
 53                 android:layout_width="match_parent"
 54                 android:layout_height="wrap_content"
 55                 android:layout_marginLeft="12dp"
 56                 android:layout_marginRight="12dp"
 57                 android:layout_marginTop="0dp"
 58                 android:layout_marginBottom="2dp"
 59                 android:gravity="center"
 60                 android:textSize="16sp"
 61                 android:textColor="@color/black"
 62                 android:text="@string/pin_subtitle"/>
 63             <ImageView
 64                 android:id="@+id/custom_confirmdialog_img"
 65                 android:layout_width="wrap_content"
 66                 android:layout_height="wrap_content"
 67                 android:layout_marginBottom="24dp"
 68                 android:layout_gravity="center"
 69                 android:contentDescription=""
 70                 android:src="@drawable/gw_open_eye"/>
 71             <TextView
 72                 android:id="@+id/custom_confirmdialog_subtitle"
 73                 android:layout_width="match_parent"
 74                 android:layout_height="wrap_content"
 75                 android:layout_marginLeft="12dp"
 76                 android:layout_marginRight="12dp"
 77                 android:layout_marginTop="0dp"
 78                 android:layout_marginBottom="34dp"
 79                 android:gravity="center"
 80                 android:textSize="16sp"
 81                 android:textColor="@color/black"
 82                 android:text="@string/pin_tips"/>
 83         </LinearLayout>
 84      </GLBMaui.DenpendencyServices.MaxHeightScrollView>
 85     
 86     <Button
 87         android:id="@+id/custom_confirmdialog_okbtn"
 88         android:layout_width="match_parent"
 89         android:layout_height="match_parent"
 90         android:height="55dp"
 91         android:layout_marginRight="12dp"
 92         android:layout_marginLeft="12dp"
 93         android:layout_marginBottom="24dp"
 94         android:gravity="center"
 95         android:background="@drawable/setbar_black_btn_bg"
 96         android:textColor="@android:color/white"
 97         android:textSize="16sp"
 98         android:textStyle="normal"
 99         />
100     <LinearLayout
101         android:layout_width="match_parent"
102         android:layout_height="match_parent"
103         android:orientation="horizontal">
104         <Button
105             android:id="@+id/custom_confirmdialog_canclebtn"
106             android:layout_width="wrap_content"
107             android:layout_height="match_parent"
108             android:layout_weight="1"
109             android:height="55dp"
110             android:layout_marginRight="6dp"
111             android:layout_marginLeft="12dp"
112             android:layout_marginBottom="24dp"
113             android:gravity="center"
114             android:background="@drawable/setbar_white_btn_bg"
115             android:backgroundTint="#FFFFFF"
116             android:textColor="@color/color_btn_black"
117             android:textSize="16sp"
118             android:textStyle="normal"
119         />
120         <Button
121             android:id="@+id/custom_confirmdialog_comfirmbtn"
122             android:layout_width="wrap_content"
123             android:layout_height="match_parent"
124             android:layout_weight="1"
125             android:height="55dp"
126             android:layout_marginRight="12dp"
127             android:layout_marginLeft="6dp"
128             android:layout_marginBottom="24dp"
129             android:gravity="center"
130             android:background="@drawable/setbar_black_btn_bg"
131             android:textColor="@android:color/white"
132             android:textSize="16sp"
133             android:textStyle="normal"
134         />
135         </LinearLayout>
136     
137 
138 </LinearLayout>
View Code

  四、在页面上使用这个弹窗

1 MainThread.BeginInvokeOnMainThread(async () =>
2         {
3             var res = await new DialogCustomer().CustomerAlertAsync("title", "在 .NET 多平台应用 UI (.NET MAUI) 不提供任何用于访问特定平台 API 的 API 的情况下,可以编写自己的代码来访问所需的平台 API。 这需要了解 Apple 的 iOS 和 MacCatalyst API、 Google 的 Android API 和 Microsoft 的 Windows 应用 SDK API。在 .NET 多平台应用 UI (.NET MAUI) 不提供任何用于访问特定平台 API 的 API 的情况下,可以编写自己的代码来访问所需的平台 API。 这需要了解 Apple 的 iOS 和 MacCatalyst API、 Google 的 Android API 和 Microsoft 的 Windows 应用 SDK API。在 .NET 多平台应用 UI (.NET MAUI) 不提供任何用于访问特定平台 API 的 API 的情况下,可以编写自己的代码来访问所需的平台 API。 这需要了解 Apple 的 iOS 和 MacCatalyst API、 Google 的 Android API 和 Microsoft 的 Windows 应用 SDK API。", confirmMsg: "OK", cancelMsg: "cancel", img: "accept.png");
4         });
View Code

  参考GitHub URL:https://github.com/zuimengaitianya/GLBMaui,喜欢的给个star。后续将继续完善iOS平台代码。

 

posted @ 2022-08-29 13:45  醉梦ai天涯  阅读(925)  评论(0编辑  收藏  举报