首页 > 代码库 > 悬窗播放视频,让你聊天看视频两不误(下)

悬窗播放视频,让你聊天看视频两不误(下)

下面实现最小化悬窗,点击继续悬窗播放,拖动小火箭效果。
这部分代码借鉴了网上的小火箭效果
技术分享
点击悬窗视频的一个按钮启动另一个server。展现小按钮图标。

case R.id.iv_small:
             MyApplicaton.setValueProgress(valueProgress);
             onExit();
             Intent i = new Intent(context, FloatWindowService.class);
             context.startService(i);
             break;

下面看FloatWindowService里面代码。createSmallWindow创建小悬浮窗。

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

        MyWindowManager.createSmallWindow(getApplicationContext());
        return super.onStartCommand(intent, flags, startId);
    }

MyWindowManager中的方法


     //小悬浮窗View的实例 
    private static FloatWindowSmallView smallWindow;
/**
     * 创建一个小悬浮窗。初始位置为屏幕的右部中间位置。
     */
    public static void createSmallWindow(Context context) {
        WindowManager windowManager = getWindowManager(context);
        int screenWidth = windowManager.getDefaultDisplay().getWidth();
        int screenHeight = windowManager.getDefaultDisplay().getHeight();
        if (smallWindow == null) {
            smallWindow = new FloatWindowSmallView(context);
            if (smallWindowParams == null) {
                smallWindowParams = new LayoutParams();
                smallWindowParams.type = LayoutParams.TYPE_SYSTEM_ALERT;
                smallWindowParams.format = PixelFormat.RGBA_8888;
                smallWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | LayoutParams.FLAG_NOT_FOCUSABLE;
                smallWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
                smallWindowParams.width = FloatWindowSmallView.windowViewWidth;
                smallWindowParams.height = FloatWindowSmallView.windowViewHeight;
                smallWindowParams.x = screenWidth;
                smallWindowParams.y = screenHeight / 2;
            }
            smallWindow.setParams(smallWindowParams);
            windowManager.addView(smallWindow, smallWindowParams);
        }
    }

    /**
     * 将小悬浮窗从屏幕上移除。
     */
    public static void removeSmallWindow(Context context) {
        if (smallWindow != null) {
            WindowManager windowManager = getWindowManager(context);
            windowManager.removeView(smallWindow);
            smallWindow = null;
        }
    }

    private static WindowManager getWindowManager(Context context) {
        if (mWindowManager == null) {
            mWindowManager = (WindowManager) context
                    .getSystemService(Context.WINDOW_SERVICE);
        }
        return mWindowManager;
    }

创建小火箭的代码如下:

/**
     * 创建一个火箭发射台,位置为屏幕底部。
     */
    public static void createLauncher(Context context) {
        WindowManager windowManager = getWindowManager(context);
        int screenWidth = windowManager.getDefaultDisplay().getWidth();
        int screenHeight = windowManager.getDefaultDisplay().getHeight();
        if (rocketLauncher == null) {
            rocketLauncher = new RocketLauncher(context);
            if (launcherParams == null) {
                launcherParams = new LayoutParams();
                launcherParams.x = screenWidth / 2 - RocketLauncher.width / 2;
                launcherParams.y = screenHeight - RocketLauncher.height;
                launcherParams.type = LayoutParams.TYPE_PHONE;
                launcherParams.format = PixelFormat.RGBA_8888;
                launcherParams.gravity = Gravity.LEFT | Gravity.TOP;
                launcherParams.width = RocketLauncher.width;
                launcherParams.height = RocketLauncher.height;
            }
            windowManager.addView(rocketLauncher, launcherParams);
        }
    }

    /**
     * 将火箭发射台从屏幕上移除。
     */
    public static void removeLauncher(Context context) {
        if (rocketLauncher != null) {
            WindowManager windowManager = getWindowManager(context);
            windowManager.removeView(rocketLauncher);
            rocketLauncher = null;
        }
    }

    /**
     * 更新火箭发射台的显示状态。
     */
    public static void updateLauncher() {
        if (rocketLauncher != null) {
            rocketLauncher.updateLauncherStatus(isReadyToLaunch());
        }
    }
/**
     * 判断小火箭是否准备好发射了。
     * 
     * @return 当火箭被发到发射台上返回true,否则返回false。
     */
    public static boolean isReadyToLaunch() {
        if ((smallWindowParams.x > launcherParams.x && smallWindowParams.x
                + smallWindowParams.width < launcherParams.x
                + launcherParams.width)
                && (smallWindowParams.y + smallWindowParams.height > launcherParams.y)) {
            return true;
        }
        return false;
    }

下面看FloatWindowSmallView 里面的代码
主要是onTouchEvent方法

@Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            isPressed = true;
            // 手指按下时记录必要数据,纵坐标的值都需要减去状态栏高度
            xInView = event.getX();
            yInView = event.getY();
            xDownInScreen = event.getRawX();
            yDownInScreen = event.getRawY() - getStatusBarHeight();
            xInScreen = event.getRawX();
            yInScreen = event.getRawY() - getStatusBarHeight();
            break;
        case MotionEvent.ACTION_MOVE:
            xInScreen = event.getRawX();
            yInScreen = event.getRawY() - getStatusBarHeight();
            // 手指移动的时候更新小悬浮窗的状态和位置
            updateViewStatus();
            updateViewPosition();
            break;
        case MotionEvent.ACTION_UP:
            isPressed = false;
            if (MyWindowManager.isReadyToLaunch()) {
                launchRocket();//符合则发射
            } else {
                updateViewStatus();
                // 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
                if (xDownInScreen == xInScreen && yDownInScreen == yInScreen) {

                    openFloatMovie();
                }
            }
            break;
        default:
            break;
        }
        return true;
    }

/**
     * 用于发射小火箭。
     */
    private void launchRocket() {
        MyWindowManager.removeLauncher(getContext());
        new LaunchTask().execute();
    }

    /**
     * 开始执行发射小火箭的任务。
     * 
     * @author guolin
     */
    class LaunchTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            // 在这里对小火箭的位置进行改变,从而产生火箭升空的效果
            while (mParams.y > 0) {
                mParams.y = mParams.y - 10;
                publishProgress();
                try {
                    Thread.sleep(8);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            windowManager.updateViewLayout(FloatWindowSmallView.this, mParams);
        }

        @Override
        protected void onPostExecute(Void result) {
            // 火箭升空结束后,回归到悬浮窗状态
            updateViewStatus();

            openFloatMovie();
        }

private void openFloatMovie() {
        Intent mIntent = new Intent("createUI");
        mIntent.setClass(getContext(), MediaPlaybackService.class);
        getContext().startService(mIntent);
        MyWindowManager.removeSmallWindow(getContext());
    }

    }
/**
     * 更新小悬浮窗在屏幕中的位置。
     */
    private void updateViewPosition() {
        mParams.x = (int) (xInScreen - xInView);
        mParams.y = (int) (yInScreen - yInView);
        windowManager.updateViewLayout(this, mParams);
        MyWindowManager.updateLauncher();
    }

    /**
     * 更新View的显示状态,判断是显示悬浮窗还是小火箭。
     */
    private void updateViewStatus() {
        if (isPressed && rocketImg.getVisibility() != View.VISIBLE) {
            mParams.width = rocketWidth;
            mParams.height = rocketHeight;
            windowManager.updateViewLayout(this, mParams);
            smallWindowLayout.setVisibility(View.GONE);
            rocketImg.setVisibility(View.VISIBLE);
            MyWindowManager.createLauncher(getContext());
        } else if (!isPressed) {
            mParams.width = windowViewWidth;
            mParams.height = windowViewHeight;
            windowManager.updateViewLayout(this, mParams);
            smallWindowLayout.setVisibility(View.VISIBLE);
            rocketImg.setVisibility(View.GONE);
            MyWindowManager.removeLauncher(getContext());
        }
    }
    /**
     * 用于获取状态栏的高度。
     * 
     * @return 返回状态栏高度的像素值。
     */
    private int getStatusBarHeight() {
        if (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;
    }
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    悬窗播放视频,让你聊天看视频两不误(下)