From b040147af392ad19f7f9807ed14bfa4fb51f39ba Mon Sep 17 00:00:00 2001 From: brnogz Date: Tue, 6 Feb 2018 21:56:19 +0300 Subject: [PATCH 1/2] multiple view support added to FloatingViewListener, OnKeyListener support added, remove method is now public to make easy to manage FloatingView instances --- build.gradle | 2 +- .../android/floatingview/FloatingView.java | 2 +- .../floatingview/FloatingViewListener.java | 4 +- .../floatingview/FloatingViewManager.java | 14 +++- .../floatingview/FullscreenObserverView.java | 17 +++- .../sample/service/ChatHeadService.java | 81 ++++++++++++++++--- .../service/CustomFloatingViewService.java | 2 +- 7 files changed, 102 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 38f9ac3..3a027ae 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0' + classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingView.java b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingView.java index 4839faa..4c74270 100644 --- a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingView.java +++ b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingView.java @@ -52,7 +52,7 @@ * http://stackoverflow.com/questions/18503050/how-to-create-draggabble-system-alert-in-android * FIXME:Nexus5+YouTubeアプリの場合にナビゲーションバーよりも前面に出てきてしまう */ -class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawListener { +public class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawListener { /** * 移動に最低必要なしきい値(dp) diff --git a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewListener.java b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewListener.java index 9a279e5..148a59d 100644 --- a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewListener.java +++ b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewListener.java @@ -17,6 +17,8 @@ package jp.co.recruit_lifestyle.android.floatingview; +import android.view.View; + /** * FloatingViewのリスナです。 */ @@ -34,6 +36,6 @@ public interface FloatingViewListener { * @param x x coordinate * @param y y coordinate */ - void onTouchFinished(boolean isFinishing, int x, int y); + void onTouchFinished(View v,boolean isFinishing, int x, int y); } diff --git a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java index 8ca9a1d..cc37c26 100644 --- a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java +++ b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java @@ -369,7 +369,7 @@ else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) if (mFloatingViewListener != null) { final boolean isFinishing = mTargetFloatingView.getState() == FloatingView.STATE_FINISHING; final WindowManager.LayoutParams params = mTargetFloatingView.getWindowLayoutParams(); - mFloatingViewListener.onTouchFinished(isFinishing, params.x, params.y); + mFloatingViewListener.onTouchFinished(mTargetFloatingView, isFinishing, params.x, params.y); } } @@ -467,8 +467,9 @@ public boolean isTrashViewEnabled() { * * @param view フローティングさせるView * @param options Options + * @return floatingView */ - public void addViewToWindow(View view, Options options) { + public FloatingView addViewToWindow(View view, Options options) { final boolean isFirstAttach = mFloatingViewList.isEmpty(); // FloatingView final FloatingView floatingView = new FloatingView(mContext); @@ -482,6 +483,7 @@ public void addViewToWindow(View view, Options options) { // set FloatingView size final FrameLayout.LayoutParams targetParams = new FrameLayout.LayoutParams(options.floatingViewWidth, options.floatingViewHeight); view.setLayoutParams(targetParams); + floatingView.setTag(view.getTag()); floatingView.addView(view); // 非表示モードの場合 @@ -503,6 +505,8 @@ public void addViewToWindow(View view, Options options) { } // 必ずトップに来て欲しいので毎回貼り付け mWindowManager.addView(mTrashView, mTrashView.getWindowLayoutParams()); + + return floatingView; } /** @@ -510,7 +514,7 @@ public void addViewToWindow(View view, Options options) { * * @param floatingView FloatingView */ - private void removeViewToWindow(FloatingView floatingView) { + public void removeViewToWindow(FloatingView floatingView) { final int matchIndex = mFloatingViewList.indexOf(floatingView); // 見つかった場合は表示とリストから削除 if (matchIndex != -1) { @@ -542,6 +546,10 @@ public void removeAllViewToWindow() { mFloatingViewList.clear(); } + public void setOnKeyListener(View.OnKeyListener listener){ + mFullscreenObserverView.setOnKeyListener(listener); + } + /** * FloatingViewを貼り付ける際のオプションを表すクラスです。 */ diff --git a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java index 4b77351..cb0babb 100644 --- a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java +++ b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java @@ -20,6 +20,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Build; +import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -62,6 +63,8 @@ class FullscreenObserverView extends View implements ViewTreeObserver.OnGlobalLa */ private final Rect mWindowRect; + private OnKeyListener mKeyListener; + static { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) { OVERLAY_TYPE = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; @@ -84,8 +87,7 @@ class FullscreenObserverView extends View implements ViewTreeObserver.OnGlobalLa mParams.width = 1; mParams.height = ViewGroup.LayoutParams.MATCH_PARENT; mParams.type = OVERLAY_TYPE; - mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | + mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; mParams.format = PixelFormat.TRANSLUCENT; @@ -142,6 +144,17 @@ public void onSystemUiVisibilityChange(int visibility) { } } + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + return (mKeyListener != null && mKeyListener.onKey(this, event.getKeyCode(), event)) || super.dispatchKeyEvent(event); + } + + @Override + public void setOnKeyListener(OnKeyListener l) { + super.setOnKeyListener(l); + mKeyListener = l; + } + /** * WindowManager.LayoutParams * diff --git a/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java b/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java index d11cd2a..290a517 100644 --- a/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java +++ b/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java @@ -4,16 +4,22 @@ import android.app.Service; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.os.IBinder; +import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import android.support.v4.app.NotificationCompat; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import jp.co.recruit.floatingview.R; +import jp.co.recruit_lifestyle.android.floatingview.FloatingView; import jp.co.recruit_lifestyle.android.floatingview.FloatingViewListener; import jp.co.recruit_lifestyle.android.floatingview.FloatingViewManager; @@ -52,20 +58,44 @@ public int onStartCommand(Intent intent, int flags, int startId) { final WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getMetrics(metrics); final LayoutInflater inflater = LayoutInflater.from(this); + final ImageView iconView = (ImageView) inflater.inflate(R.layout.widget_chathead, null, false); + iconView.setTag("one"); + + final ImageView iconView2 = (ImageView) inflater.inflate(R.layout.widget_chathead, null, false); + iconView2.setTag("two"); + + mFloatingViewManager = new FloatingViewManager(this, this); + mFloatingViewManager.setFixedTrashIconImage(R.drawable.ic_trash_fixed); + mFloatingViewManager.setActionTrashIconImage(R.drawable.ic_trash_action); + + final FloatingView firstReference = mFloatingViewManager.addViewToWindow(iconView, getOptions(metrics, iconView)); + final FloatingView secondReference = mFloatingViewManager.addViewToWindow(iconView2, getOptions(metrics, iconView2)); + + iconView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, getString(R.string.chathead_click_message)); + mFloatingViewManager.removeViewToWindow(secondReference); + } + }); + iconView2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.d(TAG, getString(R.string.chathead_click_message) + " 2"); + mFloatingViewManager.removeViewToWindow(firstReference); } }); - mFloatingViewManager = new FloatingViewManager(this, this); - mFloatingViewManager.setFixedTrashIconImage(R.drawable.ic_trash_fixed); - mFloatingViewManager.setActionTrashIconImage(R.drawable.ic_trash_action); - final FloatingViewManager.Options options = new FloatingViewManager.Options(); - options.overMargin = (int) (16 * metrics.density); - mFloatingViewManager.addViewToWindow(iconView, options); + mFloatingViewManager.setOnKeyListener(new View.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + Log.d(TAG, event.getKeyCode() + " " + event.getCharacters()); + + return true; + } + }); // 常駐起動 startForeground(NOTIFICATION_ID, createNotification(this)); @@ -73,6 +103,32 @@ public void onClick(View v) { return START_REDELIVER_INTENT; } + @NonNull + private FloatingViewManager.Options getOptions(DisplayMetrics metrics, View iconView) { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + FloatingViewManager.Options options = new FloatingViewManager.Options(); + options.overMargin = (int) (16 * metrics.density); + + // Last position + boolean isUseLastPosition = sharedPref.getBoolean("settings_save_last_position", false); + if (isUseLastPosition) { + final int defaultX = options.floatingViewX; + final int defaultY = options.floatingViewY; + options.floatingViewX = sharedPref.getInt(iconView.getTag()+"_x", defaultX); + options.floatingViewY = sharedPref.getInt(iconView.getTag()+"_y", defaultY); + } else { + // Init X/Y + final String initXSettings = sharedPref.getString("settings_init_x", ""); + final String initYSettings = sharedPref.getString("settings_init_y", ""); + if (!TextUtils.isEmpty(initXSettings) && !TextUtils.isEmpty(initYSettings)) { + final int offset = (int) (48 + 8 * metrics.density); + options.floatingViewX = (int) (metrics.widthPixels * Float.parseFloat(initXSettings) - offset); + options.floatingViewY = (int) (metrics.heightPixels * Float.parseFloat(initYSettings) - offset); + } + } + return options; + } + /** * {@inheritDoc} */ @@ -103,11 +159,14 @@ public void onFinishFloatingView() { * {@inheritDoc} */ @Override - public void onTouchFinished(boolean isFinishing, int x, int y) { - if (isFinishing) { - Log.d(TAG, getString(R.string.deleted_soon)); - } else { - Log.d(TAG, getString(R.string.touch_finished_position, x, y)); + public void onTouchFinished(View view, boolean isFinishing, int x, int y) { + if (!isFinishing) { + // Save the last position + final SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit(); + editor.putInt(view.getTag() + "_x", x); + editor.putInt(view.getTag() + "_y", y); + editor.apply(); + } } diff --git a/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/CustomFloatingViewService.java b/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/CustomFloatingViewService.java index cebc2fd..9949810 100644 --- a/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/CustomFloatingViewService.java +++ b/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/CustomFloatingViewService.java @@ -121,7 +121,7 @@ public void onFinishFloatingView() { * {@inheritDoc} */ @Override - public void onTouchFinished(boolean isFinishing, int x, int y) { + public void onTouchFinished(View view, boolean isFinishing, int x, int y) { if (!isFinishing) { // Save the last position final SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit(); From fa7537b5e6264c89457741eac19e688eb0ea0fa3 Mon Sep 17 00:00:00 2001 From: brnogz Date: Sat, 24 Feb 2018 19:16:40 +0300 Subject: [PATCH 2/2] OnKeyListener support removed to make other apps work :) --- .../floatingview/FloatingViewManager.java | 4 ---- .../floatingview/FullscreenObserverView.java | 17 ++--------------- .../sample/service/ChatHeadService.java | 9 --------- 3 files changed, 2 insertions(+), 28 deletions(-) diff --git a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java index cc37c26..8070f56 100644 --- a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java +++ b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewManager.java @@ -546,10 +546,6 @@ public void removeAllViewToWindow() { mFloatingViewList.clear(); } - public void setOnKeyListener(View.OnKeyListener listener){ - mFullscreenObserverView.setOnKeyListener(listener); - } - /** * FloatingViewを貼り付ける際のオプションを表すクラスです。 */ diff --git a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java index cb0babb..4b77351 100644 --- a/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java +++ b/library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FullscreenObserverView.java @@ -20,7 +20,6 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Build; -import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -63,8 +62,6 @@ class FullscreenObserverView extends View implements ViewTreeObserver.OnGlobalLa */ private final Rect mWindowRect; - private OnKeyListener mKeyListener; - static { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N_MR1) { OVERLAY_TYPE = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; @@ -87,7 +84,8 @@ class FullscreenObserverView extends View implements ViewTreeObserver.OnGlobalLa mParams.width = 1; mParams.height = ViewGroup.LayoutParams.MATCH_PARENT; mParams.type = OVERLAY_TYPE; - mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | + mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; mParams.format = PixelFormat.TRANSLUCENT; @@ -144,17 +142,6 @@ public void onSystemUiVisibilityChange(int visibility) { } } - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - return (mKeyListener != null && mKeyListener.onKey(this, event.getKeyCode(), event)) || super.dispatchKeyEvent(event); - } - - @Override - public void setOnKeyListener(OnKeyListener l) { - super.setOnKeyListener(l); - mKeyListener = l; - } - /** * WindowManager.LayoutParams * diff --git a/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java b/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java index 290a517..7aac76e 100644 --- a/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java +++ b/sample/src/main/java/jp/co/recruit_lifestyle/sample/service/ChatHeadService.java @@ -88,15 +88,6 @@ public void onClick(View v) { } }); - mFloatingViewManager.setOnKeyListener(new View.OnKeyListener() { - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - Log.d(TAG, event.getKeyCode() + " " + event.getCharacters()); - - return true; - } - }); - // 常駐起動 startForeground(NOTIFICATION_ID, createNotification(this));