欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android 应用内部悬浮可拖动按钮简单实现代码

程序员文章站 2023-12-09 20:53:21
本文介绍了android 应用内部悬浮可拖动按钮简单实现代码,分享给大家,具体如下: 可以悬浮在activity上面,在加载fragment时悬浮按钮不会消失...

本文介绍了android 应用内部悬浮可拖动按钮简单实现代码,分享给大家,具体如下:

android 应用内部悬浮可拖动按钮简单实现代码

可以悬浮在activity上面,在加载fragment时悬浮按钮不会消失

实现方式很简单,因为是在应用内部拖动的,只需要通过activity获取windowmanager,然后将要拖动的view设置上去就行
设置代码:

windowmanager wm = (windowmanager) activity.getsystemservice(context.window_service);
    displaymetrics dm = new displaymetrics();
    activity.getwindowmanager().getdefaultdisplay().getmetrics(dm);
    //通过像素密度来设置按钮的大小
    dpi = dpi(dm.densitydpi);
    //屏宽
    screenwidth = wm.getdefaultdisplay().getwidth();
    //屏高
    screenheight = wm.getdefaultdisplay().getheight();
    //布局设置
    wmparams = new windowmanager.layoutparams();
    // 设置window type
    wmparams.type = windowmanager.layoutparams.type_application;
    wmparams.format = pixelformat.rgba_8888; // 设置图片格式,效果为背景透明
    wmparams.gravity = gravity.left | gravity.top;
    // 设置window flag
    wmparams.flags = windowmanager.layoutparams.flag_not_focusable;
    wmparams.width = dpi;
    wmparams.height = dpi;
    wmparams.y = (screenheight - dpi) >> 1;
    wm.addview(this, wmparams);

控件的大小根据像素密度来进行设置的

  /**
   * 根据密度选择控件大小
   *
   */
  private int dpi(int densitydpi) {
    if (densitydpi <= 120) {
      return 36;
    } else if (densitydpi <= 160) {
      return 48;
    } else if (densitydpi <= 240) {
      return 72;
    } else if (densitydpi <= 320) {
      return 96;
    }
    return 108;
  }

主要的处理问题就是控件的拖动问题,通过重写ontouchevent方法进行处理

源码:

import android.app.activity;
import android.content.context;
import android.graphics.pixelformat;
import android.util.displaymetrics;
import android.view.gravity;
import android.view.layoutinflater;
import android.view.motionevent;
import android.view.view;
import android.view.windowmanager;
import android.widget.relativelayout;
import android.widget.textview;


/**
 * created by xiang on 2016/12/28.
 *
 * im悬浮窗视图
 */

public class chatview extends relativelayout{

  // 悬浮栏位置
  private final static int left = 0;
  private final static int right = 1;
  private final static int top = 3;
  private final static int buttom = 4;

  private int dpi;
  private int screenheight;
  private int screenwidth;
  private windowmanager.layoutparams wmparams;
  private windowmanager wm;
  private float x, y;
  private float mtouchstartx;
  private float mtouchstarty;
  private boolean isscroll;

  public chatview(activity activity) {
    super(activity);
    layoutinflater.from(activity).inflate(r.layout.view_chat, this);
    setbackgroundresource(r.drawable.chat_btn);
    wm = (windowmanager) activity.getsystemservice(context.window_service);
    displaymetrics dm = new displaymetrics();
    activity.getwindowmanager().getdefaultdisplay().getmetrics(dm);
    //通过像素密度来设置按钮的大小
    dpi = dpi(dm.densitydpi);
    //屏宽
    screenwidth = wm.getdefaultdisplay().getwidth();
    //屏高
    screenheight = wm.getdefaultdisplay().getheight();
    //布局设置
    wmparams = new windowmanager.layoutparams();
    // 设置window type
    wmparams.type = windowmanager.layoutparams.type_application;
    wmparams.format = pixelformat.rgba_8888; // 设置图片格式,效果为背景透明
    wmparams.gravity = gravity.left | gravity.top;
    // 设置window flag
    wmparams.flags = windowmanager.layoutparams.flag_not_focusable;
    wmparams.width = dpi;
    wmparams.height = dpi;
    wmparams.y = (screenheight - dpi) >> 1;
    wm.addview(this, wmparams);
    hide();
  }


  /**
   * 根据密度选择控件大小
   *
   */
  private int dpi(int densitydpi) {
    if (densitydpi <= 120) {
      return 36;
    } else if (densitydpi <= 160) {
      return 48;
    } else if (densitydpi <= 240) {
      return 72;
    } else if (densitydpi <= 320) {
      return 96;
    }
    return 108;
  }

  public void show() {
    if (isshown()) {
      return;
    }
    setvisibility(view.visible);
  }


  public void hide() {
    setvisibility(view.gone);
  }

  public void destory() {
    hide();
    wm.removeviewimmediate(this);
  }


  @override
  public boolean ontouchevent(motionevent event) {
    // 获取相对屏幕的坐标, 以屏幕左上角为原点
    x = event.getrawx();
    y = event.getrawy();
    switch (event.getaction()) {
      case motionevent.action_down:
        // setbackgrounddrawable(opendrawable);
        // invalidate();
        // 获取相对view的坐标,即以此view左上角为原点
        mtouchstartx = event.getx();
        mtouchstarty = event.gety();
        break;
      case motionevent.action_move:
        if (isscroll) {
          updateviewposition();
        } else {
          // 当前不处于连续滑动状态 则滑动小于图标1/3则不滑动
          if (math.abs(mtouchstartx - event.getx()) > dpi / 3
              || math.abs(mtouchstarty - event.gety()) > dpi / 3) {
            updateviewposition();
          } else {
            break;
          }
        }
        isscroll = true;
        break;
      case motionevent.action_up:
        // 拖动
        if (isscroll) {
          autoview();
          // setbackgrounddrawable(closedrawable);
          // invalidate();
        } else {
          // 当前显示功能区,则隐藏
          // setbackgrounddrawable(opendrawable);
          // invalidate();

        }
        isscroll = false;
        mtouchstartx = mtouchstarty = 0;
        break;
    }
    return true;
  }

  /**
   * 自动移动位置
   */
  private void autoview() {
    // 得到view在屏幕中的位置
    int[] location = new int[2];
    getlocationonscreen(location);
    //左侧
    if (location[0] < screenwidth / 2 - getwidth() / 2) {
      updateviewposition(left);
    } else {
      updateviewposition(right);
    }
  }

  /**
   * 手指释放更新悬浮窗位置
   *
   */
  private void updateviewposition(int l) {
    switch (l) {
      case left:
        wmparams.x = 0;
        break;
      case right:
        int x = screenwidth - dpi;
        wmparams.x = x;
        break;
      case top:
        wmparams.y = 0;
        break;
      case buttom:
        wmparams.y = screenheight - dpi;
        break;
    }
    wm.updateviewlayout(this, wmparams);
  }

  // 更新浮动窗口位置参数
  private void updateviewposition() {
    wmparams.x = (int) (x - mtouchstartx);
    //是否存在状态栏(提升滑动效果)
    // 不设置为全屏(状态栏存在) 标题栏是屏幕的1/25
    wmparams.y = (int) (y - mtouchstarty - screenheight / 25);
    wm.updateviewlayout(this, wmparams);
  }
}

使用方法:

//传入上下文activity
chatview chatview = new chatview(this);
chatview.show();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。