安卓股票悬浮窗_Android 实现可任意拖动的悬浮窗功能(类似悬浮球)

最近开发项目中,有个在屏幕上任意拖动的悬浮窗功能,其实就是利用 WindowManager的api来完成这个需求,具体的实现的功能如下:

1.自定义view

import android.content.Context;

import android.content.Intent;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.util.TypedValue;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewConfiguration;

import android.view.WindowManager;

import android.widget.LinearLayout;

import com.xinrui.recordscreen.R;

import java.lang.reflect.Field;

/**

*

*/

public class RecordScreenView extends LinearLayout implements View.OnClickListener{

private WindowManager mWindowManager;

private WindowManager.LayoutParams mLayoutParams;

private long mLastDownTime;

private float mLastDownX;

private float mLastDownY;

private boolean mIsLongTouch;

private boolean mIsTouching;

private float mTouchSlop;

private final static long LONG_CLICK_LIMIT = 20;

private final static int TIME_COUNT = 0;

private int mStatusBarHeight;

private int mCurrentMode,time=0;

private final static int MODE_NONE = 0x000;

private final static int MODE_MOVE = 0x001;

private int mOffsetToParent;

private int mOffsetToParentY;

private Context mContext;

public RecordScreenView(Context context) {

super(context);

this.mContext=context;

mWindowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);

initView();

}

private void initView() {

View view = inflate(getContext(), R.layout.layout_ball, this);

mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();

mCurrentMode = MODE_NONE;

recordtime(0);

mStatusBarHeight = getStatusBarHeight();

mOffsetToParent = dip2px(25);

mOffsetToParentY = mStatusBarHeight + mOffsetToParent;

view.setOnTouchListener(new OnTouchListener() {

@Override

public boolean onTouch(View v, final MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

mIsTouching = true;

mLastDownTime = System.currentTimeMillis();

mLastDownX = event.getX();

mLastDownY = event.getY();

postDelayed(new Runnable() {

@Override

public void run() {

if (isLongTouch()) {

mIsLongTouch = true;

}

}

}, LONG_CLICK_LIMIT);

break;

case MotionEvent.ACTION_MOVE:

if (!mIsLongTouch && isTouchSlop(event)) {

return true;

}

if (mIsLongTouch && (mCurrentMode == MODE_NONE || mCurrentMode == MODE_MOVE)) {

mLayoutParams.x = (int) (event.getRawX() - mOffsetToParent);

mLayoutParams.y = (int) (event.getRawY() - mOffsetToParentY);

mWindowManager.updateViewLayout(RecordScreenView.this, mLayoutParams);//不断刷新悬浮窗的位置

mCurrentMode = MODE_MOVE;

}

break;

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_UP:

mIsTouching = false;

if (mIsLongTouch) {

mIsLongTouch = false;

}

mCurrentMode = MODE_NONE;

break;

}

return true;

}

});

}

private boolean isLongTouch() {

long time = System.currentTimeMillis();

if (mIsTouching && mCurrentMode == MODE_NONE && (time - mLastDownTime >= LONG_CLICK_LIMIT)) {

return true;

}

return false;

}

/**

* 判断是否是轻微滑动

*

* @param event

* @return

*/

private boolean isTouchSlop(MotionEvent event) {

float x = event.getX();

float y = event.getY();

if (Math.abs(x - mLastDownX) < mTouchSlop && Math.abs(y - mLastDownY) < mTouchSlop) {

return true;

}

return false;

}

public void setLayoutParams(WindowManager.LayoutParams params) {

mLayoutParams = params;

}

/**

* 获取通知栏高度

*

* @return

*/

private int getStatusBarHeight() {

int statusBarHeight = 0;

try {

Class> c = Class.forName("com.android.internal.R$dimen");

Object o = c.newInstance();

Field field = c.getField("status_bar_height");

int x = (Integer) field.get(o);

statusBarHeight = getResources().getDimensionPixelSize(x);

} catch (Exception e) {

e.printStackTrace();

}

return statusBarHeight;

}

public int dip2px(float dip) {

return (int) TypedValue.applyDimension(

TypedValue.COMPLEX_UNIT_DIP, dip, getContext().getResources().getDisplayMetrics()

);

}

}

2.添加windowManager添加view

import android.content.Context;

import android.graphics.PixelFormat;

import android.view.Gravity;

import android.view.WindowManager;

import android.view.WindowManager.LayoutParams;

/**

* Created by wangxiandeng on 2016/11/25.

*/

public class FloatWindowManager {

private static RecordScreenView mBallView;

private static WindowManager mWindowManager;

public static void addBallView(Context context) {

if (mBallView == null) {

WindowManager windowManager = getWindowManager(context);

int screenWidth = windowManager.getDefaultDisplay().getWidth();

int screenHeight = windowManager.getDefaultDisplay().getHeight();

mBallView = new RecordScreenView(context);

LayoutParams params = new LayoutParams();

params.x = screenWidth/2;

params.y = screenHeight/2+150;

params.width = LayoutParams.WRAP_CONTENT;

params.height = LayoutParams.WRAP_CONTENT;

params.gravity = Gravity.LEFT | Gravity.TOP;

params.type = LayoutParams.TYPE_APPLICATION_OVERLAY;

params.format = PixelFormat.RGBA_8888;

params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL

| LayoutParams.FLAG_NOT_FOCUSABLE;

mBallView.setLayoutParams(params);

windowManager.addView(mBallView, params);

}

}

public static void removeBallView(Context context) {

if (mBallView != null) {

WindowManager windowManager = getWindowManager(context);

windowManager.removeView(mBallView);

mBallView = null;

}

}

private static WindowManager getWindowManager(Context context) {

if (mWindowManager == null) {

mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

}

return mWindowManager;

}

}

3.Acitivity中调用

import android.app.Activity;

import android.content.Intent;

import android.os.Build;

import android.os.Bundle;

import android.provider.Settings;

import android.util.Log;

import android.widget.Toast;

import com.xinrui.recordscreen.view.FloatWindowManager;

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if (Build.VERSION.SDK_INT >= 23) {

//设置中请求开启悬浮窗权限

if (!Settings.canDrawOverlays(this)) {

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

Toast.makeText(this, MainActivity.this.getResources().getString(R.string.open_float), Toast.LENGTH_SHORT).show();

}else{

initView();

}

}

}

private void initView() {

FloatWindowManager.addBallView(MainActivity.this);

finish();

}

}

5.AndroidManifest.xml

package="com.xinrui.recordscreen">

//悬浮窗权限

android:allowBackup="true"

android:icon="@drawable/recording_screen_nor"

android:label="@string/app_name"

android:supportsRtl="true">

总结

到此这篇关于Android 实现可任意拖动的悬浮窗功能(类似悬浮球)的文章就介绍到这了,更多相关Android任意拖动的悬浮窗内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值