Android 之浮窗篇

Android 之浮窗篇

所谓浮窗就是悬浮在屏幕上的一个小窗口,可以拖到,点击等。像360的那个所谓的加速球就是一个经典的浮窗。我们就是要做一个这样的东西。

 

1、创建浮窗,同理,也是要扩展某一个东西的,我们这里选择的是linearlayout。你也可以选择view,或者imageview等等。废话不多说,我直接把代码填出来把。

 

public class FloatWindowView extends LinearLayout {

 

    public FloatWindowView(Context context) {

super(context);

    }

 

    private float mTouchX;

    private float mTouchY;

    private float x;

    private float y;

    private float mStartX;

    private float mStartY;

    private OnClickListener mClickListener;

    private WindowManager windowManager = (WindowManager) getContext()

    .getApplicationContext().getSystemService("window");

 

    // 此windowManagerParams变量为获取的全局变量,用以保存悬浮窗口的属性

    private WindowManager.LayoutParams windowManagerParams = Constant.windowParams;

 

    @Override

    public boolean onTouchEvent(MotionEvent event) {

// 获取到状态栏的高度

Rect frame = new Rect();

 

getWindowVisibleDisplayFrame(frame);

 

int statusBarHeight = frame.top;

 

System.out.println("statusBarHeight:" + statusBarHeight);

 

// 获取相对屏幕的坐标,即以屏幕左上角为原点

x = event.getRawX();

 

// statusBarHeight是系统状态栏的高度

y = event.getRawY() - statusBarHeight;

 

Log.i("tag""currX" + x + "====currY" + y);

 

switch (event.getAction()) {

 

// 捕获手指触摸按下动作

case MotionEvent.ACTION_DOWN:

    // 获取相对View的坐标,即以此View左上角为原点

    mTouchX = event.getX();

    mTouchY = event.getY();

    mStartX = x;

    mStartY = y;

    Log.i("tag""startX" + mTouchX + "====startY" + mTouchY);

    break;

// 捕获手指触摸移动动作

case MotionEvent.ACTION_MOVE:

    updateViewPosition();

    break;

// 捕获手指触摸离开动作

case MotionEvent.ACTION_UP:

    updateViewPosition();

    mTouchX = mTouchY = 0;

    if ((x - mStartX) < 5 && (y - mStartY) < 5) {

if (mClickListener != null) {

    mClickListener.onClick(this);

}

    }

    break;

}

return true;

    }

 

    @Override

    public void setOnClickListener(OnClickListener l) {

this.mClickListener = l;

    }

 

    private void updateViewPosition() {

// 更新浮动窗口位置参数

windowManagerParams.x = (int) (x - mTouchX);

windowManagerParams.y = (int) (y - mTouchY);

windowManager.updateViewLayout(thiswindowManagerParams); // 刷新显示

    }

}

2、这里特别要注意Constant这个类,这是一个常量类

public class Constant {

 

    /**

     * 此windowManagerParams变量为获取的全局变量,用以保存悬浮窗口的属性

     */

    public static final WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();

}

 

3、最后一步就是使用FloatWindowView这个类了。

这里需要声明三个变量。我就直接粘贴代码了。因为我把这个浮窗放在了service里面,所有你看到的是在service里面的创建浮窗的代码。

public class ScreenCaptureService extends Service {

 

    /**

     * 浮窗对象

     */

    private FloatWindowView floatWindow;

 

    /**

     * 窗口管理器

     */

    private WindowManager windowManager = null;

 

    /**

     * 窗口布局

     */

    private WindowManager.LayoutParams windowManagerParams = null;

 

    /**

     * 内部类对象,这个就不知道是一种什么设计模式了

     */

    private final IBinder baseBinder = new ScreenCaptureServiceBinder();

 

    /**

     * 内部类,这样的用法还是第一次见,他返回外部类,然后在与外部类绑定的Activity中使用外部类来操作相关的细节内容

     * 

     * @author jeck

     * 

     */

    public class ScreenCaptureServiceBinder extends Binder {

 

public ScreenCaptureService getService() {

    return ScreenCaptureService.this;

}

    }

 

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

 

// 创建浮窗

crateFloatWindow();

 

return super.onStartCommand(intent, flags, startId);

    }

 

    @Override

    public IBinder onBind(Intent intent) {

return baseBinder;

    }

 

    @Override

    public void onCreate() {

super.onCreate();

    }

 

    @Override

    public void onDestroy() {

super.onDestroy();

stopSelf();

    }

 

    /**

     * 创建浮窗

     */

    private void crateFloatWindow() {

 

floatWindow = new FloatWindowView(getApplicationContext());

 

floatWindow.setOnClickListener(new OnClickListener() {

 

    @Override

    public void onClick(View v) {

 

// if (isStartCapture) {

//

// // 停止录制

// isStartCapture = false;

// captureState = 0;

//

// Toast.makeText(getApplicationContext(), "录制结束",

// Toast.LENGTH_LONG).show();

//

// } else {

//

// // 启动录屏进程

// // new ScreenCaptureTask().execute();

//

// // 开始录制

// isStartCapture = true;

// captureState = 1;

//

// Toast.makeText(getApplicationContext(), "开始录屏,再次点击停止录屏",

// Toast.LENGTH_LONG).show();

//

// }

 

    }

});

 

ImageView view = new ImageView(this);

 

// 为浮窗添加图片

view.setImageResource(R.drawable.float_window_icon);

 

// 这里简单的用自带的icon来做演示

floatWindow.addView(view);

 

windowManager = (WindowManager) getApplicationContext()

.getSystemService("window");

 

// 设置LayoutParams(全局变量)相关参数

windowManagerParams = Constant.windowParams;

// 设置window type

windowManagerParams.type = 2003;

// windowManagerParams.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明

// 设置Window flag

windowManagerParams.flags = 40;

windowManagerParams.format = 1;

 

// 调整悬浮窗口至左上角,便于调整坐标

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

 

// 以屏幕左上角为原点,设置x、y初始值

windowManagerParams.x = 100;

windowManagerParams.y = 100;

 

// 设置悬浮窗口长宽数据

windowManagerParams.width = 80;

windowManagerParams.height = 80;

 

// 显示myFloatView图像

windowManager.addView(floatWindowwindowManagerParams);

    }

}

4、最后一定要记得加权限,否则会报错的哟,这一点非常重要

 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

 

要实现Android浮窗应用,可以按照以下步骤进行操作: 1. 获取WindowManager并设置LayoutParams:在应用的onCreate方法中,获取WindowManager并设置LayoutParams。通过WindowManager可以管理窗口的显示和布局,LayoutParams用于设置浮窗的大小、位置和其他属性。\[1\] 2. 创建View并添加到WindowManager:在服务的onStartCommand方法中,创建一个View对象,并将其添加到WindowManager中。可以使用LayoutInflater来加载布局文件,然后将View添加到WindowManager中显示出来。\[2\] 3. 设置浮窗的类型和属性:在LayoutParams中设置浮窗的类型,可以根据不同的Android版本选择不同的类型。同时,还可以设置浮窗的格式、位置、大小和其他属性。例如,可以设置浮窗在其他应用和窗口上方显示,设置浮窗的宽度、高度、位置等。\[1\] 4. 不同Activity共享一个悬浮窗:通过windowManager.addView方法可以将视图添加到当前的Activity上,从而实现不同Activity共享一个悬浮窗。可以设置LayoutParams的type属性为WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG来实现此功能。\[3\] 总结起来,要实现Android浮窗应用,需要获取WindowManager并设置LayoutParams,创建View并添加到WindowManager,设置浮窗的类型和属性,以及实现不同Activity共享一个悬浮窗。 #### 引用[.reference_title] - *1* *2* [Android浮窗的简单实现](https://blog.csdn.net/liuqinhou/article/details/129352564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Android应用内悬浮窗(无需权限)](https://blog.csdn.net/baidu_33853807/article/details/130127292)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值