weixin_41512174 2018-04-03 11:50 采纳率: 0%
浏览 2631
已结题

Android 悬浮窗获取点击拖拽事件

之前参照网上例子写过一个demo,实现在Activity中点击最小化按钮,将该Activity finish,并启动servie生成一个悬浮按钮,可点击也可拖拽;
最近工作需要也做一个相似的悬浮窗,悬浮按钮生成了,App被Home也能存在,不会
消失,但该悬浮按钮却没法捕获点击和拖拽事件。
这两个代码几乎一摸一样,请大神们帮忙看下是哪里出的问题,谢谢!

代码如下:
package com.example.menqi.myapplication;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;

public class MyService extends Service {

private WindowManager mWindowManager;
private WindowManager.LayoutParams mLayoutParams;
/**
 * float的布局view
 */
private View mFloatView;
private ViewGroup glSurfaceView;
private int mFloatWinWidth,mFloatWinHeight;//悬浮窗的宽高
//private int mFloatWinMarginTop,mFloatWinMarginRight;

public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    createWindowManager();
    createFloatView();
    return super.onStartCommand(intent, flags, startId);

}


@Override
public void onDestroy() {
    super.onDestroy();
    removeFloatView();
}

private void createWindowManager() {
    // 取得系统窗体
    mWindowManager= (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
    //计算得出悬浮窗口的宽高
    DisplayMetrics metric =new DisplayMetrics();
    mWindowManager.getDefaultDisplay().getMetrics(metric);
    int screenWidth = metric.widthPixels;
    mFloatWinWidth = screenWidth *1/3;
    mFloatWinHeight=mFloatWinWidth*4/3;
    //mFloatWinMarginTop= (int)this.getResources().getDimension(R.dimen.rkcloud_av_floatwin_margintop);
    //mFloatWinMarginRight= (int)this.getResources().getDimension(R.dimen.rkcloud_av_floatwin_marginright);

    // 窗体的布局样式
    // 获取LayoutParams对象
    mLayoutParams=new WindowManager.LayoutParams();
    // 确定爱悬浮窗类型,表示在所有应用程序之上,但在状态栏之下
    //TODO? 在android2.3以上可以使用TYPE_TOAST规避权限问题
    mLayoutParams.type= WindowManager.LayoutParams.TYPE_TOAST;//TYPE_PHONE
    mLayoutParams.format= PixelFormat.RGBA_8888;
    mLayoutParams.flags= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
    // 悬浮窗的对齐方式
    mLayoutParams.gravity= Gravity.LEFT| Gravity.TOP;
    // 悬浮窗的位置
    mLayoutParams.x=70;
    mLayoutParams.y=210;
    mLayoutParams.width=mFloatWinWidth;
    mLayoutParams.height=mFloatWinHeight;
}

//开始触控的坐标,移动时的坐标(相对于屏幕左上角的坐标)
private int mTouchStartX, mTouchStartY, mTouchCurrentX, mTouchCurrentY;
//开始时的坐标和结束时的坐标(相对于自身控件的坐标)
private int mStartX, mStartY, mStopX, mStopY;
//判断悬浮窗口是否移动,这里做个标记,防止移动后松手触发了点击事件
private boolean isMove;


/**
 * 创建悬浮窗
 */
private void createFloatView() {

    LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
    mFloatView= inflater.inflate(R.layout.floatlayout, null);
    glSurfaceView= (ViewGroup)mFloatView.findViewById(R.id.VOIPFloatView);
    //glSurfaceView.setPreserveEGLContextOnPause(true);
    glSurfaceView.setKeepScreenOn(true);
    mWindowManager.addView(mFloatView,mLayoutParams);




    mFloatView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v,MotionEvent event) {
            int action = event.getAction();
            /*if(MotionEvent.ACTION_DOWN == action) {
                mStartX=mLastX= (int) event.getRawX();
                mStartY=mLastY= (int) event.getRawY();
            }else if(MotionEvent.ACTION_UP == action) {
                int dx = (int) event.getRawX() -mStartX;
                int dy = (int) event.getRawY() -mStartY;
                if(Math.abs(dx) >5|| Math.abs(dy) >5) {
                    return true;
                }
            }else if(MotionEvent.ACTION_MOVE == action) {
                int dx = (int) event.getRawX() -mLastX;
                int dy = (int) event.getRawY() -mLastY;
                mLayoutParams.x=mLayoutParams.x- dx;
                mLayoutParams.y=mLayoutParams.y+ dy;
                mWindowManager.updateViewLayout(mFloatView,mLayoutParams);
                mLastX= (int) event.getRawX();
                mLastY= (int) event.getRawY();
            }
            return false;*/
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    isMove = false;
                    mTouchStartX = (int) event.getRawX();
                    mTouchStartY = (int) event.getRawY();
                    mStartX = (int) event.getX();
                    mStartY = (int) event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    mTouchCurrentX = (int) event.getRawX();
                    mTouchCurrentY = (int) event.getRawY();
                    mLayoutParams.x += mTouchCurrentX - mTouchStartX;
                    mLayoutParams.y += mTouchCurrentY - mTouchStartY;
                    mWindowManager.updateViewLayout(mFloatView, mLayoutParams);

                    mTouchStartX = mTouchCurrentX;
                    mTouchStartY = mTouchCurrentY;
                    break;
                case MotionEvent.ACTION_UP:
                    mStopX = (int) event.getX();
                    mStopY = (int) event.getY();
                    if (Math.abs(mStartX - mStopX) >= 1 || Math.abs(mStartY - mStopY) >= 1) {
                        isMove = true;
                    }
                    break;
            }
            //如果是移动事件不触发OnClick事件,防止移动的时候一放手形成点击事件
            return isMove;

        }
    });

    mFloatView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ToVOIPActivity();
            MyService.this.stopSelf();
        }
    });

    /*VideoRendererGui.setView(glSurfaceView, new Runnable() {
        @Override
        public void run() {
            if(WebRtcHelperEx.getInstance().isWebRtcChanelAlive()) {
                WebRtcHelperEx.getInstance().updateVideoUI(WebRtcHelperEx.latestLocalVideoSize,WebRtcHelperEx.latestRemoteVideoSize);
            }
        }
    });
    if(WebRtcHelperEx.getInstance().isWebRtcChanelAlive()) {
        LogEx.d(TAG,"createFloatView: webrtc instance is alive and we will call resetRenders");
        WebRtcHelperEx.getInstance().resetRenders();
        WebRtcHelperEx.getInstance().updateVideoUI(WebRtcHelperEx.VIDEOSIZE_SMALL,WebRtcHelperEx.VIDEOSIZE_BIG);
    }*/

}

private void removeFloatView() {
    if(mFloatView != null && mWindowManager != null) {
        mWindowManager.removeView(mFloatView);
    }
}

/**
 * 单击后回到@WebRTCActivity以切换为大尺寸页面
 */
private void ToVOIPActivity() {
    //TODO跳转到Activity
    Intent intentToActivity = new Intent(this, Main2Activity.class);//WebPhoneIncomingCallActivity来电页面
    intentToActivity.setFlags(FLAG_ACTIVITY_NEW_TASK);
    startActivity(intentToActivity);
}

}

layout

<?xml version="1.0" encoding="utf-8"?>
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/VOIPFloatView"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/avcallfloat"
android:scaleType="centerInside" />

  • 写回答

5条回答 默认 最新

  • 键盘舞者113 博客专家认证 2018-04-03 12:01
    关注

    权限,需要主动申请

     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  
    
    评论

报告相同问题?

悬赏问题

  • ¥15 机器学习教材中的例题询问
  • ¥15 求.net core 几款免费的pdf编辑器
  • ¥15 C# P/Invoke的效率问题
  • ¥20 thinkphp适配人大金仓问题
  • ¥20 Oracle替换.dbf文件后无法连接,如何解决?(相关搜索:数据库|死循环)
  • ¥15 数据库数据成问号了,前台查询正常,数据库查询是?号
  • ¥15 算法使用了tf-idf,用手肘图确定k值确定不了,第四轮廓系数又太小才有0.006088746097507285,如何解决?(相关搜索:数据处理)
  • ¥15 彩灯控制电路,会的加我QQ1482956179
  • ¥200 相机拍直接转存到电脑上 立拍立穿无线局域网传
  • ¥15 (关键词-电路设计)