浮动窗体的控件:类iphone球

本文介绍了一个简单的Android悬浮窗应用程序的实现过程。该程序通过使用WindowManager服务在Android设备上创建了一个可以移动的悬浮窗口,并实现了点击跳转功能。文章详细展示了如何设置悬浮窗参数、处理触摸事件以及实现窗口移动等关键技术。
摘要由CSDN通过智能技术生成

import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

//textView为悬浮的view,现在设置为static
private static TextView textView = null;
//要有处理window的对象
private WindowManager windowManager = null;

//用于创建view的上下文
private Context context = null;

//悬浮窗的样式控制(包裹内容、设置位置)
private WindowManager.LayoutParams lp = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //实例上下文
    context = getApplicationContext();
    //实例windowmanager,它是系统服务,直接get
    windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

    //悬浮窗样式对象
    lp = new WindowManager.LayoutParams();
    //设置成在屏幕悬浮的效果
    //如下写法为api 19以前的写法,新版api要求这个lp.type只能是一个值
    //2003|2006=?     200     011    110     111=7

// lp.type=WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
// |WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
lp.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;

    //不获取焦点,不全屏
    lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;

    //设置位置
    lp.x = 10;
    lp.y = 50;

    //设置一个位置的相对标准
    lp.gravity = Gravity.LEFT | Gravity.TOP;


    //宽高包裹内容
    lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
    lp.height = WindowManager.LayoutParams.WRAP_CONTENT;

    //悬浮窗一般都是透明效果的,因为怕影响观看桌面的应用
    lp.format = PixelFormat.TRANSPARENT;


    if (textView == null) {
        //下面创建要悬浮的view
        textView = new TextView(context);
        //把之前设置好的样式交给这个悬浮的view

        //layoutparams不匹配,报错为classcastexception
        //我们应该把这个关于view的样式交给windowmanager来进行管理
        // textView.setLayoutParams(lp);
        textView.setText("123456789");

        windowManager.addView(textView, lp);
    } else {
        //如果这个textView已经存在,如何删除它
        windowManager.removeView(textView);
        textView = null;
    }


    //点击?移动?都怎么办?
    if (textView != null) {
        //点击的监听,直接跳转进来
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TOP
                );
                startActivity(intent);
            }
        });

        //移动?
        //用touchlistener来监听,然后实现移动效果
        textView.setOnTouchListener(new View.OnTouchListener() {

            private long lastDownTime;
            private int lastX;
            private int lastY;
            //把悬浮窗的属性复制一份
            private WindowManager.LayoutParams mlp = lp;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                boolean ret = false;
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        lastDownTime = System.currentTimeMillis();
                        lastX = (int) event.getRawX();
                        lastY = (int) event.getRawY();
                        ret = true;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        //移动
                        //获取这个event相对于手机屏幕的宽高
                        float x = event.getRawX();
                        float y = event.getRawY();
                        //计算这一次移动的x和y的增量
                        int ix = (int) (x - lastX);
                        int iy = (int) (y - lastY);
                        //把增量设置给lp
                        mlp.x += ix;
                        mlp.y += iy;
                        //最后还要把这一次移动的x,y作为lastX设lastY
                        lastX = (int) x;
                        lastY = (int) y;

                        //更新悬浮窗的位置
                        windowManager.updateViewLayout(textView, mlp);
                        break;
                    case MotionEvent.ACTION_UP:
                        long time = System.currentTimeMillis();
                        if (time - lastDownTime < 300) {
                            //触发点击监听
                            textView.performClick();
                        }
                        break;

                }

                return ret;
            }
        });


    }


}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值