Android开发自定义短视频系统源码全局悬浮按钮

原本想通过framelayout实现一个短视频系统源码悬浮在其他控件上的按钮,但是觉得很麻烦,需要各个界面都要动态填充.于是想到了短视频系统源码悬浮窗,就自定一个ImageView用于显示全局按钮.

一,首先因为悬浮窗式的所以要添加权限,对于SDK>=23的需要动态获取权限,我这边用的是22的

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

二,通过application获取到全局性的WindowManager的params数据

 private WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();
    public WindowManager.LayoutParams getMywmParams(){
        return wmParams;
    }

三,自定义ImageView,并实现点击具有状态选择.其中写了一个回调接口用于对点击事件的处理

public class CustomeMovebutton extends ImageView {
    private final int statusHeight;
    int sW;
    int sH;
    private float mTouchStartX;
    private float mTouchStartY;
    private float x;
    private float y;
    private boolean isMove=false;
    private Context context;
    private WindowManager wm = (WindowManager) getContext().getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
    private WindowManager.LayoutParams wmParams = ((MyApplication) getContext().getApplicationContext()).getMywmParams();
    private float mLastX;
    private float mLastY;
    private float mStartX;
    private float mStartY;
    private long mDownTime;
    private long mUpTime;
    private OnSpeakListener listener;

    public CustomeMovebutton(Context context) {
        this(context,null);
        this.context = context;
    }
    public CustomeMovebutton(Context context, AttributeSet attrs) {
        this(context, attrs,-1);
    }
    public CustomeMovebutton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs,defStyleAttr);
        sW = wm.getDefaultDisplay().getWidth();
        sH = wm.getDefaultDisplay().getHeight();
        statusHeight = getStatusHeight(context);
    }

    /**
     * 状态栏的高度
     *
     */
    public static int getStatusHeight(Context context) {
        int statusHeight = -1;
        try {
            Class clazz = Class.forName("com.android.internal.R$dimen");    //使用反射获取实例
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusHeight;
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //获取相对屏幕的坐标,即以屏幕左上角为原点
        x = event.getRawX();
        y = event.getRawY() - statusHeight;   //statusHeight是系统状态栏的高度
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:    //按下
                setImageResource(R.drawable.btn_voice_pressed);
                mTouchStartX = event.getX();
                mTouchStartY = event.getY();
                mStartX = event.getRawX();
                mStartY = event.getRawY();
                mDownTime = System.currentTimeMillis();
                isMove = false;
                break;
            case MotionEvent.ACTION_MOVE:   //手指移动
                updateViewPosition();
                isMove = true;
                break;
            case MotionEvent.ACTION_UP:    //手抬起
                setImageResource(R.drawable.btn_voice_rest);
                mLastX = event.getRawX();
                mLastY = event.getRawY();
                mUpTime = System.currentTimeMillis();
                //按下到抬起的时间大于500毫秒,并且抬手到抬手绝对值大于20像素处理点击事件
                if(mUpTime - mDownTime < 500){
                    if(Math.abs(mStartX- mLastX )< 20.0 && Math.abs(mStartY - mLastY) < 20.0){
                            if (listener!=null){
                                listener.onSpeakListener();
                            }
                    }
                }

                break;
        }
        return true;
    }

    private void updateViewPosition() {
        wmParams.x = (int) (x - mTouchStartX);
        wmParams.y = (int) (y- mTouchStartY);
        wm.updateViewLayout(this, wmParams);  //刷新显示
    }

    /**
     * 设置点击回调接口
     */
    public interface OnSpeakListener{
        void onSpeakListener();
    }
    public void setOnSpeakListener(OnSpeakListener listener){
        this.listener=listener;
    }
}

四,Activity中使用,其中有设置图片的参数和位置参数

public class MainActivity extends AppCompatActivity{

    private WindowManager wm;
    private WindowManager.LayoutParams wmParams;
    private CustomeMovebutton CustomeMovebutton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        int widthPixels = dm.widthPixels;
        int heightPixels = dm.heightPixels;
        wmParams = ((MyApplication) getApplication()).getMywmParams();
        wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        wmParams.format= PixelFormat.RGBA_8888;//设置背景图片
        wmParams.flags= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ;//
        wmParams.gravity = Gravity.LEFT|Gravity.TOP;//
        wmParams.x = widthPixels-150;   //设置位置像素
        wmParams.y = heightPixels-110;
        wmParams.width=200; //设置图片大小
        wmParams.height=200;
        CustomeMovebutton = new CustomeMovebutton(getApplicationContext());
        CustomeMovebutton.setImageResource(R.drawable.btn_voice_rest);
        wm.addView(CustomeMovebutton, wmParams);
        CustomeMovebutton.setOnSpeakListener(new CustomeMovebutton.OnSpeakListener() {
            @Override
            public void onSpeakListener() {
                Toast.makeText(MainActivity.this, "点击事件", Toast.LENGTH_SHORT).show();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(CustomeMovebutton != null){
            wm.removeView(CustomeMovebutton);
        }
    }
}

以上就是“Android开发自定义短视频系统源码全局悬浮按钮”的全部内容,希望对大家有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值