Android开发模仿qq视频通话悬浮按钮(实例代码)

模仿qq视频通话的悬浮按钮的实例代码,如下所示;

public class FloatingWindowService extends Service{  private static final String TAG="OnTouchListener";  private static View mView = null;  private static WindowManager mWindowManager = null;  private static Context mContext = null;  public static Boolean isShown = false;  public WindowManager.LayoutParams params = null;  private int pixel;  private int TheOffset;  @Override  public void onCreate() {    super.onCreate();  }  @Override  public int onStartCommand(Intent intent, int flags, int startId) {    pixel = intent.getIntExtra("pixel",1);    showPopupWindow(this);    return super.onStartCommand(intent, flags, startId);  }  /**   * 显示弹出框   *   * @param context   *   */  private void showPopupWindow(final Context context) {    if (isShown) {      return;    }    isShown = true;    // 获取应用的Context    mContext = context.getApplicationContext();    // 获取WindowManager    mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);    params = new WindowManager.LayoutParams();    mView = setUpView(context);    // 类型    params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;    int flags=WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;    params.flags = flags;    params.format = PixelFormat.TRANSLUCENT;    params.width = WindowManager.LayoutParams.WRAP_CONTENT;    params.height = WindowManager.LayoutParams.WRAP_CONTENT;    params.gravity = Gravity.CENTER;    mWindowManager.addView(mView, params);  }  /**   * 隐藏弹出框   */  private static void hidePopupWindow() {    if (isShown && null != mView) {      mWindowManager.removeView(mView);      isShown = false;    }  }  private  int x=0;  private  int y=0;  private  int startX=0;  private  int startY=0;  private View setUpView(final Context context) {    View view = LayoutInflater.from(context).inflate(R.layout.popupwindow,        null);     TextView tv= (TextView) view.findViewById(R.id.title);    int w = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);    int h = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);    tv.measure(w, h);    TheOffset=(pixel-tv.getMeasuredWidth())/2-50;    tv.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        Intent intent =new Intent(context,MainActivity.class);        context.startActivity(intent);        // Toast.makeText(context,"点击事件",Toast.LENGTH_LONG).show();      }    });    tv.setOnTouchListener(new View.OnTouchListener() {      @Override      public boolean onTouch(View v, MotionEvent event) {        switch (event.getAction()){          case MotionEvent.ACTION_MOVE:            int newX= (int) (event.getRawX()-x);            int newY= (int) (event.getRawY()-y);            params.x=newX+startX;            params.y=newY+startY;              mWindowManager.updateViewLayout(mView,params);            break;          case MotionEvent.ACTION_DOWN:            x= (int) event.getRawX();            y= (int) event.getRawY();            break;          case MotionEvent.ACTION_UP:            if(params.x>=0){              params.x=TheOffset;              mWindowManager.updateViewLayout(mView,params);            }            if(params.x<=-0){              params.x=-TheOffset;              mWindowManager.updateViewLayout(mView,params);            }            Log.i(TAG,params.x+"");            Log.i(TAG,params.y+"");            //判断 从按住到抬起时候的移动距离, 如果如果移动距离大于20 那么就拦截事件,否则就不拦截事件,主要是处理点击事件的冲突            if(Math.abs(startX-params.x)>20 ||Math.abs(startY-params.y)>20 ){              //记录上一次的偏移量              startX=params.x;              startY=params.y;              return true;            }else {              startX=params.x;              startY=params.y;              return false;            }        }        return false;      }    });    return view;  }  @Nullable  @Override  public IBinder onBind(Intent intent) {    return null;  }  @Override  public void onDestroy() {    super.onDestroy();    if (mView != null) {      isShown=false;      mWindowManager.removeView(mView);    }  }  }

Main

@Override    protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_main);      findViewById(R.id.open).setOnClickListener(this);      findViewById(R.id.close).setOnClickListener(this);    }

-点击开启 关闭悬浮按钮

@Override    public void onClick(View v) {      switch (v.getId()){        case R.id.open:          //判断是否拥有悬浮权限          //op 的值是 0 ~ 47,其中0代表粗略定位权限,1代表精确定位权限,24代表悬浮窗权限。(具体可以看看Android源码在android.app下就有个AppOpsManager类)          if(utils.checkOp(this,24)==0) {            Intent intent=new Intent(MainActivity.this, FloatingWindowService.class);            intent.putExtra("pixel",utils.pixel(this)[0]);            startService(intent);          }else {            //引导用户进入悬浮权限设置界面            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,                Uri.parse("package:" + getPackageName()));            startActivityForResult(intent, 200);          }          break;        case R.id.close:          stopService(new Intent(MainActivity.this,FloatingWindowService.class));          break;      }    }

判断权限 -获取屏幕的宽高

public class utils {      public static int checkOp(Context context, int op){        final int version = Build.VERSION.SDK_INT;        if (version >= 19){          Object object = context.getSystemService("appops");          Class c = object.getClass();          try {            Class[] cArg = new Class[3];            cArg[0] = int.class;            cArg[1] = int.class;            cArg[2] = String.class;            Method lMethod = c.getDeclaredMethod("checkOp", cArg);            return (Integer) lMethod.invoke(object, op, Binder.getCallingUid(), context.getPackageName());          } catch(NoSuchMethodException e) {            e.printStackTrace();          } catch (IllegalAccessException e) {            e.printStackTrace();          } catch (IllegalArgumentException e) {            e.printStackTrace();          } catch (InvocationTargetException e) {            e.printStackTrace();          }        }        return -1;      }      /**       * 获取屏幕的宽高       * @param context       * @return       */      public static int[] pixel(Activity context){        DisplayMetrics dm = new DisplayMetrics();        context.getWindowManager().getDefaultDisplay().getMetrics(dm);        return new int[]{dm.widthPixels,dm.heightPixels};      }    }

–popupwindow填充布局文件

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:orientation="vertical">    <LinearLayout      android:id="@+id/popup_window"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:background="@android:color/white"      android:orientation="vertical" >      <TextView        android:background="@mipmap/ic_launcher"        android:id="@+id/title"        android:layout_width="50dp"        android:layout_height="50dp"/>      </LinearLayout>  </LinearLayout>

以上所述是小编给大家介绍的Android开发模仿qq视频通话悬浮按钮(实例代码),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

因为你的喜爱会挡也挡不住地流露出来。

Android开发模仿qq视频通话悬浮按钮(实例代码)

相关文章:

你感兴趣的文章:

标签云: