Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
566 views
in Technique[技术] by (71.8m points)

c# - How can I do this floating action button where can run even in background mode in Xamarin forms

Here's my sample: I need this to be a connection in other apps... Thank you!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...