Skip to content

[Android]MAUI带有触摸或手势识别器的控件无法在安卓原生悬浮窗IWindowManager正常工作 #30598

Open
@fengxinran233

Description

@fengxinran233

Description

用中文表达更好,在Android平台中使用IWindowManager作为原生悬浮窗,使用ToPlatform方法将MAUI 带有触摸(例如点击事件)的控件,例如Button和带手势识别器的Label转换成Android View之后添加到IWindowManage中无法触发触摸回调和事件(OnTouch/Touch),且无法在事件与回调中log出任何信息,断点也没有反应,意思是完全没用调用那里的代码,使用LinearLayout等布局将转换之后的View添加到其中,也不起作用;而使用不带触摸的控件,例如Image则可以正常工作。相关代码:
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Telecom;
using Android.Views;
using Android.Widget;
using Java.Lang;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Graphics;
using Microsoft.Maui.Platform;
using CommunityToolkit.Maui.Alerts;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using View = Android.Views.View;
using Toast = CommunityToolkit.Maui.Alerts.Toast;
using AndroidX.Fragment.App.StrictMode;
using Color = Android.Graphics.Color;
using Com.Lzf.Easyfloat.Interfaces;
using Microsoft.Maui.Controls.PlatformConfiguration;

namespace example
{
class IManager : Java.Lang.Object
{
private static IWindowManager wManager;
private static WindowManagerLayoutParams wParams;
private int initialX;
private int initialY;
private float initialTouchX;
private float initialTouchY;
public void Init(Context context, Microsoft.Maui.Controls.View view)
{
var builder = MauiProgram.CreateMauiApp();
MauiContext mauiContext = new MauiContext(builder.Services, context);
var _NativeView = view.ToPlatform(mauiContext);
// 创建并初始化视图参数
wParams = new WindowManagerLayoutParams
{
Type = WindowManagerTypes.Application,
Flags = WindowManagerFlags.NotFocusable | WindowManagerFlags.LayoutInScreen | WindowManagerFlags.Fullscreen,
Gravity = GravityFlags.Center | GravityFlags.Center,
X = 0,
Y = 0,
Width = LinearLayout.LayoutParams.WrapContent,
Height = LinearLayout.LayoutParams.WrapContent,
Format = Format.Translucent
};
wManager = (IWindowManager)context.GetSystemService(Context.WindowService);

        LinearLayout NativeView = new LinearLayout(context)
        {
            LayoutParameters = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.WrapContent,
                ViewGroup.LayoutParams.WrapContent)
        };
        NativeView.AddView(_NativeView);

        NativeView.Touch += (v, e) =>
        {
            switch (e.Event.Action)
            {
                case MotionEventActions.Down:
                    initialX = wParams.X;
                    initialY = wParams.Y;
                    initialTouchX = e.Event.RawX;
                    initialTouchY = e.Event.RawY;
                    Toast.Make("Down", CommunityToolkit.Maui.Core.ToastDuration.Short, 14).Show();
                    break;
                case MotionEventActions.Move:
                    wParams.X = initialX + (int)(e.Event.RawX - initialTouchX);
                    wParams.Y = initialY + (int)(e.Event.RawY - initialTouchY);
                    wManager.UpdateViewLayout(NativeView, wParams);
                    Toast.Make("Move", CommunityToolkit.Maui.Core.ToastDuration.Short, 14).Show();
                    break;
                
                default:
                    Toast.Make("default", CommunityToolkit.Maui.Core.ToastDuration.Short, 14).Show();
                    break;
            }
            e.Handled = false; // 确保事件被处理
        };


        //NativeView.AddView(_NativeView);
        //NativeView.SetOnTouchListener(this);

        wManager.AddView(NativeView, wParams);

    }


    //public bool OnTouch(View v, MotionEvent e)
    //{
    //    switch (e.Action)
    //    {
    //        case MotionEventActions.Down:
    //            initialX = wParams.X;
    //            initialY = wParams.Y;
    //            initialTouchX = e.RawX;
    //            initialTouchY = e.RawY;
    //            Toast.Make("Down", CommunityToolkit.Maui.Core.ToastDuration.Short, 14).Show();
    //            break;
    //        case MotionEventActions.Move:
    //            wParams.X = initialX + (int)(e.RawX - initialTouchX);
    //            wParams.Y = initialY + (int)(e.RawY - initialTouchY);
    //            wManager.UpdateViewLayout(v, wParams);
    //            break;
    //        default:                  
    //            break;
    //    }
    //    return false; // 确保事件被处理

    //}
}

}

Steps to Reproduce

1.创建一个新的MAUI安卓项目
2.在Xaml中写一个button或者带手势识别器的任何控件,无论是否带Clicked或者Command,GestureRecognizers,都可以
3.使用IWindowManager将视图添加到悬浮窗,并添加触摸拖拽代码,最后调用
4.Bug:这个悬浮窗无法被拖动,且Touch/OnTouch中不会log消息,toast也不会显示
5.将视图中的控件改为不含Clicked或者Command,GestureRecognizers,再次调用,可以正常拖动

Link to public reproduction project repository

No response

Version with bug

10.0.0-preview.5

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

全部版本

Did you find any workaround?

没有

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    s/needs-reproAttach a solution or code which reproduces the issuet/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions