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

下面实现最小化悬窗,点击继续悬窗播放,拖动小火箭效果。

这部分代码借鉴了网上的小火箭效果

点击悬窗视频的一个按钮启动另一个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;
    }
时间: 2024-10-09 21:30:24

悬窗播放视频,让你聊天看视频两不误(下)的相关文章

cordova使用webrtc与网页端及移动端视频、语音聊天

最近在做一个移动端与移动端.网页端文字.视频.语音聊天的功能.文字聊天使用websocket,在网上很多资料,也没什么难度.但是在视频.语音聊天上遇到了小小的难点.之前一直在找一些SDK想快速开发,例如opentok.云通讯等,但是项目的使用环境是内网,这些SDK必须要在外网情况下才能使用,需要在他们的服务器上获取信令.后来就想办法自己用webrtc做一个视频语音聊天,因为已经用了websocket了.在webrtc的官网,看源码安卓有3G多,编译后差不多9G,直接吓尿了.就算写了插件给cord

关灯看视频(Turn Off the Lights)

插件介绍 随着使用互联网的人越来越多在网络上看视频已是常事一些相关的软件就运应而生今天为大家推荐一个能够提高用户们看视频体验的插件.关灯看视频Turn Off the Lights观看视频时自动调暗页面让您仿佛置身于电影院中只要轻轻按下灯的开关页面就会暗淡下去. 然后您就可以专心享受视频了. 再按一次开关页面就会恢复回原来的样子.Turn Off the Lights是一个轻量而实用的插件它为更舒适的观看体验而设计. 它适用于所有已知的视频网站例如 YouTube. Vimeo. Dailymo

从开发者的角度解释网上看视频出现的各种问题

本文从开发者的角度给大家用通俗的语言来解释一下有关音视频播放的问题. 1. 为什么在视频网站上播放1080P视频有时候不是特别清晰? 1080P代表视频的分辨率是1920x1080,对于图像而言,分辨率越高,清晰度也越高:但是视频不同,视频是由多帧图像组成的,为了减少存储空间.便于传播,视频中的图像都是经过了一定的算法压缩,而压缩则必然导致失真. 在视频压缩算法中,有一个衡量压缩比率的参数,叫做:码率.它代表一秒钟的视频数据大小,例如:10Mb/s,代表1秒钟有10M bit的视频数据,对于YU

Mac版爱奇艺看视频过几分钟就会黑屏?Mac版爱奇艺自动休眠如何取消?

最近很多网友再问"我的Mac版爱奇艺客户端看视频播放几分钟就会自动锁屏然后黑屏",你有没有遇到同样的问题呢?你可能需要对爱奇艺Mac客户端的设置做一个小小的改动,操作非常简单,但是效果非常好,以后用苹果电脑爱奇艺客户端看视频再也不用担心中途黑屏问题啦!来学学取消Mac版爱奇艺自动休眠功能的图文步骤吧!取消Mac版爱奇艺播放视频自动休眠的具体步骤:一.首先打开爱奇艺客户端,然后选择桌面左上角的"爱奇艺"字样,选择下拉菜单的"偏好设置"选项.如下图所

ubuntu网页看视频

ubuntu上使用火狐和chromium都无法在网页看视频,玩三国杀,安装adobe flash也不管用,最后尝试下载chrome,安装成功后就直接可以看视频,玩三国了 下载google-chrome-stable_current_i386_35.0.1916.114.deb 执行指令sudo dpkg -i google-chrome-stable_current_i386_35.0.1916.114.deb 安装成功,可以直接使用了

客观的聊聊看视频学习的方式到底如何

QQ群522720170,无商业广告,每日干货电子书+视频分享 荔枝FM手机客户端搜索"挨踢脱口秀"即可订阅我们 为什么写这篇文章 原因很简单,无非就是两个方面:有人觉得视频学习效果不好而有人觉得视频学习效果很好.你看两个极端吧,所以为了让大家能提高自己分辨.判断事情的能力就决定以比较客观的角度来聊聊.  事先声明:纯属个人观点,以下我说的有可能都是错的.请勿漫骂,不喜勿看!不管说的对不对能给大家提供多一点的思考方式不是什么坏事.有时候不是我们能力差,而是思维方式太狭隘. 本文想说啥呢

Android IOS WebRTC 音视频开发总结(四八)-- 从商业和技术的角度看视频行业的机会

本文主要从不同角度介绍视频行业的机会,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,欢迎关注个人微信公众号blacker ------------------------------------------------------------- 这段时间在北京呆了10天左右,相对深圳,这边有点冷,也比较干燥,期间发生了两件大事: 1,优酷和土豆被阿里招安了 2,搜狐出品人大会召开了 第一件事是大事,但跟我们关系不大,第二件事不算大事,但跟我们关系不小,原因如下: 1,优酷土豆

浏览器看视频时,不断上传,禁止方法

在看视频的时候,发现浏览器上传的速度很快,百度之后,原来是是flash的对等网络互助没关闭,也就是说,你在下载的同时,也要上传东西,从而充当服务器的角色,视频网站可以减少自己的带宽的占用. 关闭方法: 1.打开http://www.macromedia.com/support/documentation/cn/flashplayer/help/settings_manager09.html 勾选下图: 2.在C:\Windows\System32\Macromed\Flash下找到mms.cfg

vue播放rtmp、hls m3u8格式视频

选用Video.js作为视频播放库,如果要支持hls m3u8还需要videojs-contrib-hls组件的支持. 安装Video.js npm install --save video.js 安装videojs-contrib-hls npm install --save videojs-contrib-hls 创建一个vue的播放组件 src/components/VideoPlayer/index.vue <template> <div> <video ref=&q