From f82d7d73e9cb5f764b305008fea6cfcc47a21ac4 Mon Sep 17 00:00:00 2001 From: guoshuyu Date: Mon, 25 Dec 2017 16:08:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=A1=8C=E9=9D=A2=E6=82=AC?= =?UTF-8?q?=E6=B5=AE=E7=AA=97=E7=9A=84demo=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- app/src/main/AndroidManifest.xml | 18 +- .../example/gsyvideoplayer/EmptyActivity.java | 28 ++ .../example/gsyvideoplayer/MainActivity.java | 7 +- .../gsyvideoplayer/WindowActivity.java | 105 ++++++++ .../gsyvideoplayer/utils/JumpUtils.java | 11 + .../utils/floatUtil/FloatActivity.java | 82 ++++++ .../utils/floatUtil/FloatLifecycle.java | 129 +++++++++ .../utils/floatUtil/FloatPhone.java | 106 ++++++++ .../utils/floatUtil/FloatToast.java | 95 +++++++ .../utils/floatUtil/FloatView.java | 38 +++ .../utils/floatUtil/FloatWindow.java | 189 +++++++++++++ .../utils/floatUtil/IFloatWindow.java | 30 +++ .../utils/floatUtil/IFloatWindowImpl.java | 253 ++++++++++++++++++ .../utils/floatUtil/LifecycleListener.java | 15 ++ .../utils/floatUtil/MoveType.java | 24 ++ .../utils/floatUtil/PermissionListener.java | 11 + .../utils/floatUtil/Screen.java | 21 ++ .../gsyvideoplayer/utils/floatUtil/Util.java | 57 ++++ .../gsyvideoplayer/video/FloatingVideo.java | 188 +++++++++++++ .../gsyvideoplayer/view/FloatPlayerView.java | 74 +++++ app/src/main/res/layout/activity_empty.xml | 12 + app/src/main/res/layout/activity_main.xml | 7 + app/src/main/res/layout/activity_window.xml | 28 ++ .../main/res/layout/layout_floating_play.xml | 14 + .../main/res/layout/layout_floating_video.xml | 24 ++ dependencies.gradle | 4 +- 27 files changed, 1567 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/com/example/gsyvideoplayer/EmptyActivity.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/WindowActivity.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatActivity.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatLifecycle.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatPhone.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatToast.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatView.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatWindow.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindow.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindowImpl.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/LifecycleListener.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/MoveType.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/PermissionListener.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Screen.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Util.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/video/FloatingVideo.java create mode 100644 app/src/main/java/com/example/gsyvideoplayer/view/FloatPlayerView.java create mode 100644 app/src/main/res/layout/activity_empty.xml create mode 100644 app/src/main/res/layout/activity_window.xml create mode 100644 app/src/main/res/layout/layout_floating_play.xml create mode 100644 app/src/main/res/layout/layout_floating_video.xml diff --git a/app/build.gradle b/app/build.gradle index f94a6da..3d2463c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,6 +52,7 @@ dependencies { def androidDependencies = rootProject.ext.androidDependencies def dataDependencies = rootProject.ext.dataDependencies annotationProcessor viewDependencies.apt_butterKnife + //debugCompile dataDependencies.leakcanary compile viewDependencies.butterKnife compile androidDependencies.recyclerView compile viewDependencies.DanmakuFlameMaster @@ -62,9 +63,8 @@ dependencies { compile viewDependencies.glideProcessor compile androidDependencies.support_v4 compile androidDependencies.design - //debugCompile dataDependencies.leakcanary - compile project(':gsyVideoPlayer') + compile project(':gsyVideoPlayer') //jcenter //compile "com.shuyu:GSYVideoPlayer:$gsyVideoVersion" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6e04efc..ce25d4d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -8,7 +9,7 @@ -   + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/gsyvideoplayer/EmptyActivity.java b/app/src/main/java/com/example/gsyvideoplayer/EmptyActivity.java new file mode 100644 index 0000000..a96a4ec --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/EmptyActivity.java @@ -0,0 +1,28 @@ +package com.example.gsyvideoplayer; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.widget.Button; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class EmptyActivity extends AppCompatActivity { + + @BindView(R.id.jump_other) + Button jumpOther; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_empty); + ButterKnife.bind(this); + } + + @OnClick(R.id.jump_other) + public void onViewClicked() { + startActivity(new Intent(this, EmptyActivity.class)); + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/MainActivity.java b/app/src/main/java/com/example/gsyvideoplayer/MainActivity.java index f3058ac..b11874f 100644 --- a/app/src/main/java/com/example/gsyvideoplayer/MainActivity.java +++ b/app/src/main/java/com/example/gsyvideoplayer/MainActivity.java @@ -30,7 +30,7 @@ public class MainActivity extends AppCompatActivity { } @OnClick({R.id.open_btn, R.id.list_btn, R.id.list_btn_2, R.id.list_detail, R.id.clear_cache, R.id.recycler, R.id.recycler_2, R.id.list_detail_list, R.id.web_detail, R.id.danmaku_video, R.id.fragment_video, - R.id.more_type, R.id.input_type, R.id.open_btn_empty, R.id.open_control, R.id.open_filter, R.id.open_btn_pick, R.id.open_btn_auto, R.id.open_scroll}) + R.id.more_type, R.id.input_type, R.id.open_btn_empty, R.id.open_control, R.id.open_filter, R.id.open_btn_pick, R.id.open_btn_auto, R.id.open_scroll, R.id.open_window}) public void onClick(View view) { switch (view.getId()) { case R.id.open_btn: @@ -101,7 +101,10 @@ public class MainActivity extends AppCompatActivity { //列表自动播放 JumpUtils.goToScrollDetailPlayer(this); break; - + case R.id.open_window: + //多窗体下的悬浮窗 + JumpUtils.goToScrollWindow(this); + break; case R.id.clear_cache: //清理缓存 GSYVideoManager.clearAllDefaultCache(MainActivity.this); diff --git a/app/src/main/java/com/example/gsyvideoplayer/WindowActivity.java b/app/src/main/java/com/example/gsyvideoplayer/WindowActivity.java new file mode 100644 index 0000000..5a4fafd --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/WindowActivity.java @@ -0,0 +1,105 @@ +package com.example.gsyvideoplayer; + +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.RequiresApi; +import android.support.v7.app.AppCompatActivity; +import android.view.View; +import android.view.animation.BounceInterpolator; +import android.widget.Button; + + +import com.example.gsyvideoplayer.utils.floatUtil.FloatWindow; +import com.example.gsyvideoplayer.utils.floatUtil.MoveType; +import com.example.gsyvideoplayer.utils.floatUtil.Screen; +import com.example.gsyvideoplayer.utils.floatUtil.Util; +import com.example.gsyvideoplayer.view.FloatPlayerView; +import com.shuyu.gsyvideoplayer.GSYVideoManager; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +/** + * 多窗体下的悬浮窗页面 + */ +public class WindowActivity extends AppCompatActivity { + + @BindView(R.id.start_window) + Button startWindow; + @BindView(R.id.jump_other) + Button jumpOther; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_window); + ButterKnife.bind(this); + if (Build.VERSION.SDK_INT >= 23) { + if (!Util.hasPermission(this)) { + requestAlertWindowPermission(); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + GSYVideoManager.instance().releaseMediaPlayer(); + /** + * 这里在返回主页的时候销毁了,因为不想和DEMO中其他页面冲突 + */ + FloatWindow.destroy(); + } + + @RequiresApi(api = 23) + private void requestAlertWindowPermission() { + Intent intent = new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION"); + intent.setData(Uri.parse("package:" + getPackageName())); + startActivityForResult(intent, 1); + } + + + @RequiresApi(api = 23) + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (Build.VERSION.SDK_INT >= 23){ + //todo 用23以上编译即可出现canDrawOverlays + if (Util.hasPermission(this)) { + + } else { + this.finish(); + } + } + } + + @OnClick({R.id.start_window, R.id.jump_other}) + public void onViewClicked(View view) { + switch (view.getId()) { + case R.id.start_window: + if (FloatWindow.get() != null) { + return; + } + FloatPlayerView floatPlayerView = new FloatPlayerView(getApplicationContext()); + FloatWindow + .with(getApplicationContext()) + .setView(floatPlayerView) + .setWidth(Screen.width, 0.4f) + .setHeight(Screen.width, 0.4f) + .setX(Screen.width, 0.8f) + .setY(Screen.height, 0.3f) + .setMoveType(MoveType.slide) + .setFilter(false) + .setMoveStyle(500, new BounceInterpolator()) + .build(); + FloatWindow.get().show(); + break; + case R.id.jump_other: + startActivity(new Intent(this, EmptyActivity.class)); + break; + } + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/JumpUtils.java b/app/src/main/java/com/example/gsyvideoplayer/utils/JumpUtils.java index 1cac8b1..14f0d56 100644 --- a/app/src/main/java/com/example/gsyvideoplayer/utils/JumpUtils.java +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/JumpUtils.java @@ -26,6 +26,7 @@ import com.example.gsyvideoplayer.RecyclerView2Activity; import com.example.gsyvideoplayer.RecyclerViewActivity; import com.example.gsyvideoplayer.ScrollingActivity; import com.example.gsyvideoplayer.WebDetailActivity; +import com.example.gsyvideoplayer.WindowActivity; /** * Created by shuyu on 2016/11/11. @@ -168,6 +169,16 @@ public class JumpUtils { activity.startActivity(intent); } + /** + * 跳转到详情播放 + * + * @param activity + */ + public static void goToScrollWindow(Activity activity) { + Intent intent = new Intent(activity, WindowActivity.class); + activity.startActivity(intent); + } + /** * 跳转到详情播放 * diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatActivity.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatActivity.java new file mode 100644 index 0000000..f4dfa10 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatActivity.java @@ -0,0 +1,82 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.support.annotation.RequiresApi; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用于在内部自动申请权限 + * https://github.com/yhaolpz + */ + +public class FloatActivity extends Activity { + + private static List mPermissionListenerList; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (Build.VERSION.SDK_INT >= 23){ + requestAlertWindowPermission(); + } + } + + @RequiresApi(api = 23) + private void requestAlertWindowPermission() { + Intent intent = new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION"); + intent.setData(Uri.parse("package:" + getPackageName())); + startActivityForResult(intent, 1); + } + + + @RequiresApi(api = 23) + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (Build.VERSION.SDK_INT >= 23){ + //todo 用23以上编译即可出现canDrawOverlays + if (Util.hasPermission(this)) { + mPermissionListener.onSuccess(); + } else { + mPermissionListener.onFail(); + } + } + finish(); + } + + static synchronized void request(Context context, PermissionListener permissionListener) { + if (mPermissionListenerList == null) { + mPermissionListenerList = new ArrayList<>(); + mPermissionListener = new PermissionListener() { + @Override + public void onSuccess() { + for (PermissionListener listener : mPermissionListenerList) { + listener.onSuccess(); + } + } + + @Override + public void onFail() { + for (PermissionListener listener : mPermissionListenerList) { + listener.onFail(); + } + } + }; + Intent intent = new Intent(context, FloatActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + mPermissionListenerList.add(permissionListener); + } + + + private static PermissionListener mPermissionListener; +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatLifecycle.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatLifecycle.java new file mode 100644 index 0000000..962ab27 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatLifecycle.java @@ -0,0 +1,129 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.app.Activity; +import android.app.Application; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Handler; + +/** + * Created by yhao on 17-12-1. + * 用于控制悬浮窗显示周期 + * 使用了三种方法针对返回桌面时隐藏悬浮按钮 + * 1.startCount计数,针对back到桌面可以及时隐藏 + * 2.监听home键,从而及时隐藏 + * 3.resumeCount计时,针对一些只执行onPause不执行onStop的奇葩情况 + */ + +class FloatLifecycle extends BroadcastReceiver implements Application.ActivityLifecycleCallbacks { + + private static final String SYSTEM_DIALOG_REASON_KEY = "reason"; + private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; + private static final long delay = 300; + private Handler mHandler; + private Class[] activities; + private boolean showFlag; + private int startCount; + private int resumeCount; + private boolean appBackground; + private LifecycleListener mLifecycleListener; + + + FloatLifecycle(Context applicationContext, boolean showFlag, Class[] activities, LifecycleListener lifecycleListener) { + this.showFlag = showFlag; + this.activities = activities; + mLifecycleListener = lifecycleListener; + mHandler = new Handler(); + ((Application) applicationContext).registerActivityLifecycleCallbacks(this); + applicationContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); + } + + + private boolean needShow(Activity activity) { + if (activities == null) { + return true; + } + for (Class a : activities) { + if (a.isInstance(activity)) { + return showFlag; + } + } + return !showFlag; + } + + + @Override + public void onActivityResumed(Activity activity) { + resumeCount++; + if (needShow(activity)) { + mLifecycleListener.onShow(); + } else { + //mLifecycleListener.onHide(); + } + if (appBackground) { + appBackground = false; + } + } + + @Override + public void onActivityPaused(Activity activity) { + resumeCount--; + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + if (resumeCount == 0) { + appBackground = true; + //mLifecycleListener.onPostHide(); + } + } + }, delay); + + } + + @Override + public void onActivityStarted(Activity activity) { + startCount++; + } + + + @Override + public void onActivityStopped(Activity activity) { + startCount--; + if (startCount == 0) { + //mLifecycleListener.onHide(); + } + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action != null && action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { + String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY); + if (SYSTEM_DIALOG_REASON_HOME_KEY.equals(reason)) { + //mLifecycleListener.onHide(); + } + } + } + + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + + } + + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + + } + + @Override + public void onActivityDestroyed(Activity activity) { + + } + + +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatPhone.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatPhone.java new file mode 100644 index 0000000..a3797ce --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatPhone.java @@ -0,0 +1,106 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.view.View; +import android.view.WindowManager; + +/** + * Created by yhao on 17-11-14. + * 7.1及以上需申请权限 + */ + +class FloatPhone extends FloatView { + + private final Context mContext; + + private final WindowManager mWindowManager; + private final WindowManager.LayoutParams mLayoutParams; + private View mView; + private int mX, mY; + + FloatPhone(Context applicationContext) { + mContext = applicationContext; + mWindowManager = (WindowManager) applicationContext.getSystemService(Context.WINDOW_SERVICE); + mLayoutParams = new WindowManager.LayoutParams(); + } + + @Override + public void setSize(int width, int height) { + mLayoutParams.width = width; + mLayoutParams.height = height; + } + + @Override + public void setView(View view) { + mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; + mLayoutParams.windowAnimations = 0; + mView = view; + } + + @Override + public void setGravity(int gravity, int xOffset, int yOffset) { + mLayoutParams.gravity = gravity; + mLayoutParams.x = mX = xOffset; + mLayoutParams.y = mY = yOffset; + } + + + @Override + public void init() { + if (Util.hasPermission(mContext)) { + mLayoutParams.format = PixelFormat.RGBA_8888; + mWindowManager.addView(mView, mLayoutParams); + } else { + FloatActivity.request(mContext, new PermissionListener() { + @Override + public void onSuccess() { + mLayoutParams.format = PixelFormat.RGBA_8888; + mWindowManager.addView(mView, mLayoutParams); + } + + @Override + public void onFail() { + + } + }); + } + } + + @Override + public void dismiss() { + mWindowManager.removeView(mView); + } + + @Override + public void updateXY(int x, int y) { + mLayoutParams.x = mX = x; + mLayoutParams.y = mY = y; + mWindowManager.updateViewLayout(mView, mLayoutParams); + } + + @Override + void updateX(int x) { + mLayoutParams.x = mX = x; + mWindowManager.updateViewLayout(mView, mLayoutParams); + + } + + @Override + void updateY(int y) { + mLayoutParams.y = mY = y; + mWindowManager.updateViewLayout(mView, mLayoutParams); + } + + @Override + int getX() { + return mX; + } + + @Override + int getY() { + return mY; + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatToast.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatToast.java new file mode 100644 index 0000000..9388634 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatToast.java @@ -0,0 +1,95 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.content.Context; +import android.view.View; +import android.view.WindowManager; +import android.widget.Toast; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * 自定义 toast 方式,无需申请权限 + */ + +class FloatToast extends FloatView { + + + private Toast toast; + + private Object mTN; + private Method show; + private Method hide; + + private int mWidth; + private int mHeight; + + + FloatToast(Context applicationContext) { + toast = new Toast(applicationContext); + } + + + @Override + public void setSize(int width, int height) { + mWidth = width; + mHeight = height; + } + + @Override + public void setView(View view) { + toast.setView(view); + initTN(); + } + + @Override + public void setGravity(int gravity, int xOffset, int yOffset) { + toast.setGravity(gravity, xOffset, yOffset); + } + + @Override + public void init() { + try { + show.invoke(mTN); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void dismiss() { + try { + hide.invoke(mTN); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + private void initTN() { + try { + Field tnField = toast.getClass().getDeclaredField("mTN"); + tnField.setAccessible(true); + mTN = tnField.get(toast); + show = mTN.getClass().getMethod("show"); + hide = mTN.getClass().getMethod("hide"); + + Field tnParamsField = mTN.getClass().getDeclaredField("mParams"); + tnParamsField.setAccessible(true); + WindowManager.LayoutParams params = (WindowManager.LayoutParams) tnParamsField.get(mTN); + params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + params.width = mWidth; + params.height = mHeight; + params.windowAnimations = 0; + Field tnNextViewField = mTN.getClass().getDeclaredField("mNextView"); + tnNextViewField.setAccessible(true); + tnNextViewField.set(mTN, toast.getView()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatView.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatView.java new file mode 100644 index 0000000..86b7e7c --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatView.java @@ -0,0 +1,38 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.view.View; + +/** + * Created by yhao on 17-11-14. + * https://github.com/yhaolpz + */ + +abstract class FloatView { + + abstract void setSize(int width, int height); + + abstract void setView(View view); + + abstract void setGravity(int gravity, int xOffset, int yOffset); + + abstract void init(); + + abstract void dismiss(); + + void updateXY(int x, int y) { + } + + void updateX(int x) { + } + + void updateY(int y) { + } + + int getX() { + return 0; + } + + int getY() { + return 0; + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatWindow.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatWindow.java new file mode 100644 index 0000000..2e1609a --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/FloatWindow.java @@ -0,0 +1,189 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.animation.TimeInterpolator; +import android.content.Context; +import android.support.annotation.LayoutRes; +import android.support.annotation.MainThread; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by yhao on 2017/12/22. + * https://github.com/yhaolpz + */ + +public class FloatWindow { + + private FloatWindow() { + + } + + private static final String mDefaultTag = "default_float_window_tag"; + private static Map mFloatWindowMap; + + public static IFloatWindow get() { + return get(mDefaultTag); + } + + public static IFloatWindow get(@NonNull String tag) { + return mFloatWindowMap == null ? null : mFloatWindowMap.get(tag); + } + + private static B mBuilder = null; + + @MainThread + public static B with(@NonNull Context applicationContext) { + return mBuilder = new B(applicationContext); + } + + public static void destroy() { + destroy(mDefaultTag); + } + + public static void destroy(String tag) { + if (mFloatWindowMap == null || !mFloatWindowMap.containsKey(tag)) { + return; + } + mFloatWindowMap.get(tag).dismiss(); + mFloatWindowMap.remove(tag); + } + + public static class B { + Context mApplicationContext; + View mView; + private int mLayoutId; + int mWidth = ViewGroup.LayoutParams.WRAP_CONTENT; + int mHeight = ViewGroup.LayoutParams.WRAP_CONTENT; + int gravity = Gravity.TOP | Gravity.START; + int xOffset; + int yOffset; + boolean mShow = true; + Class[] mActivities; + int mMoveType = MoveType.fixed; + long mDuration = 300; + TimeInterpolator mInterpolator; + private String mTag = mDefaultTag; + + private B() { + + } + + B(Context applicationContext) { + mApplicationContext = applicationContext; + } + + public B setView(@NonNull View view) { + mView = view; + return this; + } + + public B setView(@LayoutRes int layoutId) { + mLayoutId = layoutId; + return this; + } + + public B setWidth(int width) { + mWidth = width; + return this; + } + + public B setHeight(int height) { + mHeight = height; + return this; + } + + public B setWidth(@Screen.screenType int screenType, float ratio) { + mWidth = (int) ((screenType == Screen.width ? + Util.getScreenWidth(mApplicationContext) : + Util.getScreenHeight(mApplicationContext)) * ratio); + return this; + } + + + public B setHeight(@Screen.screenType int screenType, float ratio) { + mHeight = (int) ((screenType == Screen.width ? + Util.getScreenWidth(mApplicationContext) : + Util.getScreenHeight(mApplicationContext)) * ratio); + return this; + } + + + public B setX(int x) { + xOffset = x; + return this; + } + + public B setY(int y) { + yOffset = y; + return this; + } + + public B setX(@Screen.screenType int screenType, float ratio) { + xOffset = (int) ((screenType == Screen.width ? + Util.getScreenWidth(mApplicationContext) : + Util.getScreenHeight(mApplicationContext)) * ratio); + return this; + } + + public B setY(@Screen.screenType int screenType, float ratio) { + yOffset = (int) ((screenType == Screen.width ? + Util.getScreenWidth(mApplicationContext) : + Util.getScreenHeight(mApplicationContext)) * ratio); + return this; + } + + + /** + * 设置 Activity 过滤器,用于指定在哪些界面显示悬浮窗,默认全部界面都显示 + * + * @param show  过滤类型,子类类型也会生效 + * @param activities  过滤界面 + */ + public B setFilter(boolean show, @NonNull Class... activities) { + mShow = show; + mActivities = activities; + return this; + } + + + public B setMoveType(@MoveType.MOVE_TYPE int moveType) { + mMoveType = moveType; + return this; + } + + public B setMoveStyle(long duration, @Nullable TimeInterpolator interpolator) { + mDuration = duration; + mInterpolator = interpolator; + return this; + } + + public B setTag(@NonNull String tag) { + mTag = tag; + return this; + } + + public void build() { + if (mFloatWindowMap == null) { + mFloatWindowMap = new HashMap<>(); + } + if (mFloatWindowMap.containsKey(mTag)) { + throw new IllegalArgumentException("FloatWindow of this tag has been added, Please set a new tag for the new FloatWindow"); + } + if (mView == null && mLayoutId == 0) { + throw new IllegalArgumentException("View has not been set!"); + } + if (mView == null) { + mView = Util.inflate(mApplicationContext, mLayoutId); + } + IFloatWindow floatWindowImpl = new IFloatWindowImpl(this); + mFloatWindowMap.put(mTag, floatWindowImpl); + } + + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindow.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindow.java new file mode 100644 index 0000000..4cc25c0 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindow.java @@ -0,0 +1,30 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.view.View; + +/** + * Created by yhao on 2017/12/22. + * https://github.com/yhaolpz + */ + +public abstract class IFloatWindow { + public abstract void show(); + + public abstract void hide(); + + public abstract int getX(); + + public abstract int getY(); + + public abstract void updateX(int x); + + public abstract void updateX(@Screen.screenType int screenType,float ratio); + + public abstract void updateY(int y); + + public abstract void updateY(@Screen.screenType int screenType,float ratio); + + public abstract View getView(); + + abstract void dismiss(); +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindowImpl.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindowImpl.java new file mode 100644 index 0000000..e4422da --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/IFloatWindowImpl.java @@ -0,0 +1,253 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.TimeInterpolator; +import android.animation.ValueAnimator; +import android.os.Build; +import android.view.MotionEvent; +import android.view.View; +import android.view.animation.DecelerateInterpolator; + +/** + * Created by yhao on 2017/12/22. + * https://github.com/yhaolpz + */ + +public class IFloatWindowImpl extends IFloatWindow { + + + private FloatWindow.B mB; + private FloatView mFloatView; + private FloatLifecycle mFloatLifecycle; + private boolean isShow; + private boolean once = true; + private ValueAnimator mAnimator; + private TimeInterpolator mDecelerateInterpolator; + + private IFloatWindowImpl() { + + } + + IFloatWindowImpl(FloatWindow.B b) { + mB = b; + if (mB.mMoveType == MoveType.fixed) { + if (Build.VERSION.SDK_INT >=25) { + mFloatView = new FloatPhone(b.mApplicationContext); + } else { + mFloatView = new FloatToast(b.mApplicationContext); + } + } else { + mFloatView = new FloatPhone(b.mApplicationContext); + initTouchEvent(); + } + mFloatView.setSize(mB.mWidth, mB.mHeight); + mFloatView.setGravity(mB.gravity, mB.xOffset, mB.yOffset); + mFloatView.setView(mB.mView); + mFloatLifecycle = new FloatLifecycle(mB.mApplicationContext, mB.mShow, mB.mActivities, new LifecycleListener() { + @Override + public void onShow() { + show(); + } + + @Override + public void onHide() { + hide(); + } + + @Override + public void onPostHide() { + postHide(); + } + }); + } + + @Override + public void show() { + if (once) { + mFloatView.init(); + once = false; + isShow = true; + } else { + if (isShow) return; + getView().setVisibility(View.VISIBLE); + isShow = true; + } + } + + @Override + public void hide() { + if (once || !isShow) return; + getView().setVisibility(View.INVISIBLE); + isShow = false; + } + + @Override + void dismiss() { + mFloatView.dismiss(); + isShow = false; + } + + @Override + public void updateX(int x) { + checkMoveType(); + mB.xOffset = x; + mFloatView.updateX(x); + } + + @Override + public void updateY(int y) { + checkMoveType(); + mB.yOffset = y; + mFloatView.updateY(y); + } + + @Override + public void updateX(int screenType, float ratio) { + checkMoveType(); + mB.xOffset = (int) ((screenType == Screen.width ? + Util.getScreenWidth(mB.mApplicationContext) : + Util.getScreenHeight(mB.mApplicationContext)) * ratio); + mFloatView.updateX(mB.xOffset); + + } + + @Override + public void updateY(int screenType, float ratio) { + checkMoveType(); + mB.yOffset = (int) ((screenType == Screen.width ? + Util.getScreenWidth(mB.mApplicationContext) : + Util.getScreenHeight(mB.mApplicationContext)) * ratio); + mFloatView.updateY(mB.yOffset); + + } + + @Override + public int getX() { + return mFloatView.getX(); + } + + @Override + public int getY() { + return mFloatView.getY(); + } + + + @Override + public View getView() { + return mB.mView; + } + + void postHide() { + if (once || !isShow) return; + getView().post(new Runnable() { + @Override + public void run() { + getView().setVisibility(View.INVISIBLE); + } + }); + isShow = false; + } + + private void checkMoveType() { + if (mB.mMoveType == MoveType.fixed) { + throw new IllegalArgumentException("FloatWindow of this tag is not allowed to move!"); + } + } + + private void initTouchEvent() { + switch (mB.mMoveType) { + case MoveType.free: + break; + default: + getView().setOnTouchListener(new View.OnTouchListener() { + float lastX, lastY, changeX, changeY; + int newX, newY; + + @Override + public boolean onTouch(View v, MotionEvent event) { + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + lastX = event.getRawX(); + lastY = event.getRawY(); + cancelAnimator(); + break; + case MotionEvent.ACTION_MOVE: + changeX = event.getRawX() - lastX; + changeY = event.getRawY() - lastY; + newX = (int) (mFloatView.getX() + changeX); + newY = (int) (mFloatView.getY() + changeY); + mFloatView.updateXY(newX, newY); + lastX = event.getRawX(); + lastY = event.getRawY(); + break; + case MotionEvent.ACTION_UP: + switch (mB.mMoveType) { + case MoveType.slide: + int startX = mFloatView.getX(); + int endX = (startX * 2 + v.getWidth() > + Util.getScreenWidth(mB.mApplicationContext)) ? + Util.getScreenWidth(mB.mApplicationContext) - v.getWidth() : 0; + mAnimator = ObjectAnimator.ofInt(startX, endX); + mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int x = (int) animation.getAnimatedValue(); + mFloatView.updateX(x); + } + }); + startAnimator(); + break; + case MoveType.back: + PropertyValuesHolder pvhX = PropertyValuesHolder.ofInt("x", mFloatView.getX(), mB.xOffset); + PropertyValuesHolder pvhY = PropertyValuesHolder.ofInt("y", mFloatView.getY(), mB.yOffset); + mAnimator = ObjectAnimator.ofPropertyValuesHolder(pvhX, pvhY); + mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int x = (int) animation.getAnimatedValue("x"); + int y = (int) animation.getAnimatedValue("y"); + mFloatView.updateXY(x, y); + } + }); + startAnimator(); + break; + } + break; + + } + return false; + } + }); + } + } + + private void startAnimator() { + if (mB.mInterpolator == null) { + if (mDecelerateInterpolator == null) { + mDecelerateInterpolator = new DecelerateInterpolator(); + } + mB.mInterpolator = mDecelerateInterpolator; + } + mAnimator.setInterpolator(mB.mInterpolator); + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAnimator.removeAllUpdateListeners(); + mAnimator.removeAllListeners(); + mAnimator = null; + } + }); + mAnimator.setDuration(mB.mDuration).start(); + } + + private void cancelAnimator() { + if (mAnimator != null && mAnimator.isRunning()) { + mAnimator.cancel(); + } + } + +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/LifecycleListener.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/LifecycleListener.java new file mode 100644 index 0000000..9c8f854 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/LifecycleListener.java @@ -0,0 +1,15 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +/** + * Created by yhao on 2017/12/22. + * https://github.com/yhaolpz + */ + +interface LifecycleListener { + + void onShow(); + + void onHide(); + + void onPostHide(); +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/MoveType.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/MoveType.java new file mode 100644 index 0000000..7209e2f --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/MoveType.java @@ -0,0 +1,24 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.support.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by yhao on 2017/12/22. + * https://github.com/yhaolpz + */ + +public class MoveType { + static final int fixed = 0; + public static final int free = 1; + public static final int active = 2; + public static final int slide = 3; + public static final int back = 4; + + @IntDef({fixed, free, active, slide, back}) + @Retention(RetentionPolicy.SOURCE) + @interface MOVE_TYPE { + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/PermissionListener.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/PermissionListener.java new file mode 100644 index 0000000..44be0d1 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/PermissionListener.java @@ -0,0 +1,11 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +/** + * Created by yhao on 2017/11/14. + * https://github.com/yhaolpz + */ +interface PermissionListener { + void onSuccess(); + + void onFail(); +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Screen.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Screen.java new file mode 100644 index 0000000..0d346c0 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Screen.java @@ -0,0 +1,21 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.support.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Created by yhao on 2017/12/23. + * https://github.com/yhaolpz + */ + +public class Screen { + public static final int width = 0; + public static final int height = 1; + + @IntDef({width, height}) + @Retention(RetentionPolicy.SOURCE) + @interface screenType { + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Util.java b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Util.java new file mode 100644 index 0000000..07c47a0 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/utils/floatUtil/Util.java @@ -0,0 +1,57 @@ +package com.example.gsyvideoplayer.utils.floatUtil; + +import android.content.Context; +import android.graphics.Point; +import android.provider.Settings; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; + +import java.lang.reflect.Method; + +/** + * Created by yhao on 2017/12/22. + * https://github.com/yhaolpz + */ + +public class Util { + + + static View inflate(Context applicationContext, int layoutId) { + LayoutInflater inflate = (LayoutInflater) applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + return inflate.inflate(layoutId, null); + } + + public static boolean hasPermission(Context context) { + Boolean result; + try { + Class clazz = Settings.class; + Method canDrawOverlays = clazz.getDeclaredMethod("canDrawOverlays", Context.class); + result = (Boolean) canDrawOverlays.invoke(null, context); + } catch (Exception e) { + result = false; + } + return result; + } + + + private static Point sPoint; + + static int getScreenWidth(Context context) { + if (sPoint == null) { + sPoint = new Point(); + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + wm.getDefaultDisplay().getSize(sPoint); + } + return sPoint.x; + } + + static int getScreenHeight(Context context) { + if (sPoint == null) { + sPoint = new Point(); + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + wm.getDefaultDisplay().getSize(sPoint); + } + return sPoint.y; + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/video/FloatingVideo.java b/app/src/main/java/com/example/gsyvideoplayer/video/FloatingVideo.java new file mode 100644 index 0000000..b8479e6 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/video/FloatingVideo.java @@ -0,0 +1,188 @@ +package com.example.gsyvideoplayer.video; + + +import android.content.Context; +import android.media.AudioManager; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +import com.example.gsyvideoplayer.R; +import com.shuyu.gsyvideoplayer.GSYVideoManager; +import com.shuyu.gsyvideoplayer.utils.Debuger; +import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer; + +import java.util.Timer; +import java.util.TimerTask; + +import static com.shuyu.gsyvideoplayer.utils.CommonUtil.hideNavKey; + +/** + * 多窗体下的悬浮窗页面支持Video + * Created by shuyu on 2017/12/25. + */ + +public class FloatingVideo extends StandardGSYVideoPlayer { + + protected DismissControlViewTimerTask mDismissControlViewTimerTask; + + /** + * 1.5.0开始加入,如果需要不同布局区分功能,需要重载 + */ + public FloatingVideo(Context context, Boolean fullFlag) { + super(context, fullFlag); + } + + public FloatingVideo(Context context) { + super(context); + } + + public FloatingVideo(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void init(Context context) { + if (getActivityContext() != null) { + this.mContext = getActivityContext(); + } else { + this.mContext = context; + } + + initInflate(mContext); + + mTextureViewContainer = (ViewGroup) findViewById(R.id.surface_container); + mStartButton = findViewById(R.id.start); + + if (isInEditMode()) + return; + mScreenWidth = getActivityContext().getResources().getDisplayMetrics().widthPixels; + mScreenHeight = getActivityContext().getResources().getDisplayMetrics().heightPixels; + mAudioManager = (AudioManager) getActivityContext().getApplicationContext().getSystemService(Context.AUDIO_SERVICE); + mStartButton = findViewById(com.shuyu.gsyvideoplayer.R.id.start); + mStartButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + clickStartIcon(); + } + }); + } + + @Override + public int getLayoutId() { + return R.layout.layout_floating_video; + } + + + @Override + protected void startPrepare() { + if (GSYVideoManager.instance().listener() != null) { + GSYVideoManager.instance().listener().onCompletion(); + } + GSYVideoManager.instance().setListener(this); + GSYVideoManager.instance().setPlayTag(mPlayTag); + GSYVideoManager.instance().setPlayPosition(mPlayPosition); + mAudioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + //((Activity) getActivityContext()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + mBackUpPlayingBufferState = -1; + GSYVideoManager.instance().prepare(mUrl, mMapHeadData, mLooping, mSpeed); + setStateAndUi(CURRENT_STATE_PREPAREING); + } + + @Override + public void onAutoCompletion() { + setStateAndUi(CURRENT_STATE_AUTO_COMPLETE); + + mSaveChangeViewTIme = 0; + + if (mTextureViewContainer.getChildCount() > 0) { + mTextureViewContainer.removeAllViews(); + } + + if (!mIfCurrentIsFullscreen) + GSYVideoManager.instance().setLastListener(null); + mAudioManager.abandonAudioFocus(onAudioFocusChangeListener); + //((Activity) getActivityContext()).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + releaseNetWorkState(); + + if (mVideoAllCallBack != null && isCurrentMediaListener()) { + Debuger.printfLog("onAutoComplete"); + mVideoAllCallBack.onAutoComplete(mOriginUrl, mTitle, this); + } + } + + @Override + public void onCompletion() { + //make me normal first + setStateAndUi(CURRENT_STATE_NORMAL); + + mSaveChangeViewTIme = 0; + + if (mTextureViewContainer.getChildCount() > 0) { + mTextureViewContainer.removeAllViews(); + } + + if (!mIfCurrentIsFullscreen) { + GSYVideoManager.instance().setListener(null); + GSYVideoManager.instance().setLastListener(null); + } + GSYVideoManager.instance().setCurrentVideoHeight(0); + GSYVideoManager.instance().setCurrentVideoWidth(0); + + mAudioManager.abandonAudioFocus(onAudioFocusChangeListener); + //((Activity) getActivityContext()).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + releaseNetWorkState(); + + } + + + @Override + protected Context getActivityContext() { + return getContext(); + } + + @Override + protected void startDismissControlViewTimer() { + cancelDismissControlViewTimer(); + mDismissControlViewTimer = new Timer(); + mDismissControlViewTimerTask = new DismissControlViewTimerTask(); + mDismissControlViewTimer.schedule(mDismissControlViewTimerTask, mDismissControlTime); + } + + @Override + protected void cancelDismissControlViewTimer() { + if (mDismissControlViewTimer != null) { + mDismissControlViewTimer.cancel(); + mDismissControlViewTimer = null; + } + if (mDismissControlViewTimerTask != null) { + mDismissControlViewTimerTask.cancel(); + mDismissControlViewTimerTask = null; + } + + } + + private class DismissControlViewTimerTask extends TimerTask { + @Override + public void run() { + if (mCurrentState != CURRENT_STATE_NORMAL + && mCurrentState != CURRENT_STATE_ERROR + && mCurrentState != CURRENT_STATE_AUTO_COMPLETE) { + if (getActivityContext() != null) { + FloatingVideo.this.post(new Runnable() { + @Override + public void run() { + hideAllWidget(); + setViewShowState(mLockScreen, GONE); + if (mHideKey && mIfCurrentIsFullscreen && mShowVKey) { + hideNavKey(mContext); + } + } + }); + } + } + } + } +} diff --git a/app/src/main/java/com/example/gsyvideoplayer/view/FloatPlayerView.java b/app/src/main/java/com/example/gsyvideoplayer/view/FloatPlayerView.java new file mode 100644 index 0000000..f989c34 --- /dev/null +++ b/app/src/main/java/com/example/gsyvideoplayer/view/FloatPlayerView.java @@ -0,0 +1,74 @@ +package com.example.gsyvideoplayer.view; + +import android.content.Context; +import android.graphics.Color; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.example.gsyvideoplayer.video.FloatingVideo; +import com.shuyu.gsyvideoplayer.video.base.GSYVideoPlayer; + +/** + * Created by guoshuyu on 2017/12/25. + */ + +public class FloatPlayerView extends FrameLayout { + + FloatingVideo videoPlayer; + + public FloatPlayerView(Context context) { + super(context); + init(); + } + + public FloatPlayerView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public FloatPlayerView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + + videoPlayer = new FloatingVideo(getContext()); + + LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); + layoutParams.gravity = Gravity.CENTER; + + addView(videoPlayer, layoutParams); + + String source1 = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4"; + + videoPlayer.setUp(source1, true, "测试视频"); + + //增加封面 + /*ImageView imageView = new ImageView(getContext()); + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + imageView.setImageResource(R.mipmap.xxx1); + videoPlayer.setThumbImageView(imageView);*/ + + //是否可以滑动调整 + videoPlayer.setIsTouchWiget(false); + + } + + + public void onPause() { + videoPlayer.onVideoPause(); + } + + public void onResume() { + videoPlayer.onVideoResume(); + } + + public void onBackPressed() { + //释放所有 + videoPlayer.setStandardVideoAllCallBack(null); + GSYVideoPlayer.releaseAllVideos(); + } +} diff --git a/app/src/main/res/layout/activity_empty.xml b/app/src/main/res/layout/activity_empty.xml new file mode 100644 index 0000000..94ff8df --- /dev/null +++ b/app/src/main/res/layout/activity_empty.xml @@ -0,0 +1,12 @@ + + + +