当前位置: 移动技术网 > 移动技术>移动开发>Android > Android开发模仿qq视频通话悬浮按钮(实例代码)

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

模仿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视频通话悬浮按钮(实例代码),希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网