setOnTouchListener 不适用于具有扩展服务的 RelativeLayout

Posted

技术标签:

【中文标题】setOnTouchListener 不适用于具有扩展服务的 RelativeLayout【英文标题】:setOnTouchListener not work on RelativeLayout with extend service 【发布时间】:2016-06-20 17:37:42 【问题描述】:

我有以下代码,我想在其中获取 x 和 y 坐标。

public class HeadService extends Service 

    private final static int FOREGROUND_ID = 999;

    private WindowManager windowManager;

    // private HeadLayer mHeadLayer;

    ViewGroup mTopView;
    LayoutInflater inflater;

    @Override
    public IBinder onBind(Intent intent) 
        return null;
    

    @Override
    public void onCreate() 
        super.onCreate();
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

        inflater = (LayoutInflater) getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE);
        mTopView = (ViewGroup) inflater.inflate(
                R.layout.activity_invisible, null);


        RelativeLayout rl;
        rl = (RelativeLayout) mTopView.findViewById(R.id.window);




        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT);



        windowManager.addView(rl, params);



        rl.setOnTouchListener(new View.OnTouchListener() 
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) 
                switch (event.getAction()) 
                    case MotionEvent.ACTION_DOWN:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);

                        Toast.makeText(getApplicationContext(), String.valueOf(params.x), Toast.LENGTH_SHORT).show();
                        return true;
                
                return false;
            
        );



    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        logServiceStarted();

        initHeadLayer();

        PendingIntent pendingIntent = createPendingIntent();
        Notification notification = createNotification(pendingIntent);

        startForeground(FOREGROUND_ID, notification);

        return START_STICKY;
    

    @Override
    public void onDestroy() 
        destroyHeadLayer();
        stopForeground(true);

        logServiceEnded();
        if (chatHead != null) windowManager.removeView(chatHead);
    

    private void initHeadLayer() 
        //   mHeadLayer = new HeadLayer(this);

    

    private void destroyHeadLayer() 
        //  mHeadLayer.destroy();
        //  mHeadLayer = null;
    

    private PendingIntent createPendingIntent() 
        Intent intent = new Intent(this, MainActivity.class);
        return PendingIntent.getActivity(this, 0, intent, 0);
    

    private Notification createNotification(PendingIntent intent) 
        return new Notification.Builder(this)
                .setContentTitle(getText(R.string.notificationTitle))
                .setContentText(getText(R.string.notificationText))
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentIntent(intent)
                .build();
    

    private void logServiceStarted() 
        Toast.makeText(this, "Start", Toast.LENGTH_SHORT).show();
    

    private void logServiceEnded() 
        Toast.makeText(this, "End", Toast.LENGTH_SHORT).show();
    

xml 文件:

<RelativeLayout
    android:id="@+id/window"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="#80000000"
    android:clickable="false"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

</RelativeLayout>

现在当我触摸屏幕时,我无法获得 x 和 y 坐标。

那么我怎样才能得到触摸相对布局的坐标呢?

【问题讨论】:

调试器是否在 onTouch 方法中停止?? @VivekMishra 不,我已经设置了调试点,但它没有停止。 仔细阅读此链接的第一行developer.android.com/guide/components/services.html 根据定义,服务没有用户界面,如果您尝试从服务中添加 UI 元素,那么您做错了。 但如果我按下按钮,同样的事情会起作用。按钮点击有效。 【参考方案1】:

我已经解决了。

我刚刚将 WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY 替换为 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 并且它可以工作。

谢谢

【讨论】:

以上是关于setOnTouchListener 不适用于具有扩展服务的 RelativeLayout的主要内容,如果未能解决你的问题,请参考以下文章

为啥 INDIRECT() 不适用于具有工作表范围的动态命名范围?

具有组合布局的集合视图不适用于标题视图

NSIndexPath 不适用于具有 AlertView 功能的 DidSelectedRow

Android iconGravity 不适用于具有 CircularProgressIndicator 的 MaterialButton

GhostDoc“记录此”不适用于具有属性的方法

textarea 不适用于具有值的文档加载