重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
本文介绍了android 应用内部悬浮可拖动按钮简单实现代码,分享给大家,具体如下:
成都创新互联主要业务有网站营销策划、成都网站设计、做网站、微信公众号开发、微信平台小程序开发、H5页面制作、程序开发等业务。一次合作终身朋友,是我们奉行的宗旨;我们不仅仅把客户当客户,还把客户视为我们的合作伙伴,在开展业务的过程中,公司还积累了丰富的行业经验、成都营销网站建设资源和合作伙伴关系资源,并逐渐建立起规范的客户服务和保障体系。
可以悬浮在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();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。