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

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

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

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

       @Overridepublic 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方法

@Overridepublic 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 {@Overrideprotected 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;}@Overrideprotected void onProgressUpdate(Void... values) {windowManager.updateViewLayout(FloatWindowSmallView.this, mParams);}@Overrideprotected 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;}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部