ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MAUI Android 自定义弹窗

2022-08-29 14:05:04  阅读:366  来源: 互联网

标签:Resource string 自定义 var context MAUI Android public


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,喜欢的给个start。后续将继续完善iOS平台代码。

 

标签:Resource,string,自定义,var,context,MAUI,Android,public
来源: https://www.cnblogs.com/zuimengaitianya/p/16635699.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有