├── .gitignore ├── Android.mk ├── AndroidManifest.xml ├── README.md ├── proguard-project.txt ├── project.properties ├── res ├── drawable-hdpi │ ├── back.png │ ├── back_pressed.png │ ├── home.png │ ├── home_pressed.png │ ├── ic.png │ ├── ic_launcher.png │ ├── menu.png │ ├── menu_pressed.png │ ├── recent.png │ └── recent_pressed.png ├── drawable-xhdpi │ ├── back.png │ ├── back_pressed.png │ ├── home.png │ ├── home_pressed.png │ ├── menu.png │ ├── menu_pressed.png │ ├── recent.png │ └── recent_pressed.png ├── drawable │ ├── back_selector.xml │ ├── home_selector.xml │ ├── menu_selector.xml │ └── recent_selector.xml ├── layout │ └── image_preference_layout.xml ├── values-zh-rCN │ └── strings.xml ├── values │ ├── dimens.xml │ └── strings.xml └── xml │ └── mipop_settings.xml ├── screenshot └── 1.gif └── src └── com └── way └── mipop ├── AppLog.java ├── MainActivity.java ├── animation ├── AnimationParking.java └── AnimationTransparent.java ├── api └── App.java └── widget ├── MeterBack.java ├── MeterBase.java ├── MeterHome.java ├── MeterMenu.java ├── MeterRecent.java └── Until.java /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Intellij project files 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | .metadata 32 | .settings/ 33 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008 The Android Open Source Project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | LOCAL_PATH := $(call my-dir) 18 | include $(CLEAR_VARS) 19 | 20 | LOCAL_MODULE_TAGS := optional 21 | 22 | LOCAL_SRC_FILES := $(call all-java-files-under, src) 23 | 24 | 25 | LOCAL_PACKAGE_NAME := MiPop 26 | LOCAL_CERTIFICATE := platform 27 | LOCAL_PRIVILEGED_MODULE := true 28 | 29 | LOCAL_PROGUARD_FLAG_FILES := proguard.flags 30 | 31 | include $(BUILD_PACKAGE) 32 | 33 | # Use the following include to make our test apk. 34 | #include $(call all-makefiles-under,$(LOCAL_PATH)) 35 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 13 | 14 | 17 | 18 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MiPop 2 | Android屏幕助手,可以代替Android原生的NavigationBar,释放更多的屏幕空间。由于需要替换系统按键消息,因此需要`平台签名`,具体可以参看`Android.mk`文件。 3 | 4 | ## 代码结构 5 | 本项目基于`Android源码环境`开发,需要在Android源码环境下编译,由于本人不会`PhotoShop`,所以测试截图中有一个`menu`按键图标与其他图标风格不符,请谅解。 6 | 7 | ## 联系我 8 | 9 | way: 10 | * [邮箱](mailto:way.ping.li@gmail.com "给我发邮件") 11 | * [博客](http://blog.csdn.net/way_ping_li "CSDN博客") 12 | 13 | 14 | ## 测试截图 15 | 16 | ![Screenshot 1](https://raw.githubusercontent.com/way1989/Mipop/master/screenshot/1.gif "Screenshot 1") 17 | 18 | 19 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-22 15 | -------------------------------------------------------------------------------- /res/drawable-hdpi/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/back.png -------------------------------------------------------------------------------- /res/drawable-hdpi/back_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/back_pressed.png -------------------------------------------------------------------------------- /res/drawable-hdpi/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/home.png -------------------------------------------------------------------------------- /res/drawable-hdpi/home_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/home_pressed.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/ic.png -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-hdpi/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/menu.png -------------------------------------------------------------------------------- /res/drawable-hdpi/menu_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/menu_pressed.png -------------------------------------------------------------------------------- /res/drawable-hdpi/recent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/recent.png -------------------------------------------------------------------------------- /res/drawable-hdpi/recent_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-hdpi/recent_pressed.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/back.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/back_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/back_pressed.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/home.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/home_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/home_pressed.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/menu.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/menu_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/menu_pressed.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/recent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/recent.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/recent_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/res/drawable-xhdpi/recent_pressed.png -------------------------------------------------------------------------------- /res/drawable/back_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/drawable/home_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/drawable/menu_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/drawable/recent_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /res/layout/image_preference_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | -------------------------------------------------------------------------------- /res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 屏幕助手 5 | 屏幕助手 6 | 屏幕助手 7 | 启动后取代屏幕底部的返回、Home、最近任务、菜单键 8 | 隐藏底部导航条 9 | 隐藏底部导航条,扩大屏幕使用范围 10 | 11 | -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25dip 6 | 7 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Mi-POP 5 | Mi-POP 6 | Mi-POP enabled,the navigation bar could be replaced 7 | Hide the navigation bar 8 | Larger screen area available 9 | 10 | -------------------------------------------------------------------------------- /res/xml/mipop_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 16 | 17 | 21 | 22 | -------------------------------------------------------------------------------- /screenshot/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/way1989/Mipop/c4ff7fe0bea4689991654edf6927a9733e6cee05/screenshot/1.gif -------------------------------------------------------------------------------- /src/com/way/mipop/AppLog.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop; 2 | 3 | import android.content.Context; 4 | import android.os.Debug; 5 | import android.util.Log; 6 | import android.widget.Toast; 7 | 8 | public class AppLog { 9 | static final boolean DEBUG = 10 | //BuildConfig.DEBUG; 11 | Debug.isDebuggerConnected(); 12 | static final String TAG = "MiPop"; 13 | 14 | public static void DisplayToast(Context context, String message) { 15 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); 16 | } 17 | 18 | public static void i(Object object, String log) { 19 | if (!DEBUG) 20 | return; 21 | String className = object.getClass().getName(); 22 | Log.d(className.substring(1 + className.lastIndexOf('.')), 23 | className.substring(1 + className.lastIndexOf('.')) + ": " 24 | + log); 25 | } 26 | 27 | public static void i(String log) { 28 | if (!DEBUG) 29 | return; 30 | Log.d(TAG, log); 31 | } 32 | 33 | public static void i(String tag, String log) { 34 | if (!DEBUG) 35 | return; 36 | Log.d(tag, tag + ": " + log); 37 | } 38 | 39 | public static void d(Object object, String log) { 40 | if (!DEBUG) 41 | return; 42 | String className = object.getClass().getName(); 43 | Log.d(className.substring(1 + className.lastIndexOf('.')), 44 | className.substring(1 + className.lastIndexOf('.')) + ": " 45 | + log); 46 | } 47 | 48 | public static void d(String log) { 49 | if (!DEBUG) 50 | return; 51 | Log.d(TAG, log); 52 | } 53 | 54 | public static void d(String tag, String log) { 55 | if (!DEBUG) 56 | return; 57 | Log.d(tag, tag + ": " + log); 58 | } 59 | 60 | public static void e(Object object, String log) { 61 | if (!DEBUG) 62 | return; 63 | String className = object.getClass().getName(); 64 | Log.e(className.substring(1 + className.lastIndexOf('.')), 65 | className.substring(1 + className.lastIndexOf('.')) + ": " 66 | + log); 67 | } 68 | 69 | public static void e(String log) { 70 | if (!DEBUG) 71 | return; 72 | Log.e(TAG, log); 73 | } 74 | 75 | public static void e(String tag, String log) { 76 | if (!DEBUG) 77 | return; 78 | Log.e(tag, tag + ": " + log); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/com/way/mipop/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop; 2 | 3 | import android.os.Bundle; 4 | import android.preference.CheckBoxPreference; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceActivity; 7 | import android.preference.PreferenceScreen; 8 | import android.provider.Settings; 9 | 10 | import com.way.mipop.api.App; 11 | 12 | @SuppressWarnings("deprecation") 13 | public class MainActivity extends PreferenceActivity { 14 | private String TAG = "MainActivity"; 15 | CheckBoxPreference mFullScreen; 16 | CheckBoxPreference mMiPop; 17 | 18 | private void setupFloatIcon() { 19 | boolean isMipopShow = getSharedPreferences( 20 | "com.way.mipop_preferences", MODE_PRIVATE).getBoolean( 21 | "mipop_switch", true); 22 | mMiPop.setChecked(isMipopShow); 23 | if (mFullScreen.isChecked()) 24 | mMiPop.setEnabled(false); 25 | } 26 | 27 | private void setupFullScreen() { 28 | boolean isEnable = getSharedPreferences( 29 | "com.way.mipop_preferences", MODE_PRIVATE).getBoolean( 30 | "mipop_fullscreen", false); 31 | mFullScreen.setEnabled(isEnable); 32 | String str = Settings.System.getString(getContentResolver(), 33 | "showNavigationBar"); 34 | if ("show".equals(str)) { 35 | mFullScreen.setChecked(false); 36 | } else if ("hide".equals(str)) { 37 | mFullScreen.setChecked(true); 38 | } 39 | } 40 | 41 | public void onCreate(Bundle bundle) { 42 | AppLog.i(TAG, "onCreate()..."); 43 | super.onCreate(bundle); 44 | addPreferencesFromResource(R.xml.mipop_settings); 45 | mMiPop = ((CheckBoxPreference) findPreference("mipop_switch")); 46 | mFullScreen = ((CheckBoxPreference) findPreference("mipop_fullscreen")); 47 | } 48 | 49 | public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 50 | Preference preference) { 51 | AppLog.i(TAG, "onPreferenceTreeClick"); 52 | if (preference == mMiPop) { 53 | AppLog.i(TAG, "onPreferenceTreeClick preference == mMiPop"); 54 | if (mMiPop.isChecked()) { 55 | App.showMipop(); 56 | } else { 57 | App.hideMipop(); 58 | } 59 | } else if (preference == mFullScreen) { 60 | AppLog.i(TAG, "onPreferenceTreeClick preference == mFullScreen"); 61 | if (mFullScreen.isChecked()) { 62 | AppLog.i(TAG, "mFullScreen checked mipop = true"); 63 | mMiPop.setChecked(true); 64 | mMiPop.setEnabled(false); 65 | App.showMipop(); 66 | } else { 67 | mMiPop.setEnabled(true); 68 | } 69 | } 70 | return super.onPreferenceTreeClick(preferenceScreen, preference); 71 | 72 | } 73 | 74 | protected void onResume() { 75 | super.onResume(); 76 | AppLog.i(TAG, "onResume()..."); 77 | setupFloatIcon(); 78 | setupFullScreen(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/way/mipop/animation/AnimationParking.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.animation; 2 | 3 | import android.os.Handler; 4 | import android.view.View; 5 | 6 | import com.way.mipop.AppLog; 7 | import com.way.mipop.widget.MeterBack; 8 | import com.way.mipop.widget.MeterBase; 9 | import com.way.mipop.widget.MeterHome; 10 | import com.way.mipop.widget.MeterMenu; 11 | import com.way.mipop.widget.MeterRecent; 12 | import com.way.mipop.widget.Until; 13 | 14 | public class AnimationParking { 15 | public static final boolean LEFT = true; 16 | public static final boolean RIGHT = false; 17 | private static String TAG = "AnimationParking"; 18 | public static int baseX = MeterBase.baseX; 19 | public static int baseY = MeterBase.baseY; 20 | private static Handler handler4Parking = new Handler(); 21 | private static Handler handler4PosCheck = new Handler(); 22 | private static Handler handler4Shrink = new Handler(); 23 | private static Handler handler4Turning = new Handler(); 24 | private static int homeX; 25 | private static int homeY; 26 | public static boolean mAreaChanged = false; 27 | private static long mAutoUpdatePeriod = 10L; 28 | public static boolean mOriginSide = LEFT; 29 | private static long mParking2Shrink = 2000L; 30 | private static int mStep = 15; 31 | private static boolean mTimeOut; 32 | private static long mVelocityTime = 300L; 33 | private static int menuX; 34 | private static int menuY; 35 | private static int recentX; 36 | private static int recentY; 37 | private static Runnable runnable4Parking = new Runnable() { 38 | 39 | @Override 40 | public void run() { 41 | parking(); 42 | } 43 | }; 44 | private static Runnable runnable4PosCheck = new Runnable() { 45 | 46 | @Override 47 | public void run() { 48 | mTimeOut = true; 49 | velocityCheck = true; 50 | if (mAreaChanged) { 51 | mAreaChanged = false; 52 | } 53 | } 54 | }; 55 | private static Runnable runnable4Shrink = new Runnable() { 56 | @Override 57 | public void run() { 58 | shrinking(); 59 | } 60 | }; 61 | private static Runnable runnable4Turning = new Runnable() { 62 | 63 | @Override 64 | public void run() { 65 | turning(); 66 | } 67 | }; 68 | private static boolean velocityCheck; 69 | 70 | private static void hideSub() { 71 | MeterBase.MeterMap.get(MeterRecent.NAME).setVisibility(View.INVISIBLE); 72 | MeterBase.MeterMap.get(MeterHome.NAME).setVisibility(View.INVISIBLE); 73 | MeterBase.MeterMap.get(MeterMenu.NAME).setVisibility(View.INVISIBLE); 74 | } 75 | 76 | private static void initial() { 77 | baseX = MeterBase.baseX; 78 | baseY = MeterBase.baseY; 79 | } 80 | 81 | public static void land() { 82 | if (!mOriginSide) { 83 | stop(); 84 | baseX = Until.SCREEM_WIDTH - Until.IMAGE_WIDTH; 85 | updateAll(baseX, baseY); 86 | } 87 | if (MeterBase.baseY > Until.SCREEM_HEIGHT) { 88 | updateBottom(baseX, baseY); 89 | } 90 | shrinkStart(); 91 | } 92 | 93 | private static void parking() { 94 | if (baseX < Until.MID_LINE) { 95 | parking2Margin(true); 96 | } else { 97 | AppLog.d("MBack", "baseX = " + baseX); 98 | parking2Margin(false); 99 | } 100 | } 101 | 102 | private static void parking2Margin(boolean isLeft) { 103 | int expendLine = Until.EXPEND_LINE; 104 | if (!isLeft) { 105 | expendLine = Until.SCREEM_WIDTH - Until.IMAGE_WIDTH 106 | - Until.EXPEND_LINE; 107 | } 108 | int speed = mStep; 109 | if (baseX > expendLine) { 110 | speed = -mStep; 111 | } 112 | baseX = speed + baseX; 113 | updateAll(baseX, baseY); 114 | if (Math.abs(baseX - expendLine) <= mStep) { 115 | baseX = expendLine; 116 | updateAll(baseX, baseY); 117 | handler4Parking.removeCallbacks(runnable4Parking); 118 | handler4Turning.postDelayed(runnable4Turning, mParking2Shrink); 119 | return; 120 | } 121 | handler4Shrink.removeCallbacks(runnable4Shrink); 122 | handler4Parking.postDelayed(runnable4Parking, mAutoUpdatePeriod); 123 | } 124 | 125 | private static void posCalculateLeftX(int x, int y) { 126 | if (x <= Until.EXPEND_LINE) { 127 | recentX = x - Until.EXPEND_LINE; 128 | recentY = y; 129 | homeX = x / 2; 130 | homeY = y - x / 2; 131 | menuX = x / 2; 132 | menuY = y + x / 2; 133 | return; 134 | } 135 | if (mOriginSide) { 136 | if (x < Until.MID_LINE) { 137 | recentX = x - Until.EXPEND_LINE; 138 | recentY = y; 139 | homeX = x - Until.EXPEND_LINE / 2; 140 | homeY = y - Until.EXPEND_LINE / 2; 141 | menuX = x - Until.EXPEND_LINE / 2; 142 | menuY = y + Until.EXPEND_LINE / 2; 143 | return; 144 | } 145 | if (x < Until.MID_LINE + Until.SHRINK_LINE) { 146 | AppLog.i("Park", "Left shrink x=" + x); 147 | recentX = x - Until.EXPEND_LINE + Until.EXPEND_LINE 148 | / Until.SHRINK_LINE * (x - Until.MID_LINE); 149 | recentY = y; 150 | homeX = x - Until.EXPEND_LINE / 2 + Until.EXPEND_LINE 151 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 152 | homeY = y - Until.EXPEND_LINE / 2 + Until.EXPEND_LINE 153 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 154 | menuX = x - Until.EXPEND_LINE / 2 + Until.EXPEND_LINE 155 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 156 | menuY = y + Until.EXPEND_LINE / 2 - Until.EXPEND_LINE 157 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 158 | return; 159 | } 160 | } 161 | mAreaChanged = true; 162 | recentX = x; 163 | recentY = y; 164 | homeX = x; 165 | homeY = y; 166 | menuX = x; 167 | menuY = y; 168 | hideSub(); 169 | 170 | } 171 | 172 | private static void quickSlide() { 173 | handler4PosCheck.removeCallbacks(runnable4PosCheck); 174 | if (!mTimeOut) { 175 | velocityCheck = true; 176 | } 177 | if (mAreaChanged) { 178 | velocityCheck = false; 179 | } 180 | } 181 | 182 | private static void showOrHide(int x) { 183 | if (!velocityCheck) { 184 | hideSub(); 185 | } else { 186 | if (mAreaChanged) { 187 | hideSub(); 188 | return; 189 | } 190 | if ((x > Until.SCREEM_WIDTH - Until.IMAGE_WIDTH) || (x < 0)) { 191 | hideSub(); 192 | return; 193 | } 194 | 195 | showSub(); 196 | } 197 | } 198 | 199 | private static void showSub() { 200 | MeterBase.MeterMap.get(MeterRecent.NAME).setVisibility(View.VISIBLE); 201 | MeterBase.MeterMap.get(MeterHome.NAME).setVisibility(View.VISIBLE); 202 | MeterBase.MeterMap.get(MeterMenu.NAME).setVisibility(View.VISIBLE); 203 | } 204 | 205 | public static void shrinkStart() { 206 | handler4Parking.removeCallbacks(runnable4Parking); 207 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 208 | } 209 | 210 | private static void shrinking() { 211 | int speed = mStep; 212 | if (baseX < Until.MID_LINE) { 213 | speed = -speed; 214 | } 215 | baseX = speed + baseX; 216 | AppLog.i("Suhao", "shrinking x= " + baseX); 217 | updateAll(baseX, baseY); 218 | if (baseX >= Until.SCREEM_WIDTH - Until.IMAGE_WIDTH) { 219 | baseX = Until.SCREEM_WIDTH - Until.IMAGE_WIDTH; 220 | updateAll(baseX, baseY); 221 | velocityCheck = false; 222 | mOriginSide = RIGHT; 223 | mAreaChanged = false; 224 | handler4Shrink.removeCallbacks(runnable4Shrink); 225 | AppLog.i("Suhao.TransParent", 226 | "AnimationParking.shrinking(), baseX>SCREEN_WIDTH-IMAGE_WIDTH"); 227 | AnimationTransparent.start(); 228 | return; 229 | } 230 | if (baseX <= 1) { 231 | baseX = 0; 232 | updateAll(baseX, baseY); 233 | velocityCheck = false; 234 | mOriginSide = LEFT; 235 | mAreaChanged = false; 236 | handler4Shrink.removeCallbacks(runnable4Shrink); 237 | AppLog.i("Suhao.TransParent", 238 | "AnimationParking.shrinking(), baseX<1"); 239 | AnimationTransparent.start(); 240 | return; 241 | } 242 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 243 | } 244 | 245 | public static void start() { 246 | AppLog.i("Suhao", "AnimationParking start()"); 247 | quickSlide(); 248 | initial(); 249 | if (baseX <= 0) { 250 | AppLog.i("Suhao.TransParent", "AnimationParking.start(), baseX<0"); 251 | mOriginSide = LEFT; 252 | mAreaChanged = false; 253 | velocityCheck = false; 254 | baseX = 0; 255 | AnimationTransparent.start(); 256 | return; 257 | } 258 | if (baseX >= Until.SCREEM_WIDTH - Until.IMAGE_WIDTH) { 259 | AppLog.i("Suhao.TransParent", 260 | "AnimationParking.start(), baseX>SCREEN_WIDTH-IMAGE_WIDTH"); 261 | mOriginSide = RIGHT; 262 | mAreaChanged = false; 263 | velocityCheck = false; 264 | baseX = Until.SCREEM_WIDTH - Until.IMAGE_WIDTH; 265 | AnimationTransparent.start(); 266 | return; 267 | } 268 | updateTop(baseX, baseY); 269 | updateBottom(baseX, baseY); 270 | if (!mAreaChanged) { 271 | if ((baseX < Until.PARKING_LINE) 272 | || (baseX > Until.PARKING_LINE_RIGHT)) { 273 | AppLog.i("Suhao", "LEFT && > MID_LINE"); 274 | handler4Parking.removeCallbacks(runnable4Parking); 275 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 276 | return; 277 | } 278 | if ((mOriginSide) && (baseX > Until.MID_LINE)) { 279 | AppLog.i("Suhao", "LEFT && > MID_LINE"); 280 | handler4Parking.removeCallbacks(runnable4Parking); 281 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 282 | return; 283 | } 284 | if ((!mOriginSide) && (baseX < Until.MID_LINE)) { 285 | AppLog.i("Suhao", "LEFT && > MID_LINE"); 286 | handler4Parking.removeCallbacks(runnable4Parking); 287 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 288 | return; 289 | } 290 | handler4Shrink.removeCallbacks(runnable4Shrink); 291 | handler4Parking.postDelayed(runnable4Parking, mAutoUpdatePeriod); 292 | return; 293 | } 294 | AppLog.i("Suhao", "else"); 295 | handler4Parking.removeCallbacks(runnable4Parking); 296 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 297 | } 298 | 299 | public static void stop() { 300 | AppLog.i("Suhao.TransParent", "AnimationParking.stop()"); 301 | AnimationTransparent.stop(); 302 | handler4Parking.removeCallbacks(runnable4Parking); 303 | handler4Shrink.removeCallbacks(runnable4Shrink); 304 | handler4Turning.removeCallbacks(runnable4Turning); 305 | mTimeOut = false; 306 | handler4PosCheck.postDelayed(runnable4PosCheck, mVelocityTime); 307 | } 308 | 309 | private static void turning() { 310 | handler4Shrink.postDelayed(runnable4Shrink, mAutoUpdatePeriod); 311 | handler4Turning.removeCallbacks(runnable4Turning); 312 | } 313 | 314 | public static void updateAll(int x, int y) { 315 | if (x < 0) { 316 | x = 0; 317 | } 318 | if (x > Until.SCREEM_WIDTH - Until.IMAGE_WIDTH) { 319 | x = Until.SCREEM_WIDTH - Until.IMAGE_WIDTH; 320 | } 321 | if (y < 0) { 322 | y = 0; 323 | } 324 | MeterBase.MeterMap.get(MeterBack.NAME).update(x, y); 325 | MeterBase.baseX = x; 326 | MeterBase.baseY = y; 327 | if (mOriginSide) { 328 | updateAllLeft(x, y); 329 | } else { 330 | updateAllRight(x, y); 331 | } 332 | } 333 | 334 | private static void updateAllLeft(int x, int y) { 335 | showOrHide(x); 336 | posCalculateLeftX(x, y); 337 | MeterBase.MeterMap.get(MeterRecent.NAME).update(recentX, recentY); 338 | MeterBase.MeterMap.get(MeterHome.NAME).update(homeX, homeY); 339 | MeterBase.MeterMap.get(MeterMenu.NAME).update(menuX, menuY); 340 | } 341 | 342 | private static void updateAllRight(int x, int y) { 343 | showOrHide(x); 344 | if (x >= Until.EXPEND_LINE_RIGHT) { 345 | recentX = x + Until.EXPEND_LINE; 346 | recentY = y; 347 | homeX = (x + Until.SCREEM_WIDTH - Until.IMAGE_WIDTH) / 2; 348 | homeY = y - (Until.SCREEM_WIDTH - Until.IMAGE_WIDTH - x) / 2; 349 | menuX = (x + Until.SCREEM_WIDTH - Until.IMAGE_WIDTH) / 2; 350 | menuY = y + (Until.SCREEM_WIDTH - Until.IMAGE_WIDTH - x) / 2; 351 | } else { 352 | if (x > Until.MID_LINE) { 353 | recentX = x + Until.EXPEND_LINE; 354 | recentY = y; 355 | homeX = x + Until.EXPEND_LINE / 2; 356 | homeY = y - Until.EXPEND_LINE / 2; 357 | menuX = x + Until.EXPEND_LINE / 2; 358 | menuY = y + Until.EXPEND_LINE / 2; 359 | } else if (x > Until.MID_LINE - Until.SHRINK_LINE) { 360 | recentX = x + Until.EXPEND_LINE + Until.EXPEND_LINE 361 | / Until.SHRINK_LINE * (x - Until.MID_LINE); 362 | recentY = y; 363 | homeX = x + Until.EXPEND_LINE / 2 + Until.EXPEND_LINE 364 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 365 | homeY = y - Until.EXPEND_LINE / 2 - Until.EXPEND_LINE 366 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 367 | menuX = x + Until.EXPEND_LINE / 2 + Until.EXPEND_LINE 368 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 369 | menuY = y + Until.EXPEND_LINE / 2 + Until.EXPEND_LINE 370 | / Until.SHRINK_LINE * (x - Until.MID_LINE) / 2; 371 | } else if (!mOriginSide) { 372 | mAreaChanged = true; 373 | recentX = x; 374 | recentY = y; 375 | homeX = x; 376 | homeY = y; 377 | menuX = x; 378 | menuY = y; 379 | hideSub(); 380 | } 381 | } 382 | MeterBase.MeterMap.get(MeterRecent.NAME).update(recentX, recentY); 383 | MeterBase.MeterMap.get(MeterHome.NAME).update(homeX, homeY); 384 | MeterBase.MeterMap.get(MeterMenu.NAME).update(menuX, menuY); 385 | } 386 | 387 | private static void updateBottom(int x, int y) { 388 | if (y <= Until.BOTTOM_LINE) { 389 | AppLog.i("Bottom", "return"); 390 | return; 391 | } 392 | 393 | if (mOriginSide) { 394 | if (x >= Until.PARKING_LINE && x <= Until.MID_LINE) { 395 | AppLog.i("Bottom", "LEFT bar = " + Until.STATUS_HEIGHT); 396 | int offsetY = Until.BOTTOM_LINE; 397 | baseX = x; 398 | baseY = offsetY; 399 | updateAll(x, offsetY); 400 | } 401 | } else { 402 | if (x <= Until.SCREEM_WIDTH - Until.PARKING_LINE 403 | && x > Until.MID_LINE) { 404 | AppLog.i("Bottom", "RIGHT"); 405 | int offsetY = Until.BOTTOM_LINE; 406 | baseX = x; 407 | baseY = offsetY; 408 | updateAll(x, offsetY); 409 | } 410 | } 411 | } 412 | 413 | private static void updateTop(int x, int y) { 414 | if (y >= (int) (0.707D * Until.IMAGE_WIDTH)) { 415 | return; 416 | } 417 | 418 | if (mOriginSide) { 419 | if (x >= Until.PARKING_LINE && x <= Until.MID_LINE) { 420 | int offsetY = Until.EXPEND_LINE / 2; 421 | baseX = x; 422 | baseY = offsetY; 423 | updateAll(x, offsetY); 424 | } 425 | } else { 426 | if (x <= Until.SCREEM_WIDTH - Until.PARKING_LINE 427 | && x > Until.MID_LINE) { 428 | int offsetY = Until.EXPEND_LINE / 2; 429 | baseX = x; 430 | baseY = offsetY; 431 | updateAll(x, offsetY); 432 | } 433 | } 434 | 435 | } 436 | } 437 | -------------------------------------------------------------------------------- /src/com/way/mipop/animation/AnimationTransparent.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.animation; 2 | 3 | import android.os.Handler; 4 | import android.view.View; 5 | 6 | import com.way.mipop.widget.MeterBack; 7 | import com.way.mipop.widget.MeterBase; 8 | import com.way.mipop.widget.MeterHome; 9 | import com.way.mipop.widget.MeterMenu; 10 | import com.way.mipop.widget.MeterRecent; 11 | 12 | public class AnimationTransparent { 13 | private static int currentAlpha = 255; 14 | private static int endAlpha = 100; 15 | private static int startAlpha = 255; 16 | private static long time4Trans = 2000L; 17 | private static Handler handler4Transparent = new Handler(); 18 | private static int periodTime = 10; 19 | private static Runnable runnable4Transparent = new Runnable() { 20 | @Override 21 | public void run() { 22 | transparenting(); 23 | } 24 | }; 25 | 26 | public static void start() { 27 | periodTime = (int) (time4Trans / Math.abs(startAlpha - endAlpha)); 28 | handler4Transparent.postDelayed(runnable4Transparent, 1L); 29 | MeterBase.MeterMap.get(MeterHome.NAME).setVisibility(View.GONE); 30 | MeterBase.MeterMap.get(MeterMenu.NAME).setVisibility(View.GONE); 31 | MeterBase.MeterMap.get(MeterRecent.NAME).setVisibility(View.GONE); 32 | } 33 | 34 | public static void stop() { 35 | currentAlpha = startAlpha; 36 | handler4Transparent.removeCallbacks(runnable4Transparent); 37 | MeterBase.MeterMap.get(MeterBack.NAME).setAlpha(startAlpha / 255.0f); 38 | MeterBase.MeterMap.get(MeterHome.NAME).setVisibility(View.VISIBLE); 39 | MeterBase.MeterMap.get(MeterMenu.NAME).setVisibility(View.VISIBLE); 40 | MeterBase.MeterMap.get(MeterRecent.NAME).setVisibility(View.VISIBLE); 41 | } 42 | 43 | private static void transparenting() { 44 | if (currentAlpha <= endAlpha) { 45 | return; 46 | } 47 | currentAlpha = currentAlpha - 1; 48 | MeterBase.MeterMap.get(MeterBack.NAME).setAlpha(currentAlpha / 255.0f); 49 | periodTime = (int) (time4Trans / Math.abs(startAlpha - endAlpha)); 50 | handler4Transparent.postDelayed(runnable4Transparent, periodTime); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/com/way/mipop/api/App.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.api; 2 | 3 | import android.app.Application; 4 | import android.view.View; 5 | 6 | import com.way.mipop.animation.AnimationParking; 7 | import com.way.mipop.animation.AnimationTransparent; 8 | import com.way.mipop.widget.MeterBack; 9 | import com.way.mipop.widget.MeterBase; 10 | import com.way.mipop.widget.MeterHome; 11 | import com.way.mipop.widget.MeterMenu; 12 | import com.way.mipop.widget.MeterRecent; 13 | import com.way.mipop.widget.Until; 14 | 15 | public class App extends Application { 16 | 17 | public static void hideMipop() { 18 | MeterBase.MeterMap.get(MeterHome.NAME).setVisibility(View.GONE); 19 | MeterBase.MeterMap.get(MeterRecent.NAME).setVisibility(View.GONE); 20 | MeterBase.MeterMap.get(MeterMenu.NAME).setVisibility(View.GONE); 21 | MeterBase.MeterMap.get(MeterBack.NAME).setVisibility(View.GONE); 22 | } 23 | 24 | public static void showMipop() { 25 | AnimationParking.stop(); 26 | AnimationParking.mOriginSide = AnimationParking.LEFT; 27 | AnimationParking.baseX = -1; 28 | AnimationParking.updateAll(-1, MeterBack.baseY); 29 | MeterBase.MeterMap.get(MeterBack.NAME).setVisibility(View.VISIBLE); 30 | MeterBase.MeterMap.get(MeterHome.NAME).setVisibility(View.GONE); 31 | MeterBase.MeterMap.get(MeterRecent.NAME).setVisibility(View.GONE); 32 | MeterBase.MeterMap.get(MeterMenu.NAME).setVisibility(View.GONE); 33 | MeterBase.MeterMap.get(MeterBack.NAME).setAlpha(0.4f); 34 | AnimationParking.shrinkStart(); 35 | } 36 | 37 | public void onCreate() { 38 | super.onCreate(); 39 | Until.initialPop(this); 40 | new MeterMenu(this); 41 | new MeterRecent(this); 42 | new MeterHome(this); 43 | new MeterBack(this); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/com/way/mipop/widget/MeterBack.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.widget; 2 | 3 | import android.app.Instrumentation; 4 | import android.content.Context; 5 | import android.content.res.Configuration; 6 | import android.view.MotionEvent; 7 | 8 | import com.way.mipop.AppLog; 9 | import com.way.mipop.R; 10 | import com.way.mipop.animation.AnimationParking; 11 | 12 | public class MeterBack extends MeterBase { 13 | public static final String NAME = MeterBack.class.getSimpleName(); 14 | private int changeX = 0; 15 | private int changeY = 0; 16 | private boolean hasMoved = false; 17 | private int mTouchStartX = 0; 18 | private int mTouchStartY = 0; 19 | 20 | public MeterBack(Context context) { 21 | super(context); 22 | Register(NAME, this); 23 | setSoundEffectsEnabled(true); 24 | setImageResource(R.drawable.back_selector); 25 | setResId(R.drawable.back, R.drawable.back_pressed); 26 | } 27 | 28 | public void Click() { 29 | AppLog.i("way", "back click"); 30 | playSoundEffect(0); 31 | new Thread() { 32 | public void run() { 33 | try { 34 | new Instrumentation().sendKeyDownUpSync(4); 35 | AppLog.i("shenzhan", "Back implement"); 36 | } catch (Exception e) { 37 | AppLog.d("shenzhan", e.toString()); 38 | } 39 | } 40 | }.start(); 41 | } 42 | 43 | public void LongClick() { 44 | AppLog.i("way", "back long click"); 45 | } 46 | 47 | protected void onConfigurationChanged(Configuration configuration) { 48 | super.onConfigurationChanged(configuration); 49 | Until.initialPop(getContext()); 50 | AnimationParking.land(); 51 | } 52 | 53 | @Override 54 | public boolean onTouchEvent(MotionEvent event) { 55 | int rawX = (int) event.getRawX(); 56 | int rawY = (int) event.getRawY() - Until.STATUS_HEIGHT; 57 | //if ((Math.abs(rawX - mTouchStartX) <= Until.MOVE_MAX_SIZE) 58 | // && (Math.abs(rawY - mTouchStartY) <= Until.MOVE_MAX_SIZE)) 59 | // return super.onTouchEvent(event); 60 | switch (event.getAction()) { 61 | case MotionEvent.ACTION_DOWN: 62 | AppLog.i("OUT", "back ACTION_DOWN" + this.hasMoved); 63 | this.changeX = rawX; 64 | this.changeY = rawY; 65 | this.mTouchStartX = rawX; 66 | this.mTouchStartY = rawY; 67 | break; 68 | case MotionEvent.ACTION_MOVE: 69 | AppLog.i("OUT", "back ACTION_OUTSIDE"); 70 | int offsetX = rawX - changeX; 71 | int offsetY = rawY - changeY; 72 | if ((Math.abs(offsetX) > 3) || (Math.abs(offsetY) > 3)) { 73 | //AppLog.i("way", "baseX/offsetX = " + baseX + "/" + offsetX); 74 | baseX = offsetX + baseX; 75 | baseY = offsetY + baseY; 76 | AnimationParking.updateAll(baseX, baseY); 77 | changeX = rawX; 78 | changeY = rawY; 79 | moved(); 80 | } 81 | break; 82 | 83 | case MotionEvent.ACTION_UP: 84 | AppLog.i("Suhao.Click", "MeterBacd.UP, MOVE_MAX_SIZE/baseX= " 85 | + Until.MOVE_MAX_SIZE + " / " + baseX); 86 | if (!this.hasMoved) { 87 | } 88 | hasMoved = false; 89 | break; 90 | default: 91 | break; 92 | } 93 | return super.onTouchEvent(event); 94 | 95 | } 96 | /* boolean bool = true; 97 | int i = (int)event.getRawX(); 98 | int j = -25 + (int)event.getRawY(); 99 | switch (event.getAction()) 100 | { 101 | } 102 | for (;;) 103 | { 104 | bool = super.onTouchEvent(event); 105 | do 106 | { 107 | return bool; 108 | AppLog.i("OUT", "back ACTION_DOWN" + this.hasMoved); 109 | mTouchDown = bool; 110 | this.changeX = i; 111 | this.changeY = j; 112 | this.mTouchStartX = i; 113 | this.mTouchStartY = j; 114 | this.isDown = bool; 115 | break; 116 | AppLog.i("OUT", "back ACTION_OUTSIDE"); 117 | break; 118 | int k = i - this.changeX; 119 | int m = j - this.changeY; 120 | if ((Math.abs(k) > 3) || (Math.abs(m) > 3)) 121 | { 122 | AppLog.i("MBack", "baseX/offsetX = " + baseX + "/" + k); 123 | baseX = k + baseX; 124 | baseY = m + baseY; 125 | AnimationParking.updateAll(baseX, baseY); 126 | this.changeX = i; 127 | this.changeY = j; 128 | } 129 | } while ((Math.abs(i - this.mTouchStartX) <= Until.MOVE_MAX_SIZE) && (Math.abs(j - this.mTouchStartY) <= Until.MOVE_MAX_SIZE)); 130 | moved(); 131 | return bool; 132 | AppLog.i("Suhao.Click", "MeterBacd.UP, MOVE_MAX_SIZE/baseX= " + Until.MOVE_MAX_SIZE + " / " + baseX); 133 | if (!this.hasMoved) {} 134 | mTouchDown = false; 135 | this.hasMoved = false; 136 | this.isDown = false; 137 | }*/ 138 | } 139 | -------------------------------------------------------------------------------- /src/com/way/mipop/widget/MeterBase.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.widget; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import android.content.Context; 7 | import android.graphics.Paint; 8 | import android.graphics.PixelFormat; 9 | import android.os.Handler; 10 | import android.view.Gravity; 11 | import android.view.MotionEvent; 12 | import android.view.WindowManager; 13 | import android.view.WindowManager.LayoutParams; 14 | import android.widget.ImageView; 15 | 16 | import com.way.mipop.AppLog; 17 | import com.way.mipop.animation.AnimationParking; 18 | 19 | public abstract class MeterBase extends ImageView { 20 | public static Map MeterMap = new HashMap(); 21 | public static int baseX = 0; 22 | public static int baseY = Until.SCREEM_HEIGHT / 2; 23 | public static int mLeftMargin = 0; 24 | public static boolean mTouchDown = false; 25 | public static Paint paint = new Paint(); 26 | private Handler handler4LongClick = new Handler(); 27 | private boolean hasMoved = false; 28 | public boolean isLongClick = false; 29 | private final long mTime4LongClick = 1000L; 30 | public WindowManager mWindowManager = null; 31 | private int resId = 0; 32 | private int resIdPressed = 0; 33 | private Runnable runnable4LongClick = new Runnable() { 34 | public void run() { 35 | isLongClick = true; 36 | LongClick(); 37 | } 38 | }; 39 | public WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams(); 40 | 41 | public MeterBase(Context context) { 42 | super(context); 43 | this.mWindowManager = ((WindowManager) context.getApplicationContext() 44 | .getSystemService(Context.WINDOW_SERVICE)); 45 | this.wmParams.type = LayoutParams.TYPE_SYSTEM_ALERT; 46 | this.wmParams.format = PixelFormat.TRANSPARENT; 47 | wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 48 | this.wmParams.gravity = Gravity.LEFT | Gravity.TOP; 49 | this.wmParams.x = baseX; 50 | this.wmParams.y = baseY; 51 | this.wmParams.height = Until.IMAGE_WIDTH; 52 | this.wmParams.width = Until.IMAGE_WIDTH; 53 | this.mWindowManager.addView(this, wmParams); 54 | } 55 | 56 | public static Map getMap() { 57 | return MeterMap; 58 | } 59 | 60 | protected abstract void Click(); 61 | 62 | protected abstract void LongClick(); 63 | 64 | public void Register(String name, MeterBase key) { 65 | MeterMap.put(name, key); 66 | } 67 | 68 | public void moved() { 69 | hasMoved = true; 70 | handler4LongClick.removeCallbacks(runnable4LongClick); 71 | } 72 | 73 | @Override 74 | public boolean onTouchEvent(MotionEvent event) { 75 | switch (event.getAction()) { 76 | case MotionEvent.ACTION_DOWN: 77 | AppLog.i("OUT", "base DOWN" + hasMoved); 78 | setImageResource(resIdPressed); 79 | handler4LongClick.postDelayed(runnable4LongClick, mTime4LongClick); 80 | AnimationParking.stop(); 81 | return true; 82 | case MotionEvent.ACTION_MOVE: 83 | return true; 84 | case MotionEvent.ACTION_UP: 85 | AppLog.i("OUT", "base UP" + this.hasMoved); 86 | setImageResource(resId); 87 | this.handler4LongClick.removeCallbacks(runnable4LongClick); 88 | if (!hasMoved) { 89 | if (!isLongClick) { 90 | AppLog.i("Suhao.Click", "MeterBase.UP, Click"); 91 | Click(); 92 | } 93 | } 94 | if(isLongClick){ 95 | AppLog.i("Suhao.Click", "MeterBase.UP, Long click"); 96 | }else if(hasMoved){ 97 | AppLog.i("Suhao.Click", "MeterBase.UP, has moved"); 98 | } 99 | 100 | hasMoved = false; 101 | isLongClick = false; 102 | AnimationParking.start(); 103 | return true; 104 | 105 | default: 106 | break; 107 | } 108 | AppLog.i("OUT", "base ACTION_OUTSIDE" + this.hasMoved); 109 | AnimationParking.shrinkStart(); 110 | return true; 111 | /*for (;;) 112 | { 113 | return true; 114 | AppLog.i("OUT", "base DOWN" + this.hasMoved); 115 | setImageResource(this.resIdPressed); 116 | this.handler4LongClick.postDelayed(this.runnable4LongClick, 1000L); 117 | AnimationParking.stop(); 118 | continue; 119 | AppLog.i("OUT", "base UP" + this.hasMoved); 120 | setImageResource(this.resId); 121 | this.handler4LongClick.removeCallbacks(this.runnable4LongClick); 122 | if (!this.hasMoved) { 123 | if (!this.isLongClick) 124 | { 125 | AppLog.i("Suhao.Click", "MeterBase.UP, Click"); 126 | Click(); 127 | } 128 | } 129 | for (;;) 130 | { 131 | this.hasMoved = false; 132 | this.isLongClick = false; 133 | AnimationParking.start(); 134 | break; 135 | AppLog.i("Suhao.Click", "MeterBase.UP, Long click"); 136 | continue; 137 | AppLog.i("Suhao.Click", "MeterBase.UP, has moved"); 138 | } 139 | AppLog.i("OUT", "base ACTION_OUTSIDE" + this.hasMoved); 140 | AnimationParking.shrinkStart(); 141 | }*/ 142 | } 143 | 144 | public void setResId(int normal, int pressed) { 145 | resId = normal; 146 | resIdPressed = pressed; 147 | } 148 | 149 | public void update(int x, int y) { 150 | wmParams.x = x; 151 | wmParams.y = y; 152 | mWindowManager.updateViewLayout(this, wmParams); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/com/way/mipop/widget/MeterHome.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.widget; 2 | 3 | import com.way.mipop.AppLog; 4 | import com.way.mipop.R; 5 | 6 | import android.app.Instrumentation; 7 | import android.content.Context; 8 | 9 | public class MeterHome extends MeterBase { 10 | public static final String NAME = MeterHome.class.getSimpleName(); 11 | 12 | public MeterHome(Context context) { 13 | super(context); 14 | Register(NAME, this); 15 | setSoundEffectsEnabled(true); 16 | setImageResource(R.drawable.home_selector); 17 | setResId(R.drawable.home, R.drawable.home_pressed); 18 | } 19 | 20 | public void Click() { 21 | AppLog.i("way", "home click"); 22 | playSoundEffect(0); 23 | new Thread() { 24 | public void run() { 25 | try { 26 | new Instrumentation().sendKeyDownUpSync(3); 27 | AppLog.i("shenzhan", "Home implement"); 28 | return; 29 | } catch (Exception e) { 30 | AppLog.d("shenzhan", e.toString()); 31 | } 32 | } 33 | }.start(); 34 | } 35 | 36 | public void LongClick() { 37 | AppLog.i("way", "home long click"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/way/mipop/widget/MeterMenu.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.widget; 2 | 3 | import com.way.mipop.AppLog; 4 | import com.way.mipop.R; 5 | 6 | import android.app.Instrumentation; 7 | import android.content.Context; 8 | 9 | public class MeterMenu extends MeterBase { 10 | public static final String NAME = MeterMenu.class.getSimpleName(); 11 | 12 | public MeterMenu(Context context) { 13 | super(context); 14 | Register(NAME, this); 15 | setSoundEffectsEnabled(true); 16 | setImageResource(R.drawable.menu_selector); 17 | setResId(R.drawable.menu, R.drawable.menu_pressed); 18 | } 19 | 20 | public void Click() { 21 | AppLog.i("way", "menu click"); 22 | playSoundEffect(0); 23 | new Thread() { 24 | public void run() { 25 | try { 26 | new Instrumentation().sendKeyDownUpSync(82); 27 | AppLog.i("shenzhan", "MENU implement"); 28 | return; 29 | } catch (Exception e) { 30 | AppLog.d("HouJiong", e.toString()); 31 | } 32 | } 33 | }.start(); 34 | } 35 | 36 | public void LongClick() { 37 | AppLog.i("way", "menu long click"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/way/mipop/widget/MeterRecent.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.widget; 2 | 3 | import android.content.Context; 4 | import android.os.RemoteException; 5 | 6 | import com.way.mipop.AppLog; 7 | import android.os.ServiceManager; 8 | import com.android.internal.statusbar.IStatusBarService; 9 | import com.android.internal.statusbar.IStatusBarService.Stub; 10 | import com.way.mipop.R; 11 | 12 | public class MeterRecent extends MeterBase { 13 | public static final String NAME = MeterRecent.class.getSimpleName(); 14 | 15 | public MeterRecent(Context paramContext) { 16 | super(paramContext); 17 | Register(NAME, this); 18 | setSoundEffectsEnabled(true); 19 | setImageResource(R.drawable.recent_selector); 20 | setResId(R.drawable.recent, R.drawable.recent_pressed); 21 | } 22 | 23 | public void Click() { 24 | AppLog.i("way", "recent click"); 25 | playSoundEffect(0); 26 | new Thread() { 27 | public void run() { 28 | IStatusBarService iStatusBarService = IStatusBarService.Stub 29 | .asInterface(ServiceManager.getService("statusbar")); 30 | if (iStatusBarService != null) { 31 | } 32 | try { 33 | iStatusBarService.topAppWindowChanged(false); 34 | iStatusBarService.toggleRecentApps(); 35 | return; 36 | } catch (RemoteException e) { 37 | AppLog.i("Input", "DeadOjbectException"); 38 | } 39 | } 40 | }.start(); 41 | } 42 | 43 | public void LongClick() { 44 | AppLog.i("way", "recent long click"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/com/way/mipop/widget/Until.java: -------------------------------------------------------------------------------- 1 | package com.way.mipop.widget; 2 | 3 | import android.content.Context; 4 | import android.util.DisplayMetrics; 5 | import android.view.WindowManager; 6 | 7 | import com.way.mipop.AppLog; 8 | import com.way.mipop.R; 9 | 10 | public class Until { 11 | public static int BOTTOM_LINE; 12 | public static int EXPEND_LINE; 13 | public static int EXPEND_LINE_RIGHT; 14 | public static int EXPEND_OFFSET; 15 | public static int IMAGE_WIDTH; 16 | public static int MID_LINE; 17 | public static int MOVE_MAX_SIZE; 18 | public static int PARKING_LINE; 19 | public static int PARKING_LINE_RIGHT; 20 | public static int SCREEM_HEIGHT; 21 | public static int SCREEM_WIDTH; 22 | public static int SHRINK_LINE; 23 | public static int STATUS_HEIGHT; 24 | private static final int EXPEND_OFFSET_FACTOR = 10; 25 | private static final int IMAGE_HEIGHT_FACTOR = 6; 26 | private static final int MID_LINE_FACTOR = 2; 27 | private static final int MOVE_MAX_FACTOR = 5; 28 | private static float PARKING_FACTOR = 0.707F; 29 | private static final int SHRINK_FACTOR = 2; 30 | 31 | public static void initialPop(Context context) { 32 | DisplayMetrics displayMetrics = new DisplayMetrics(); 33 | ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)) 34 | .getDefaultDisplay().getMetrics(displayMetrics); 35 | SCREEM_WIDTH = displayMetrics.widthPixels; 36 | SCREEM_HEIGHT = displayMetrics.heightPixels; 37 | setStatusBarHeight(context); 38 | IMAGE_WIDTH = Math.min(SCREEM_WIDTH, SCREEM_HEIGHT) 39 | / IMAGE_HEIGHT_FACTOR; 40 | MID_LINE = (SCREEM_WIDTH - IMAGE_WIDTH) / MID_LINE_FACTOR; 41 | MOVE_MAX_SIZE = IMAGE_WIDTH / MOVE_MAX_FACTOR; 42 | EXPEND_OFFSET = IMAGE_WIDTH / EXPEND_OFFSET_FACTOR; 43 | EXPEND_LINE = (int) (1.414D * IMAGE_WIDTH) + EXPEND_OFFSET; 44 | SHRINK_LINE = IMAGE_WIDTH / SHRINK_FACTOR; 45 | PARKING_LINE = (int) (PARKING_FACTOR * IMAGE_WIDTH); 46 | BOTTOM_LINE = SCREEM_HEIGHT - STATUS_HEIGHT - IMAGE_WIDTH - EXPEND_LINE 47 | / 2; 48 | EXPEND_LINE_RIGHT = SCREEM_WIDTH - IMAGE_WIDTH - EXPEND_LINE; 49 | PARKING_LINE_RIGHT = SCREEM_WIDTH - IMAGE_WIDTH - PARKING_LINE; 50 | } 51 | 52 | private static void setStatusBarHeight(Context context) { 53 | try { 54 | Class clasz = Class.forName("com.android.internal.R$dimen"); 55 | Object object = clasz.newInstance(); 56 | int i = Integer.parseInt(clasz.getField("status_bar_height") 57 | .get(object).toString()); 58 | STATUS_HEIGHT = context.getResources().getDimensionPixelSize(i); 59 | AppLog.i("way", "StatusBarHeight = " + STATUS_HEIGHT); 60 | } catch (Exception e) { 61 | STATUS_HEIGHT = context.getResources().getDimensionPixelSize( 62 | R.dimen.status_bar_height); 63 | e.printStackTrace(); 64 | } 65 | } 66 | } 67 | --------------------------------------------------------------------------------