├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── vcs.xml
├── inspectionProfiles
│ ├── profiles_settings.xml
│ └── Project_Default.xml
├── modules.xml
├── runConfigurations.xml
├── gradle.xml
├── compiler.xml
└── misc.xml
├── app
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ └── styles.xml
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── icon_suspend_hide_off.png
│ │ │ ├── icon_suspend_hide_on.png
│ │ │ ├── icon_suspend_menu_left.png
│ │ │ └── icon_suspend_menu_right.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ └── layout
│ │ │ ├── view_game_suspend_menu.xml
│ │ │ ├── view_game_suspend_hide.xml
│ │ │ ├── activity_main.xml
│ │ │ └── view_game_suspend_remind.xml
│ │ ├── java
│ │ └── com
│ │ │ └── toeii
│ │ │ └── mhrfloatwindow
│ │ │ ├── window
│ │ │ ├── SkipActivity.java
│ │ │ ├── Config.java
│ │ │ ├── view
│ │ │ │ ├── FloatWindowHideView.java
│ │ │ │ ├── FloatWindowRemindView.java
│ │ │ │ ├── FloatWindowMenuView.java
│ │ │ │ └── FloatWindowMainView.java
│ │ │ ├── SuspendMenuEntity.java
│ │ │ └── FloatWindowManager.java
│ │ │ ├── MainActivity.java
│ │ │ └── ScreenUtils.java
│ │ └── AndroidManifest.xml
├── build.gradle
├── proguard-rules.pro
└── app.iml
├── settings.gradle
├── images
├── float_window.gif
└── float_window_new.gif
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── README.md
├── gradle.properties
├── FloatWindow.iml
├── gradlew.bat
└── gradlew
/.idea/.name:
--------------------------------------------------------------------------------
1 | FloatWindow
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/images/float_window.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/images/float_window.gif
--------------------------------------------------------------------------------
/images/float_window_new.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/images/float_window_new.gif
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GameSDK FloatWindow
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_suspend_hide_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xhdpi/icon_suspend_hide_off.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_suspend_hide_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xhdpi/icon_suspend_hide_on.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_suspend_menu_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xhdpi/icon_suspend_menu_left.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_suspend_menu_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toeii/FloatWindow/HEAD/app/src/main/res/mipmap-xhdpi/icon_suspend_menu_right.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri May 22 15:24:54 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | db_files
2 | .DS_Store
3 | /gen/
4 | /bin/
5 | build.properties
6 | local.properties
7 | .settings/*
8 | *.iml
9 | *.orig
10 | .idea/*
11 | obj/*
12 | out/*
13 | build/*
14 | .gradle/*
15 | proguard/*
16 | libs/android-support-v4.jar.properties
17 | /project.properties
18 | /gradle/
19 | /gradlew
20 | /gradlew.bat
21 | /build/
22 | /captures/
23 | /bug/
24 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # introduce
2 | - A floating window menu
3 | - Function:
4 | the menu control,
5 | turn to hide,
6 | sliding handle,
7 | timing close to the edge,
8 | transparent processing...
9 | - Support minSdkVersion 9+
10 | - Out of the Service
11 |
12 | # 介绍
13 | - 该悬浮窗实现了久游悬浮窗的大部分效果。
14 | - 菜单检出、翻转显示隐藏、滑动处理、定时贴边以及透明化...
15 | - 最低兼容到2.3+
16 | - 脱离Service
17 |
18 | # Demo
19 | 
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_game_suspend_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 |
6 | defaultConfig {
7 | applicationId "com.toeii.mhrfloatwindow"
8 | minSdkVersion 9
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:23.1.0'
24 | }
25 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_game_suspend_hide.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/SkipActivity.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.widget.RelativeLayout;
7 |
8 | import com.toeii.mhrfloatwindow.R;
9 |
10 | public class SkipActivity extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_main);
16 | RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rl_layout);
17 | relativeLayout.setBackgroundColor(Color.BLUE);
18 | }
19 |
20 | @Override
21 | protected void onDestroy() {
22 | super.onDestroy();
23 | FloatWindowManager.getInstance(this).showFloatWindow(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/FloatWindow.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.view.Window;
6 | import android.view.WindowManager;
7 |
8 | import com.toeii.mhrfloatwindow.window.FloatWindowManager;
9 |
10 | public class MainActivity extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_main);
16 | FloatWindowManager.getInstance(this).showFloatWindow(this);
17 | }
18 |
19 | @Override
20 | protected void onPause() {
21 | super.onPause();
22 | // FloatWindowManager.getInstance(this).removeMainWindow();
23 | }
24 |
25 | @Override
26 | protected void onDestroy() {
27 | super.onDestroy();
28 | FloatWindowManager.getInstance(this).destroyFloatWindow();
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/Config.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window;
2 |
3 | /**
4 | *
5 | * @version 1.0.0.0
6 | * @author toeii
7 | * @date 2016/9/6
8 | * @path https://github.com/toeii/FloatWindow
9 | *
10 | */
11 | public class Config {
12 |
13 | //悬浮窗Key
14 | public static abstract class SuspendKey{
15 | public final static String WEB_PATH = "web_path";
16 | public final static String KEY_USER_ID= "key_user_id";
17 | public final static String KEY_SERVER_STATE="key_server_state";
18 | public final static String SP_CHOOSE = "choose";
19 | public final static String FLOAT_WINDOW = "float_window";
20 | }
21 |
22 | //悬浮窗服务状态
23 | public static abstract class SuspendServerState{
24 | public final static int DEFAULT = 0;
25 | public final static int SHOW = 1;
26 | public final static int HIDE = 2;
27 | public final static int DESTROY = 3;
28 | }
29 |
30 | //悬浮窗菜单点击隐藏状态
31 | public static abstract class SuspendMenuOnClikHideState{
32 | public final static int DEFAULT = 0;
33 | public final static int SHOW = 1;
34 | public final static int HIDE = 2;
35 | public final static int DESTROY = 3;
36 | }
37 |
38 | public static abstract class SuspendSkipType{
39 | public final static int ALL_SKIP = -1;
40 | public final static int DEFAULT_SKIP = 0;
41 | public final static int APP_SKIP = 2;
42 | public final static int WEB_SKIP = 1;
43 | public final static int ACCOUNT_SKIP = 3;
44 | public final static int GIFT_SKIP = 4;
45 | public final static int CIRCLE_SKIP = 5;
46 | public final static int MHR_CHAT_SKIP = 6;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/view/FloatWindowHideView.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.graphics.drawable.Drawable;
6 | import android.view.Gravity;
7 | import android.view.LayoutInflater;
8 | import android.widget.RelativeLayout;
9 | import android.widget.TextView;
10 |
11 | import com.toeii.mhrfloatwindow.R;
12 | import com.toeii.mhrfloatwindow.ScreenUtils;
13 |
14 | /**
15 | * 隐藏窗
16 | * @version 1.0.0.0
17 | * @author toeii
18 | * @date 2016/9/6
19 | * @path https://github.com/toeii/FloatWindow
20 | *
21 | */
22 | public class FloatWindowHideView extends RelativeLayout {
23 |
24 | private Context mContext;
25 |
26 | private TextView mHideSuspendTv;
27 | private RelativeLayout mHideSuspendRl;
28 |
29 | public FloatWindowHideView(Context context) {
30 | super(context);
31 | this.mContext = context;
32 | LayoutInflater.from(context).inflate(R.layout.view_game_suspend_hide, this);
33 | mHideSuspendRl = (RelativeLayout) findViewById(R.id.rl_suspend_hide);
34 | mHideSuspendTv = (TextView) findViewById(R.id.tv_suspend_hide);
35 |
36 | updateHideView(false);
37 | }
38 |
39 | public void updateHideView(boolean isCollsionWithRect){
40 | Drawable drawable = null;
41 | if(isCollsionWithRect){
42 | drawable = getResources().getDrawable(R.mipmap.icon_suspend_hide_on);
43 | mHideSuspendTv.setTextColor(Color.parseColor("#FFD800"));
44 | }else{
45 | drawable = getResources().getDrawable(R.mipmap.icon_suspend_hide_off);
46 | mHideSuspendTv.setTextColor(Color.WHITE);
47 | }
48 | if(null != drawable){
49 | drawable.setBounds(0, 0, ScreenUtils.dip2px(mContext, 30), ScreenUtils.dip2px(mContext, 30));
50 | }
51 | mHideSuspendTv.setCompoundDrawables(null, drawable, null, null);
52 | mHideSuspendTv.setCompoundDrawablePadding(ScreenUtils.dip2px(mContext, 8));
53 | mHideSuspendTv.setGravity(Gravity.CENTER);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/SuspendMenuEntity.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window;
2 |
3 | import android.graphics.drawable.Drawable;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | *
9 | * @version 1.0.0.0
10 | * @author toeii
11 | * @date 2016/9/6
12 | * @path https://github.com/toeii/FloatWindow
13 | *
14 | */
15 | public class SuspendMenuEntity implements Serializable {
16 |
17 | private static final long serialVersionUID = 87573344585549130L;
18 |
19 | private String menuItemName;
20 | private int menuItemType;
21 | private String menuItemIcon;
22 | private Drawable menuItemLocalIcon;
23 | private String menuItemPath;
24 | private String menuItemParams;
25 |
26 |
27 | public SuspendMenuEntity() {
28 |
29 | }
30 |
31 | public Drawable getMenuItemLocalIcon() {
32 | return menuItemLocalIcon;
33 | }
34 |
35 | public void setMenuItemLocalIcon(Drawable menuItemLocalIcon) {
36 | this.menuItemLocalIcon = menuItemLocalIcon;
37 | }
38 |
39 | public int getMenuItemType() {
40 | return menuItemType;
41 | }
42 |
43 | public void setMenuItemType(int menuItemType) {
44 | this.menuItemType = menuItemType;
45 | }
46 |
47 | public String getMenuItemParams() {
48 | return menuItemParams;
49 | }
50 |
51 | public void setMenuItemParams(String menuItemParams) {
52 | this.menuItemParams = menuItemParams;
53 | }
54 |
55 | public String getMenuItemName() {
56 | return menuItemName;
57 | }
58 |
59 | public void setMenuItemName(String menuItemName) {
60 | this.menuItemName = menuItemName;
61 | }
62 |
63 | public String getMenuItemIcon() {
64 | return menuItemIcon;
65 | }
66 |
67 | public void setMenuItemIcon(String menuItemIcon) {
68 | this.menuItemIcon = menuItemIcon;
69 | }
70 |
71 | public String getMenuItemPath() {
72 | return menuItemPath;
73 | }
74 |
75 | public void setMenuItemPath(String menuItemPath) {
76 | this.menuItemPath = menuItemPath;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/view/FloatWindowRemindView.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window.view;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.widget.Button;
8 | import android.widget.CheckBox;
9 | import android.widget.LinearLayout;
10 |
11 | import com.toeii.mhrfloatwindow.R;
12 | import com.toeii.mhrfloatwindow.window.Config;
13 | import com.toeii.mhrfloatwindow.window.FloatWindowManager;
14 |
15 | /**
16 | * 翻转提醒窗
17 | * @version 1.0.0.0
18 | * @author toeii
19 | * @date 2016/9/6
20 | * @path https://github.com/toeii/FloatWindow
21 | *
22 | */
23 | public class FloatWindowRemindView extends LinearLayout {
24 |
25 | private SharedPreferences preferences;
26 |
27 | private FloatWindowManager floatWindowManager;
28 |
29 | public FloatWindowRemindView(final Context context) {
30 | super(context);
31 | preferences = context.getSharedPreferences(Config.SuspendKey.FLOAT_WINDOW, Context.MODE_PRIVATE);
32 | LayoutInflater.from(context).inflate(R.layout.view_game_suspend_remind, this);
33 | floatWindowManager = FloatWindowManager.getInstance(context);
34 | final CheckBox suspendRemindCb = (CheckBox) findViewById(R.id.cb_suspend_remindwindow);
35 | Button suspendRemindCancel = (Button) findViewById(R.id.btn_suspend_remind_cancel);
36 | Button suspendRemindHide = (Button) findViewById(R.id.btn_suspend_remind_hide);
37 |
38 | suspendRemindCancel.setOnClickListener(new OnClickListener() {
39 |
40 | @Override
41 | public void onClick(View v) {
42 | floatWindowManager.removeRemindWindow();
43 | floatWindowManager.createMainWindow(context);
44 | if(null != floatWindowManager.getFloatWindowMainView()){
45 | floatWindowManager.getFloatWindowMainView().suspendMoveEnd();
46 | }
47 | }
48 | });
49 |
50 | suspendRemindHide.setOnClickListener(new OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | SharedPreferences.Editor editor = preferences.edit();
54 | if (suspendRemindCb.isChecked()) {
55 | editor.putBoolean(Config.SuspendKey.SP_CHOOSE, true);
56 | } else {
57 | editor.putBoolean(Config.SuspendKey.SP_CHOOSE, false);
58 | }
59 | editor.apply();
60 | floatWindowManager.removeRemindWindow();
61 | }
62 | });
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/ScreenUtils.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow;
2 |
3 | import android.content.Context;
4 | import android.content.res.Configuration;
5 | import android.view.WindowManager;
6 |
7 | /**
8 | *
9 | * @version 1.0.0.0
10 | * @author toeii
11 | * @date 2016/9/6
12 | * @path https://github.com/toeii/FloatWindow
13 | *
14 | */
15 | public class ScreenUtils {
16 |
17 | /**
18 | * 获取屏幕宽度
19 | *
20 | * @param context
21 | * @return
22 | */
23 | public static int getScreenWidth(Context context) {
24 | return ((WindowManager) context
25 | .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
26 | .getWidth();
27 | }
28 |
29 | /**
30 | * 获取屏幕宽度
31 | *
32 | * @param context
33 | * @return
34 | */
35 | public static int getScreenHeight(Context context) {
36 | return ((WindowManager) context
37 | .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
38 | .getHeight();
39 | }
40 |
41 | /**
42 | * 获得状态栏的高度
43 | *
44 | * @param context
45 | * @return
46 | */
47 | public static int getStatusHeight(Context context) {
48 |
49 | int statusHeight = -1;
50 | try {
51 | Class> clazz = Class.forName("com.android.internal.R$dimen");
52 | Object object = clazz.newInstance();
53 | int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
54 | statusHeight = context.getResources().getDimensionPixelSize(height);
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | return statusHeight;
59 | }
60 |
61 | public static int dip2px(Context context, float dpValue) {
62 | final float scale = context.getResources().getDisplayMetrics().density;
63 | return (int) (dpValue * scale + 0.5f);
64 | }
65 |
66 | public static int px2dip(Context context, float pxValue) {
67 | final float scale = context.getResources().getDisplayMetrics().density;
68 | return (int) (pxValue / scale + 0.5f);
69 | }
70 |
71 | public static boolean isScreenChange(Context context) {
72 | Configuration mConfiguration = context.getResources().getConfiguration();
73 | int ori = mConfiguration.orientation;
74 | if (ori == Configuration.ORIENTATION_LANDSCAPE) {
75 | // 横屏
76 | return true;
77 | } else if (ori == Configuration.ORIENTATION_PORTRAIT) {
78 | // 竖屏
79 | return false;
80 | }
81 | // return AppConfig.mhrOrientation == MHROrientation.LANDSCAPE;
82 | return false;
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_game_suspend_remind.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
29 |
30 |
36 |
37 |
45 |
46 |
55 |
56 |
57 |
64 |
65 |
77 |
78 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/view/FloatWindowMenuView.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window.view;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.graphics.Color;
6 | import android.net.Uri;
7 | import android.view.Gravity;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | import com.toeii.mhrfloatwindow.R;
17 | import com.toeii.mhrfloatwindow.ScreenUtils;
18 | import com.toeii.mhrfloatwindow.window.FloatWindowManager;
19 | import com.toeii.mhrfloatwindow.window.SkipActivity;
20 | import com.toeii.mhrfloatwindow.window.SuspendMenuEntity;
21 |
22 | import java.util.ArrayList;
23 |
24 | /**
25 | * 菜单窗
26 | *
27 | * @author toeii
28 | * @version 1.0.0.0
29 | * @date 2016/9/6
30 | * @path https://github.com/toeii/FloatWindow
31 | *
32 | */
33 | public class FloatWindowMenuView extends LinearLayout {
34 |
35 | private Context mContext;
36 |
37 | private LinearLayout mSuspendMenuLayout;
38 |
39 | private ArrayList mSuspendMenuBeans = new ArrayList<>();
40 |
41 | public LinearLayout getSuspendMenuLayout() {
42 | if (null == mSuspendMenuLayout) {
43 | mSuspendMenuLayout = (LinearLayout) findViewById(R.id.ll_suspend);
44 | }
45 | return mSuspendMenuLayout;
46 | }
47 |
48 | public FloatWindowMenuView(Context context) {
49 | super(context);
50 | this.mContext = context;
51 | LayoutInflater.from(context).inflate(R.layout.view_game_suspend_menu, this);
52 | mSuspendMenuLayout = (LinearLayout) findViewById(R.id.ll_suspend);
53 | }
54 |
55 | public void addMenuChild(ArrayList suspendMenuBeans) {
56 | int width = ScreenUtils.getScreenWidth(mContext);
57 | int height = ScreenUtils.getScreenHeight(mContext);
58 | int menuWidth = width>height?height:width - (FloatWindowManager.getInstance(mContext).getFloatWindowMainView().getWidth()*2);
59 | LinearLayout.LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
60 | lp.width = menuWidth;
61 | lp.gravity = Gravity.CENTER;
62 | getSuspendMenuLayout().setLayoutParams(lp);
63 |
64 | mSuspendMenuBeans.clear();
65 | mSuspendMenuBeans.addAll(suspendMenuBeans);
66 | if(null != suspendMenuBeans && suspendMenuBeans.size()>0){
67 | getSuspendMenuLayout().removeAllViews();
68 | for (int i = 0; i < suspendMenuBeans.size(); i++) {
69 | SuspendMenuEntity bean = suspendMenuBeans.get(i);
70 | if (null != bean) {
71 | LinearLayout menuLayout = new LinearLayout(mContext);
72 | initMenuView(menuLayout, i, bean);
73 | getSuspendMenuLayout().addView(menuLayout);
74 | }
75 | }
76 | }
77 | }
78 |
79 | private void initMenuView(LinearLayout menuLayout, final int index, SuspendMenuEntity bean) {
80 | if (null != bean) {
81 | menuLayout.setOrientation(LinearLayout.VERTICAL);
82 | LinearLayout.LayoutParams menuLayoutLp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1);
83 | menuLayoutLp.gravity = Gravity.TOP | Gravity.LEFT;
84 | if (index == 0) {
85 | menuLayoutLp.setMargins(ScreenUtils.px2dip(mContext, 16), ScreenUtils.px2dip(mContext, 4), 0, 0);
86 | } else {
87 | menuLayoutLp.setMargins(0, ScreenUtils.px2dip(mContext, 4), 0, 0);
88 | }
89 | menuLayout.setLayoutParams(menuLayoutLp);
90 |
91 | ImageView menuIv = new ImageView(mContext);
92 | LinearLayout.LayoutParams menuIvLp = new LinearLayout.LayoutParams(ScreenUtils.dip2px(mContext, 30), ScreenUtils.dip2px(mContext, 30));
93 | menuIvLp.gravity = Gravity.CENTER;
94 | menuIv.setLayoutParams(menuIvLp);
95 |
96 | TextView menuTv = new TextView(mContext);
97 | menuTv.setTextSize(10);
98 | menuTv.setTextColor(Color.WHITE);
99 | menuTv.setSingleLine(true);
100 | menuTv.setGravity(Gravity.CENTER);
101 |
102 | if (null == bean.getMenuItemIcon() || bean.getMenuItemIcon().equals("")) {
103 | // menuIv.setBackgroundDrawable(bean.getMenuItemLocalIcon());
104 | menuIv.setImageResource(R.mipmap.ic_launcher);
105 | } else {
106 | // Picasso.with(mContext).load(Uri.parse(bean.getMenuItemIcon())).into(menuIv);
107 | }
108 | menuTv.setText(bean.getMenuItemName());
109 |
110 | menuLayout.addView(menuIv);
111 | menuLayout.addView(menuTv);
112 | menuLayout.setOnClickListener(new OnClickListener() {
113 | @Override
114 | public void onClick(View v) {
115 | Toast.makeText(mContext,"skip app"+index,Toast.LENGTH_SHORT).show();
116 | FloatWindowManager.getInstance(mContext).destroyFloatWindow();
117 | mContext.startActivity(new Intent(mContext, SkipActivity.class));
118 | }
119 | });
120 |
121 | }
122 | }
123 |
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/FloatWindowManager.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window;
2 |
3 | import android.content.Context;
4 | import android.graphics.PixelFormat;
5 | import android.os.Build;
6 | import android.view.Gravity;
7 | import android.view.View;
8 | import android.view.WindowManager;
9 |
10 | import com.toeii.mhrfloatwindow.ScreenUtils;
11 | import com.toeii.mhrfloatwindow.window.view.FloatWindowHideView;
12 | import com.toeii.mhrfloatwindow.window.view.FloatWindowMainView;
13 | import com.toeii.mhrfloatwindow.window.view.FloatWindowMenuView;
14 | import com.toeii.mhrfloatwindow.window.view.FloatWindowRemindView;
15 |
16 | /**
17 | * 悬浮窗管理类
18 | * @version 1.0.0.0
19 | * @author toeii
20 | * @date 2016/9/6
21 | * @path https://github.com/toeii/FloatWindow
22 | *
23 | */
24 | public class FloatWindowManager {
25 |
26 | public final int VIEW_MAIN = 0;
27 | public final int VIEW_HIDE = 1;
28 | public final int VIEW_REMIND = 2;
29 | public final int VIEW_MENU = 3;
30 |
31 | private static FloatWindowManager floatWindowManager;
32 | private Context context;
33 | private WindowManager windowManager;
34 |
35 | private FloatWindowMainView floatWindowMainView;
36 | private FloatWindowMenuView floatWindowMenuView;
37 | private FloatWindowHideView floatWindowHideView;
38 | private FloatWindowRemindView floatWindowRemindView;
39 |
40 | private static WindowManager.LayoutParams mWindowParams;
41 |
42 | private boolean isFullHide = false;//是否完全隐藏
43 |
44 | private FloatWindowManager(Context context) {
45 | this.context = context;
46 | }
47 |
48 | public void setWindowParams(WindowManager.LayoutParams mWindowParams) {
49 | FloatWindowManager.mWindowParams = mWindowParams;
50 | }
51 |
52 | public static FloatWindowManager getInstance(Context context) {
53 | if(null == floatWindowManager){
54 | floatWindowManager = new FloatWindowManager(context);
55 | }
56 | return floatWindowManager;
57 | }
58 |
59 | //初始化窗口管理器
60 | public WindowManager getWindowManager() {
61 | if (windowManager == null) {
62 | windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
63 | }
64 | return windowManager;
65 | }
66 |
67 | //初始化悬浮窗参数
68 | public WindowManager.LayoutParams getLayoutParams(int type) {
69 | WindowManager.LayoutParams wmLayoutParams = new WindowManager.LayoutParams();
70 |
71 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
72 | wmLayoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
73 | } else {
74 | wmLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
75 | }
76 |
77 | wmLayoutParams.format = PixelFormat.RGBA_8888;
78 | wmLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
79 |
80 | wmLayoutParams.alpha = 1.0f;
81 |
82 | if (type == VIEW_MAIN || type == VIEW_MENU) {
83 | wmLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; // 调整悬浮窗口至左上角
84 | wmLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
85 | wmLayoutParams.height = ScreenUtils.dip2px(context, 48);
86 | } else if (type == VIEW_HIDE) {
87 | wmLayoutParams.gravity = Gravity.CENTER | Gravity.BOTTOM; // 调整悬浮窗口至下方
88 | wmLayoutParams.height = ScreenUtils.dip2px(context, 100);
89 | } else if (type == VIEW_REMIND) {
90 | wmLayoutParams.gravity = Gravity.CENTER; // 调整悬浮窗口至中间
91 | wmLayoutParams.width = ScreenUtils.dip2px(context, 300);
92 | wmLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
93 | }
94 | // 以屏幕左上角为原点,设置x、y初始值
95 | wmLayoutParams.x = 0;
96 | wmLayoutParams.y = 0;
97 | return wmLayoutParams;
98 | }
99 |
100 | public void setIsFullHide(boolean isFullHide) {
101 | this.isFullHide = isFullHide;
102 | }
103 |
104 | //判断悬浮窗是否存在
105 | public boolean isWindowShowing() {
106 | return floatWindowMainView != null || floatWindowMenuView != null || floatWindowHideView != null || floatWindowRemindView != null;
107 | }
108 |
109 | //显示悬浮窗
110 | public void showFloatWindow(Context context) {
111 | setIsFullHide(false);
112 | createMainWindow(context.getApplicationContext());
113 | registerSensorEventListener();
114 | }
115 |
116 | //销毁悬浮窗
117 | public void destroyFloatWindow() {
118 | setIsFullHide(true);
119 | removeMainWindow();
120 | unregisterSensorEventListener();
121 | }
122 |
123 | //创建主窗
124 | public void createMainWindow(Context context) {
125 | if(isFullHide){
126 | return;
127 | }
128 | WindowManager windowManager = getWindowManager();
129 | floatWindowMainView = new FloatWindowMainView(context.getApplicationContext());
130 | if(null == mWindowParams){
131 | mWindowParams = getLayoutParams(VIEW_MAIN);
132 | }
133 | floatWindowMainView.setWindowParams(mWindowParams);
134 | try {
135 | windowManager.addView(floatWindowMainView, mWindowParams);
136 | } catch (Exception e) { }
137 |
138 | //提前创建好隐藏窗
139 | if(null == floatWindowHideView){
140 | createHideWindow(context.getApplicationContext());
141 | }
142 | }
143 |
144 | //创建菜单窗
145 | public void createMenuWindow(Context context) {
146 | WindowManager windowManager = getWindowManager();
147 | if(null == floatWindowMenuView){
148 | floatWindowMenuView = new FloatWindowMenuView(context);
149 | }
150 | floatWindowMenuView.setVisibility(View.GONE);
151 | try {
152 | windowManager.addView(floatWindowMenuView,getLayoutParams(VIEW_MENU));
153 | } catch (Exception e) { }
154 |
155 | }
156 |
157 | //创建隐藏窗
158 | public void createHideWindow(Context context) {
159 | WindowManager windowManager = getWindowManager();
160 | if(null == floatWindowHideView){
161 | floatWindowHideView = new FloatWindowHideView(context);
162 | }
163 | floatWindowHideView.setVisibility(View.GONE);
164 | try {
165 | windowManager.addView(floatWindowHideView, getLayoutParams(VIEW_HIDE));
166 | } catch (Exception e) { }
167 |
168 | }
169 |
170 | //创建提醒窗
171 | public void createRemindWindow(Context context) {
172 | WindowManager windowManager = getWindowManager();
173 | if(null == floatWindowRemindView){
174 | floatWindowRemindView = new FloatWindowRemindView(context);
175 | }
176 | try {
177 | windowManager.addView(floatWindowRemindView,getLayoutParams(VIEW_REMIND));
178 | } catch (Exception e) { }
179 |
180 | }
181 |
182 | //移除主窗
183 | public void removeMainWindow() {
184 | if(null == floatWindowMainView){return;}
185 | WindowManager windowManager = getWindowManager();
186 | try {
187 | windowManager.removeView(floatWindowMainView);
188 | floatWindowMainView = null;
189 | //将其他悬浮窗也一并移除
190 | removeRemindWindow();
191 | removeMenuWindow();
192 | removeHideWindow();
193 | } catch (Exception e) {
194 | }
195 | }
196 |
197 | //移除菜单窗
198 | public void removeMenuWindow() {
199 | if(null == floatWindowMenuView){return;}
200 | WindowManager windowManager = getWindowManager();
201 | try {
202 | windowManager.removeView(floatWindowMenuView);
203 | floatWindowMenuView = null;
204 | } catch (Exception e) {
205 | }
206 | }
207 |
208 | //移除隐藏窗
209 | public void removeHideWindow() {
210 | if(null == floatWindowHideView){return;}
211 | WindowManager windowManager = getWindowManager();
212 | try {
213 | windowManager.removeView(floatWindowHideView);
214 | floatWindowHideView = null;
215 | } catch (Exception e) {
216 | }
217 | }
218 |
219 | //移除提醒窗
220 | public void removeRemindWindow() {
221 | if(null == floatWindowRemindView){return;}
222 | WindowManager windowManager = getWindowManager();
223 | try {
224 | windowManager.removeView(floatWindowRemindView);
225 | floatWindowRemindView = null;
226 | } catch (Exception e) {
227 | }
228 | }
229 |
230 | public FloatWindowMainView getFloatWindowMainView() {
231 | return floatWindowMainView;
232 | }
233 |
234 | public FloatWindowMenuView getFloatWindowMenuView() {
235 | if(null == floatWindowMenuView){
236 | createMenuWindow(context);
237 | }
238 | return floatWindowMenuView;
239 | }
240 |
241 | public FloatWindowHideView getFloatWindowHideView() {
242 | if (null == floatWindowHideView) {
243 | createHideWindow(context);
244 | }
245 | return floatWindowHideView;
246 | }
247 |
248 | public void registerSensorEventListener() {
249 | if (!isWindowShowing()) {return;}
250 | floatWindowMainView.registerSensorEventListener();
251 | }
252 |
253 | public void unregisterSensorEventListener() {
254 | if (!isWindowShowing()) {return;}
255 | floatWindowMainView.unregisterSensorEventListener();
256 | }
257 | }
258 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/toeii/mhrfloatwindow/window/view/FloatWindowMainView.java:
--------------------------------------------------------------------------------
1 | package com.toeii.mhrfloatwindow.window.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 | import android.hardware.Sensor;
7 | import android.hardware.SensorEvent;
8 | import android.hardware.SensorEventListener;
9 | import android.hardware.SensorManager;
10 | import android.os.Build;
11 | import android.os.Handler;
12 | import android.util.Log;
13 | import android.view.LayoutInflater;
14 | import android.view.MotionEvent;
15 | import android.view.View;
16 | import android.view.WindowManager;
17 | import android.widget.ImageView;
18 | import android.widget.LinearLayout;
19 |
20 | import com.toeii.mhrfloatwindow.R;
21 | import com.toeii.mhrfloatwindow.ScreenUtils;
22 | import com.toeii.mhrfloatwindow.window.Config;
23 | import com.toeii.mhrfloatwindow.window.FloatWindowManager;
24 | import com.toeii.mhrfloatwindow.window.SuspendMenuEntity;
25 |
26 | import java.util.ArrayList;
27 |
28 | /**
29 | * 主悬浮窗
30 | *
31 | * @version 1.0.0.0
32 | * @author toeii
33 | * @date 2016/9/6
34 | * @path https://github.com/toeii/FloatWindow
35 | *
36 | */
37 | public class FloatWindowMainView extends LinearLayout implements SensorEventListener {
38 |
39 | private int TIME = 5000;// 5秒后开始贴边
40 | private int LONG_TIME = 10000;// 10秒后开始贴边
41 | private final int MOVE_DISTANCE = 20;// 移动距离
42 |
43 | // 子窗口显示位置
44 | private int position = 2;
45 | private final int LEFT = 1;
46 | private final int RIGHT = 2;
47 |
48 | private Context mContext;
49 |
50 | // 翻转角度
51 | private final int FLIP_ANGLE_DOWN = -9;
52 | private final int FLIP_ANGLE_UP = 9;
53 | // 感应器管理器
54 | private SensorManager mSensorManager = null;
55 | private Sensor mAccelerometer = null;
56 | // 不再提醒
57 | private SharedPreferences mPreferences;
58 |
59 | private FloatWindowManager mFloatWindowManager;
60 | private WindowManager mWindowManager;
61 | private FloatWindowHideView mFloatWindowHideView;// 隐藏窗
62 | private FloatWindowMenuView mFloatWindowMenuView;// 菜单窗
63 | private WindowManager.LayoutParams mWindowParams;
64 | private WindowManager.LayoutParams mMenuViewWindowParams;
65 |
66 | private ImageView mSuspendIv;
67 | private static Handler handler = new Handler();// 透明化定时
68 | // private TranslateAnimation mClingAnimation;// 悬浮窗贴边动画
69 |
70 | // 屏幕宽高
71 | private int mScreenWidth;
72 | private int mScreenHeigh;
73 |
74 | // 窗体宽高
75 | public int mWindowWidth;
76 | public int mWindowHeight;
77 |
78 | // 当前移动X轴,Y轴
79 | private float mNowX;
80 | private float mNowY;
81 |
82 | // 之前位置X轴,Y轴
83 | private float mTouchStartX;
84 | private float mTouchStartY;
85 |
86 | // 隐藏窗X轴,Y轴
87 | private int mViewHideX;
88 | private int mViewHideY;
89 |
90 | private boolean isMove = false;//是否正在移动
91 | private boolean isCling = false;// 是否贴边
92 | private boolean isMoveComeHide = false;// 是否移动在隐藏窗口上
93 | private boolean isTurnOver = false;// 手机翻转是否停止
94 | private boolean isAddedMenu = false;// 是否有显示菜单栏窗口
95 |
96 | public void setWindowParams(WindowManager.LayoutParams mWindowParams) {
97 | this.mWindowParams = mWindowParams;
98 | }
99 |
100 | public FloatWindowMainView(Context context) {
101 | super(context);
102 | this.mContext = context;
103 | mSensorManager = (SensorManager) mContext.getSystemService(mContext.SENSOR_SERVICE);
104 | mPreferences = context.getSharedPreferences(Config.SuspendKey.FLOAT_WINDOW, Context.MODE_PRIVATE);
105 | mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
106 | mFloatWindowManager = FloatWindowManager.getInstance(mContext);
107 | mWindowManager = mFloatWindowManager.getWindowManager();
108 | mFloatWindowHideView = mFloatWindowManager.getFloatWindowHideView();
109 | mFloatWindowMenuView = mFloatWindowManager.getFloatWindowMenuView();
110 | mMenuViewWindowParams = mFloatWindowManager.getLayoutParams(mFloatWindowManager.VIEW_MENU);
111 | LayoutInflater.from(mContext).inflate(R.layout.view_game_suspend_menu, this);
112 | View view = findViewById(R.id.ll_suspend);
113 | mWindowWidth = view.getLayoutParams().width;
114 | mWindowHeight = view.getLayoutParams().height;
115 | mSuspendIv = (ImageView) findViewById(R.id.iv_suspend);
116 | mSuspendIv.setVisibility(View.VISIBLE);
117 |
118 | setAlpha();
119 |
120 | mScreenWidth = ScreenUtils.getScreenWidth(context);
121 | mScreenHeigh = ScreenUtils.getScreenHeight(context);
122 |
123 | mViewHideX = 0;
124 | mViewHideY = mScreenHeigh - ScreenUtils.getStatusHeight(context) - mFloatWindowHideView.getLayoutParams().height;
125 |
126 | handler.postDelayed(clingBoundaryRunnable, LONG_TIME);
127 |
128 | mFloatWindowMenuView.post(new Runnable() {
129 | @Override
130 | public void run() {
131 | initMenuData();
132 | }
133 | });
134 |
135 | }
136 |
137 | @Override
138 | public boolean onTouchEvent(MotionEvent event) {
139 | Log.d("toeii","onTouchEvent--------->"+event.getAction());
140 | mNowX = event.getRawX();
141 | mNowY = event.getRawY() - ScreenUtils.getStatusHeight(mContext);
142 | switch (event.getAction()) {
143 | case MotionEvent.ACTION_DOWN:
144 | handler.removeCallbacks(clingBoundaryRunnable);
145 | handler.removeCallbacks(transparentRunnable);
146 | isMove = false;
147 | mTouchStartX = event.getX();
148 | mTouchStartY = event.getY();
149 | setAlpha();
150 | break;
151 | case MotionEvent.ACTION_MOVE:
152 | if (mTouchStartY - event.getY() > MOVE_DISTANCE
153 | || mTouchStartY - event.getY() < -MOVE_DISTANCE
154 | || mTouchStartX - event.getX() > MOVE_DISTANCE
155 | || mTouchStartX - event.getX() < -MOVE_DISTANCE) {
156 | isMove = true;
157 | if (isAddedMenu) {
158 | isAddedMenu = false;
159 | // 隐藏菜单
160 | mFloatWindowMenuView.setVisibility(View.GONE);
161 | }
162 | updateViewPosition();
163 |
164 | if(mFloatWindowManager.getFloatWindowHideView().getVisibility() == View.GONE){
165 | mFloatWindowManager.getFloatWindowHideView().setVisibility(View.VISIBLE);
166 | }
167 |
168 | // 检测是否移动在隐藏窗口上
169 | if (isCollsionWithRect(mViewHideX, mViewHideY, ScreenUtils.getScreenWidth(mContext), mFloatWindowHideView.getHeight(), mWindowParams.x, mWindowParams.y, mWindowParams.width,
170 | mWindowParams.height)) {
171 | isMoveComeHide = true;
172 | mFloatWindowManager.getFloatWindowHideView().updateHideView(true);
173 | } else {
174 | isMoveComeHide = false;
175 | mFloatWindowManager.getFloatWindowHideView().updateHideView(false);
176 | }
177 |
178 | }
179 |
180 | break;
181 | case MotionEvent.ACTION_UP:
182 | mFloatWindowHideView.setVisibility(View.GONE);
183 | if(isMoveComeHide){
184 | mFloatWindowManager.removeMainWindow();
185 | if (!mPreferences.getBoolean(Config.SuspendKey.SP_CHOOSE, false)) {
186 | mFloatWindowManager.createRemindWindow(mContext);
187 | }
188 | }else{
189 | judgeScreenEdge();
190 | if (mTouchStartY - event.getY() > MOVE_DISTANCE
191 | || mTouchStartY - event.getY() < -MOVE_DISTANCE
192 | || mTouchStartX - event.getX() > MOVE_DISTANCE
193 | || mTouchStartX - event.getX() < -MOVE_DISTANCE) {
194 | mTouchStartX = mTouchStartY = 0;
195 | }else{
196 | if (isAddedMenu) {
197 | isAddedMenu = false;
198 | mFloatWindowMenuView.setVisibility(View.GONE);
199 | } else if(!isMove && !isCling){
200 | mMenuViewWindowParams.y = mWindowParams.y;
201 | if (position == LEFT) {
202 | mMenuViewWindowParams.x = mWindowParams.x + mSuspendIv.getWidth();
203 | mFloatWindowMenuView.setBackgroundResource(R.mipmap.icon_suspend_menu_right);
204 | } else {
205 | mMenuViewWindowParams.x = mWindowParams.x - mFloatWindowMenuView.getWidth() - ScreenUtils.px2dip(mContext, 12);
206 | mFloatWindowMenuView.setBackgroundResource(R.mipmap.icon_suspend_menu_left);
207 | }
208 | mFloatWindowMenuView.setVisibility(View.VISIBLE);
209 | updateViewLayout(mFloatWindowMenuView,mMenuViewWindowParams);
210 | isAddedMenu = true;
211 | }
212 | }
213 | suspendMoveEnd();
214 | }
215 | isCling = false;
216 | break;
217 | }
218 | return true;
219 | }
220 |
221 | // 更新浮动窗口位置参数
222 | private void updateViewPosition() {
223 | mWindowParams.x = (int) (mNowX - mTouchStartX);
224 | mWindowParams.y = (int) (mNowY - mTouchStartY);
225 | // 限制悬浮滑动范围
226 | viewMoveRestrict();
227 | updateViewLayout(mFloatWindowManager.getFloatWindowMainView(),mWindowParams);
228 | }
229 |
230 | private void updateViewLayout(View view,WindowManager.LayoutParams mWindowParams) {
231 | if(null == view || null == mWindowParams){return;}
232 | mFloatWindowManager.setWindowParams(mWindowParams);
233 | try {
234 | mWindowManager.updateViewLayout(view, mWindowParams);
235 | }catch (Exception e){
236 | mWindowManager.addView(view, mWindowParams);
237 | mWindowManager.updateViewLayout(view, mWindowParams);
238 | }
239 | }
240 |
241 | private void viewMoveRestrict() {
242 | if (mWindowParams.x > mScreenWidth - ScreenUtils.dip2px(mContext, 48)) {
243 | mWindowParams.x = mScreenWidth - ScreenUtils.dip2px(mContext, 48);
244 | } else if (mWindowParams.x <= 0) {
245 | mWindowParams.x = 0;
246 | }
247 | if (mWindowParams.y > mScreenHeigh - ScreenUtils.dip2px(mContext, 48)) {
248 | mWindowParams.y = mScreenHeigh - (ScreenUtils.dip2px(mContext, 48));//这里没有减状态栏高度。某些应用接入时是隐藏状态栏的,感觉所需要的情况去修改吧
249 | } else if (mWindowParams.y <= 0) {
250 | mWindowParams.y = 0;
251 | }
252 | }
253 |
254 | // 移动结束后的定位
255 | public void suspendMoveEnd() {
256 | if(null == mFloatWindowManager.getFloatWindowMainView()){return;}
257 | // if (AppUtil.isScreenChange(mContext)) {
258 | // if (mScreenHeigh / 2 > mWindowParams.x) {
259 | // mWindowParams.x = 0;
260 | // } else {
261 | // mWindowParams.x = mScreenHeigh - mSuspendIv.getWidth();
262 | // }
263 | // } else {
264 | if (mScreenWidth / 2 > mWindowParams.x) {
265 | mWindowParams.x = 0;
266 | } else {
267 | mWindowParams.x = mScreenWidth - ScreenUtils.dip2px(mContext,48);
268 | }
269 | // }
270 |
271 | updateViewLayout(mFloatWindowManager.getFloatWindowMainView(),mWindowParams);
272 | timerAgain();
273 | }
274 |
275 | // 透明化定时
276 | private void timerAgain() {
277 | if(null == mFloatWindowManager.getFloatWindowMainView()){return;}
278 | if (null != handler) {
279 | handler.removeCallbacks(clingBoundaryRunnable);
280 | if (isAddedMenu) {
281 | handler.postDelayed(clingBoundaryRunnable, LONG_TIME);
282 | } else {
283 | handler.postDelayed(clingBoundaryRunnable, TIME);
284 | }
285 | }
286 | }
287 |
288 | /**
289 | * 矩形碰撞的函数
290 | *
291 | * @param x1
292 | * 第一个矩形的X坐标
293 | * @param y1
294 | * 第一个矩形的Y坐标
295 | * @param w1
296 | * 第一个矩形的宽
297 | * @param h1
298 | * 第一个矩形的高
299 | * @param x2
300 | * 第二个矩形的X坐标
301 | * @param y2
302 | * 第二个矩形的Y坐标
303 | * @param w2
304 | * 第二个矩形的宽
305 | * @param h2
306 | * 第二个矩形的高
307 | */
308 | public boolean isCollsionWithRect(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
309 | // 当矩形1位于矩形2的左侧
310 | if (x1 >= x2 && x1 >= x2 + w2) {
311 | return false;
312 | // 当矩形1位于矩形2的右侧
313 | } else if (x1 <= x2 && x1 + w1 <= x2) {
314 | return false;
315 | // 当矩形1位于矩形2的上方
316 | } else if (y1 >= y2 && y1 >= y2 + h2) {
317 | return false;
318 | } else if (y1 <= y2 && y1 + h1 <= y2) {
319 | return false;
320 | }
321 | // 所有不会发生碰撞都不满足时,肯定就是碰撞了
322 | return true;
323 | }
324 |
325 | // 还原透明度
326 | private void setAlpha() {
327 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
328 | mSuspendIv.setImageAlpha(204);
329 | } else {
330 | mSuspendIv.setAlpha(204);
331 | }
332 | }
333 |
334 | // 悬浮窗贴边线程
335 | protected Runnable clingBoundaryRunnable = new Runnable() {
336 | @Override
337 | public void run() {
338 | suspendClingBoundary();
339 |
340 | // 两秒后透明
341 | handler.postDelayed(transparentRunnable, 2000);
342 |
343 | // 菜单栏
344 | if (isAddedMenu) {
345 | isAddedMenu = false;
346 | mFloatWindowMenuView.setVisibility(View.GONE);
347 | }
348 | }
349 | };
350 |
351 | // 贴边后的半透明处理
352 | protected Runnable transparentRunnable = new Runnable() {
353 | @Override
354 | public void run() {
355 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
356 | mSuspendIv.setImageAlpha(128);
357 | } else {
358 | mSuspendIv.setAlpha(128);
359 | }
360 | }
361 | };
362 |
363 | // 判断屏幕两边
364 | private void judgeScreenEdge () {
365 | if (mScreenWidth / 2 > mWindowParams.x) {
366 | position = LEFT;
367 | } else {
368 | position = RIGHT;
369 | }
370 | }
371 |
372 | // 贴边
373 | private void suspendClingBoundary() {
374 | if (mWindowParams.x == 0) {
375 | mWindowParams.x = ScreenUtils.dip2px(mContext, -24);
376 | } else {
377 | // if (AppUtil.isScreenChange(mContext)) {
378 | // mWindowParams.x = mScreenHeigh - AppUtil.dip2px(mContext, 24);
379 | // } else {
380 | mWindowParams.x = mScreenWidth - ScreenUtils.dip2px(mContext, 24);
381 | // }
382 | }
383 | updateViewLayout(mFloatWindowManager.getFloatWindowMainView(),mWindowParams);
384 | isCling = true;
385 | }
386 |
387 |
388 | @Override
389 | public void onSensorChanged(SensorEvent event) {
390 | float value = event.values[2];
391 | // -10 ~ 10 水平翻转值
392 | if (value < FLIP_ANGLE_DOWN) {
393 | isTurnOver = true;
394 | }
395 |
396 | if (isTurnOver && value > FLIP_ANGLE_UP) {
397 | if (!mFloatWindowManager.isWindowShowing()) {
398 | mFloatWindowManager.createMainWindow(mContext);
399 | // 恢复默认坐标
400 | // updateViewLayout(mFloatWindowManager.getFloatWindowMainView(),mWindowParams);
401 | isTurnOver = false;
402 | suspendMoveEnd();
403 | } else {
404 | mFloatWindowManager.removeMainWindow();
405 | isTurnOver = false;
406 | }
407 | }
408 | }
409 |
410 | @Override
411 | public void onAccuracyChanged(Sensor sensor, int accuracy) {
412 |
413 | }
414 |
415 | public void registerSensorEventListener() {
416 | if (null != mSensorManager) {
417 | mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
418 | }
419 | }
420 |
421 | public void unregisterSensorEventListener() {
422 | if (null != mSensorManager) {
423 | mSensorManager.unregisterListener(this);
424 | }
425 | }
426 |
427 | private void initMenuData() {
428 | if(mFloatWindowMenuView.getSuspendMenuLayout().getChildCount() <= 1){
429 | initMenuDefaultData();
430 | mFloatWindowMenuView.invalidate();
431 | }
432 | updateViewLayout(mFloatWindowMenuView,mMenuViewWindowParams);
433 | }
434 |
435 | private void initMenuDefaultData() {
436 | ArrayList suspendMenuBeans = new ArrayList<>();
437 | SuspendMenuEntity suspendMenuEntity1 = new SuspendMenuEntity();
438 | suspendMenuEntity1.setMenuItemName("菜单1");
439 |
440 | SuspendMenuEntity suspendMenuEntity2 = new SuspendMenuEntity();
441 | suspendMenuEntity2.setMenuItemName("菜单2");
442 |
443 | SuspendMenuEntity suspendMenuEntity3 = new SuspendMenuEntity();
444 | suspendMenuEntity3.setMenuItemName("菜单3");
445 |
446 | SuspendMenuEntity suspendMenuEntity4 = new SuspendMenuEntity();
447 | suspendMenuEntity4.setMenuItemName("菜单4");
448 |
449 | suspendMenuBeans.add(suspendMenuEntity1);
450 | suspendMenuBeans.add(suspendMenuEntity2);
451 | suspendMenuBeans.add(suspendMenuEntity3);
452 | suspendMenuBeans.add(suspendMenuEntity4);
453 | mFloatWindowMenuView.addMenuChild(suspendMenuBeans);
454 | }
455 |
456 | }
457 |
--------------------------------------------------------------------------------