目录
- 1、说明
 - 2、代码如下
 - 2.1 图1的代码
 - 2.1.1、创建一个`Activity`或者`Fragment`,如下:
 - 2.1.2、创建`Layout`
 - 2.1.3、如何使用
 
- 2.2 图2的代码
 
- 4、其他补充
 - 4.1 C#与Java中的匿名类
 - 4.2 、其他知识点
 
- 5、参考资料
 
1、说明
在实际使用过程中,常常会用到点击按钮后,系统弹出加载中画面的需求,因此整理了一下Xamarin.Android中实现加载的功能,效果如下:
 
 
2、代码如下
2.1 图1的代码
2.1.1、创建一个Activity或者Fragment,如下:
 
public class BaseAcitivity : Activity, IDialogInterfaceOnKeyListener
{
    public Android.App.AlertDialog alertDialog;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    }
    //展示对话框
    public void showLoadingDialog()
    {
        alertDialog = new Android.App.AlertDialog.Builder(this).Create();;
        alertDialog.Window.SetBackgroundDrawable(new ColorDrawable());
        alertDialog.SetCancelable(false);
        alertDialog.SetOnKeyListener(this);
        alertDialog.Show();
        alertDialog.Window.SetLayout(300, 300);
        alertDialog.SetContentView(Resource.Layout.loading_alert);
        alertDialog.SetCanceledOnTouchOutside(false);
    }
    //退出对话框
    public void dismissLoadingDialog()
    {
        if (null != alertDialog && alertDialog.IsShowing)
        {
            alertDialog.Dismiss();
        }
    }
    //监听事件,主要是防止系统监听返回事件---悄无声息得把对话框给干没了
    public bool OnKey(IDialogInterface? dialog, [GeneratedEnum] Keycode keyCode, KeyEvent? e)
    {
        //这儿主要是防止系统监听搜索或返回事件,造成弹框被取消
        if (keyCode == Keycode.Search || keyCode == Keycode.Back)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
 
Fragment同理
public class BaseFragment : AndroidX.Fragment.App.Fragment, IDialogInterfaceOnKeyListener
{
    private Android.App.AlertDialog alertDialog;
    public void showLoadingDialog()
    {
        alertDialog = new Android.App.AlertDialog.Builder(this.Context).Create();;
        alertDialog.Window.SetBackgroundDrawable(new ColorDrawable());
        alertDialog.SetCancelable(false);
        alertDialog.SetOnKeyListener(this);
        alertDialog.Show();
        alertDialog.Window.SetLayout(300, 300);
        alertDialog.SetContentView(Resource.Layout.loading_alert);
        alertDialog.SetCanceledOnTouchOutside(false);
    }
    public void dismissLoadingDialog()
    {
        if (null != alertDialog && alertDialog.IsShowing)
        {
            alertDialog.Dismiss();
        }
    }
    public bool OnKey(IDialogInterface? dialog, [GeneratedEnum] Keycode keyCode, KeyEvent? e)
    {
        if (keyCode == Keycode.Search || keyCode == Keycode.Back)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
 
2.1.2、创建Layout
 
即Resource.Layout.loading_alert,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:background="#000">
    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_gravity="center_horizontal"
        style="@style/AppTheme.NoActionBar"
        />
    <TextView
        android:text="加载中..."
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white"
        android:id="@+id/textView1" />
</LinearLayout>
 
代码比较简单,只不过在ProgressBar用到了一个style,—AppTheme.NoActionBar。其代码如下:
<style name="AppTheme.NoActionBar">
		<item name="android:windowActionBar">false</item>
		<item name="android:windowNoTitle">true</item>
</style>
 
2.1.3、如何使用
创建一个新的Activity或者Fragment时,继承上面的两个基类
 例如:
public class MineFragment : BaseFragment
 
然后在子类中直接使用:
private void DataUpdateBtn_Click(object sender, EventArgs e)
{
    base.showLoadingDialog();
    Task.Factory.StartNew(() => {
        //同步字典数据
        //具体业务操作代码
        //TO-DO
        //关闭对话框
        base.dismissLoadingDialog();
    });
}
 
即可实现
2.2 图2的代码
相比较图1,图2在具体实现上基本没有差别,仅有的差别就是在Layout上,图2的Layout如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:layout_width="110dp"
    android:layout_height="110dp"
    android:background="@drawable/corners_bg"  <!--差别1:主要是实现了圆角-->
    android:gravity="center"
    android:orientation="vertical" >
    <ProgressBar
      android:id="@+id/progressBar1"
      android:layout_width="35dp"
      android:layout_height="35dp"
      android:layout_gravity="center_horizontal"
      android:indeterminateBehavior="cycle"
      android:indeterminateDrawable="@drawable/dialog_loading"   <!--差别2:使用了自定义的图片-->
      android:indeterminateOnly="true" />
    <TextView
      android:id="@+id/tipTextView"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="15dp"
      android:text="加载中..."
      android:textColor="#f0f0f0"
      android:textSize="15sp" />
  </LinearLayout>
 
corners_bg.xml定义如下:
 主要是实现圆角功能
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
	<solid android:color="#000" />
	<corners android:topLeftRadius="10dp"
			 android:topRightRadius="10dp"
			 android:bottomRightRadius="10dp"
			 android:bottomLeftRadius="10dp"/>
</shape>
 
dialog_loading.xml定义如下:
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@mipmap/loading"
    android:pivotX="50%"
    android:pivotY="50%" />
 
主要是使用了自定义的图片,以及图片旋转时的参数
4、其他补充
4.1 C#与Java中的匿名类
在网上的例子中,常常可以看到如下的代码:
alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
	 @Override
	 public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
	     if (keyCode == KeyEvent.KEYCODE_SEARCH || keyCode == KeyEvent.KEYCODE_BACK)
	         return true;
	     return false;
	 }
});
 
这是Java中常见的写法,在匿名类中实现方法。但这种方式无法在C#中实现,因为C#的匿名类中只能包含字段(field),C#的匿名类型是由一个或多个公共只读属性组成的类类型。 不允许包含其他种类的类成员(如方法或事件)。 匿名类型不能强制转换为除 object 以外的任何接口或类型。
官网的说明如下:
Anonymous types contain one or more public read-only properties. No other kinds of class members, such as methods or events, are valid.
It is also possible to define a field by object of another type: class, struct or even another anonymous type.
为啥Java可以,C#不可以呢。主要原因就是C#有委托(delegate)。 因此,在Java中,如果我们想实现事件机制或者传一个方法,一般是使用接口。那么定义一个类去实现接口是多么麻烦的事情。 你在Java中能看到大量的只有一个方法的接口,比如Runnable。 而C#已经有了匿名委托了,使用委托比使用接口更简单,没必要再画蛇添足了。 事实上Java饶了弯路,它们现在也开始支持Lambda表达式,而且还不得不出于兼容的考虑,创造了一个雌雄同体的怪异语法约定——那种只有一个方法的接口,可以用Lambda表达式表示
4.2 、其他知识点
在整个过程中,用到的知识就是ProgressBar和Handler接口
5、参考资料
1、Android最简单的LoadingDialog
 2、C# 匿名类












![[JavaWeb]SQL介绍-DDL-DML](https://img-blog.csdnimg.cn/05033827a41648daa359f62a65d01cfc.png#pic_center)

![[nlp] TF-IDF算法介绍](https://img-blog.csdnimg.cn/4e186ba8072d46ecac7be6eda9f882ba.png)




