Floating Windows are implemented primarily through the WindowsManager class.
Here is a simple sample you could refer to.
Create a FloatingService :
[Service]
class FloatingService : Service,Android.Views.View.IOnTouchListener
{
WindowManagerLayoutParams layoutParams;
IWindowManager windowManager;
View floatView;
public override void OnCreate()
{
base.OnCreate();
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
showFloatingWindow();
return StartCommandResult.NotSticky;
}
public override IBinder OnBind(Intent intent)
{
return null;
}
private void showFloatingWindow()
{
windowManager = GetSystemService(WindowService).JavaCast<IWindowManager>();
LayoutInflater mLayoutInflater = LayoutInflater.From(ApplicationContext);
floatView = mLayoutInflater.Inflate(Resource.Layout.floatview, null);
floatView.SetBackgroundColor(Android.Graphics.Color.Transparent);
floatView.SetOnTouchListener(this);
ImageView iv1 = floatView.FindViewById<ImageView>(Resource.Id.iv1);
ImageView iv2 = floatView.FindViewById<ImageView>(Resource.Id.iv2);
ImageView iv3 = floatView.FindViewById<ImageView>(Resource.Id.iv3);
iv1.Click += delegate { Toast.MakeText(ApplicationContext, "The first Image Click", ToastLength.Short).Show(); };
iv2.Click += delegate { Toast.MakeText(ApplicationContext, "The second Image Click", ToastLength.Short).Show(); };
iv3.Click += delegate { Toast.MakeText(ApplicationContext, "The third Image Click", ToastLength.Short).Show(); };
// set LayoutParam
layoutParams = new WindowManagerLayoutParams();
if (Build.VERSION.SdkInt >= Build.VERSION_CODES.O)
{
layoutParams.Type = WindowManagerTypes.ApplicationOverlay;
}
else
{
layoutParams.Type = WindowManagerTypes.Phone;
}
layoutParams.Flags = WindowManagerFlags.NotTouchModal;
layoutParams.Flags = WindowManagerFlags.NotFocusable;
layoutParams.Width = 400;
layoutParams.Height = 100;
layoutParams.X = 300;
layoutParams.Y = 300;
windowManager.AddView(floatView, layoutParams);
}
private int x;
private int y;
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
x = (int)e.RawX;
y = (int)e.RawY;
break;
case MotionEventActions.Move:
int nowX = (int) e.RawX;
int nowY = (int) e.RawY;
int movedX = nowX - x;
int movedY = nowY - y;
x = nowX;
y = nowY;
layoutParams.X = layoutParams.X+ movedX;
layoutParams.Y = layoutParams.Y + movedY;
windowManager.UpdateViewLayout(floatView, layoutParams);
break;
default:
break;
}
return false;
}
}
the floatview.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv1"
android:src="@android:drawable/ic_media_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv2"
android:src="@android:drawable/star_on"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv3"
android:src="@android:drawable/ic_menu_more"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
then in your Activity start FloatingService :
button.Click += async delegate
{
if (!Settings.CanDrawOverlays(this))
{
StartActivityForResult(new Intent(Settings.ActionManageOverlayPermission, Android.Net.Uri.Parse("package:" + PackageName)), 0);
}
else
{
StartService(new Intent(this, typeof(FloatingService)));
}
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
if (requestCode == 0)
{
if (!Settings.CanDrawOverlays(this))
{
}
else
{
StartService(new Intent(this, typeof(FloatingService)));
}
}
}
and add <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
in your Manifest.xml
.
the effect like below:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…