Skip to content
This repository was archived by the owner on Feb 3, 2020. It is now read-only.

Commit f37d149

Browse files
Merge pull request #32 from recruit-lifestyle/2.2
2.2
2 parents ae29cc2 + 235d0c2 commit f37d149

File tree

8 files changed

+322
-70
lines changed

8 files changed

+322
-70
lines changed

README.md

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To API Level 14 or later are supported
1212
[SimpleFloating](http://youtu.be/nb8M2p0agF4)
1313

1414
## Requirements
15-
Target Sdk Version : 25
15+
Target Sdk Version : 25
1616
Min Sdk Version : 14
1717

1818
## How to use
@@ -25,7 +25,7 @@ Min Sdk Version : 14
2525
}
2626

2727
dependencies {
28-
compile 'com.github.recruit-lifestyle:FloatingView:2.1'
28+
compile 'com.github.recruit-lifestyle:FloatingView:2.2'
2929
}
3030
```
3131

@@ -53,9 +53,9 @@ public class ChatHeadService extends Service {
5353
mFloatingViewManager.addViewToWindow(iconView, options);
5454
```
5555

56-
The second argument of FloatingViewManager is FloatingViewListener
56+
The second argument of `FloatingViewManager` is `FloatingViewListener`
5757

58-
Describe the process (onFinishFloatingView) that is called when you exit the FloatingView
58+
Describe the process (`onFinishFloatingView`) that is called when you exit the FloatingView
5959
```java
6060
@Override
6161
public void onFinishFloatingView() {
@@ -87,18 +87,61 @@ example)
8787
activity.startService(new Intent(activity, ChatHeadService.class));
8888
```
8989

90+
## Static Options
91+
It can be set only when displaying for the first time
92+
93+
example)
94+
```java
95+
final FloatingViewManager.Options options = new FloatingViewManager.Options();
96+
options.overMargin = (int) (16 * metrics.density);
97+
mFloatingViewManager.addViewToWindow(iconView, options);
98+
```
99+
100+
|Option|Description|
101+
|:-:|---|
102+
|shape|`FloatingViewManager.SHAPE_CIRCLE`:Cicle(default)<br> `FloatingViewManager.SHAPE_RECTANGLE`:Rectangle|  
103+
|overMargin|Margin over the edge of the screen (px)<br>(default) 0|
104+
|floatingViewX|X coordinate of initial display<br>(default) left side of display|
105+
|floatingViewY|Y coordinate of initial display<br>(default) top of display|
106+
|floatingViewWidth|FloatingView width<br>(default) The width of the layout added to FloatingView |
107+
|floatingViewHeight|FloatingView height<br>(default) The height of the layout added to FloatingView|
108+
|moveDirection|`FloatingViewManager.MOVE_DIRECTION_DEFAULT`:Left end or right end(default)<br> `FloatingViewManager.MOVE_DIRECTION_LEFT`:Left end<br>`FloatingViewManager.MOVE_DIRECTION_RIGHT`:Right end<br>`FloatingViewManager.MOVE_DIRECTION_NONE`:Not move|
109+
|animateInitialMove|If true, animation when first displayed<br>(FloatingViewX, floatingViewY) to screen edge<br>Info: If `MOVE_DIRECTION_NONE` is set, nothing happens|
110+
111+
## Dynamic Options
112+
It can be set any time
113+
114+
exapmle)
115+
```java
116+
mFloatingViewManager.setFixedTrashIconImage(R.drawable.ic_trash_fixed);
117+
mFloatingViewManager.setActionTrashIconImage(R.drawable.ic_trash_action);
118+
```
119+
120+
|Option|Description|
121+
|:-:|---|
122+
|setFixedTrashIconImage|It is an icon that does *not* enlarge when FloatingView overlaps.|
123+
|setActionTrashIconImage|It is an icon that enlarge when FloatingView overlaps.|
124+
|setDisplayMode|`FloatingViewManager.DISPLAY_MODE_SHOW_ALWAYS`:Always show<br>`FloatingViewManager.DISPLAY_MODE_HIDE_ALWAYS`:Always hidden<br>`FloatingViewManager.DISPLAY_MODE_HIDE_FULLSCREEN`:It is hidden when in full screen|
125+
|setTrashViewEnabled|If false, the trash icon does not show during dragging.<br>(default) true|
126+
127+
# Revisions
128+
## Update in 2.2
129+
- Support for large image for FloatingView (not complete, but almost works)([#16](../../issues/16))
130+
- Support size specification of FloatingView([#16](../../issues/16))
131+
- Fix issue [#14](../../issues/14)
132+
90133
## Update in 2.1
91134
- Add `FloatingViewListener#onTouchFinished`.This method is called when the touch action is finished.
92135

93136

94-
## Credits
137+
# Credits
95138

96139
FloatingView is owned and maintained by [RECRUIT LIFESTYLE CO., LTD.](http://www.recruit-lifestyle.co.jp/)
97140

98141
FloatingView was originally created by [Yoshihide Sogawa](https://twitter.com/egg_sogawa)
99142

100143

101-
## License
144+
# License
102145

103146
Copyright 2015 RECRUIT LIFESTYLE CO., LTD.
104147

library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingView.java

Lines changed: 137 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/**
22
* Copyright 2015 RECRUIT LIFESTYLE CO., LTD.
3-
*
3+
* <p>
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -31,6 +31,8 @@
3131
import android.support.annotation.NonNull;
3232
import android.util.DisplayMetrics;
3333
import android.view.Gravity;
34+
import android.view.KeyCharacterMap;
35+
import android.view.KeyEvent;
3436
import android.view.MotionEvent;
3537
import android.view.View;
3638
import android.view.ViewConfiguration;
@@ -114,6 +116,16 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
114116
*/
115117
static final int DEFAULT_Y = Integer.MIN_VALUE;
116118

119+
/**
120+
* Default width size
121+
*/
122+
static final int DEFAULT_WIDTH = ViewGroup.LayoutParams.WRAP_CONTENT;
123+
124+
/**
125+
* Default height size
126+
*/
127+
static final int DEFAULT_HEIGHT = ViewGroup.LayoutParams.WRAP_CONTENT;
128+
117129
/**
118130
* WindowManager
119131
*/
@@ -180,7 +192,34 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
180192
/**
181193
* ステータスバーの高さ
182194
*/
183-
private final int mStatusBarHeight;
195+
private final int mBaseStatusBarHeight;
196+
197+
/**
198+
* Current status bar's height
199+
*/
200+
private int mStatusBarHeight;
201+
202+
/**
203+
* Navigation bar's height(portlait)
204+
*/
205+
private final int mBaseNavigationBarHeight;
206+
207+
/**
208+
* Navigation bar's height
209+
* Placed bottom on the screen(tablet)
210+
* Or placed vertically on the screen(phone)
211+
*/
212+
private final int mBaseNavigationBarRotatedHeight;
213+
214+
/**
215+
* Current Navigation bar's vertical size
216+
*/
217+
private int mNavigationBarVerticalOffset;
218+
219+
/**
220+
* Current Navigation bar's horizontal size
221+
*/
222+
private int mNavigationBarHorizontalOffset;
184223

185224
/**
186225
* 左・右端に寄せるアニメーション
@@ -242,6 +281,11 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
242281
*/
243282
private int mMoveDirection;
244283

284+
/**
285+
* If true, it's a tablet. If false, it's a phone
286+
*/
287+
private final boolean mIsTablet;
288+
245289
/**
246290
* コンストラクタ
247291
*
@@ -266,30 +310,57 @@ class FloatingView extends FrameLayout implements ViewTreeObserver.OnPreDrawList
266310
mLongPressHandler = new LongPressHandler(this);
267311
mMoveEdgeInterpolator = new OvershootInterpolator(MOVE_TO_EDGE_OVERSHOOT_TENSION);
268312
mMoveDirection = FloatingViewManager.MOVE_DIRECTION_DEFAULT;
313+
final Resources resources = context.getResources();
314+
mIsTablet = (resources.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
269315

270316
mMoveLimitRect = new Rect();
271317
mPositionLimitRect = new Rect();
272318

273319
// ステータスバーの高さを取得
274-
final Resources resources = context.getResources();
275-
final int statusBarHeightId = resources.getIdentifier("status_bar_height", "dimen", "android");
276-
if (statusBarHeightId > 0) {
277-
mStatusBarHeight = resources.getDimensionPixelSize(statusBarHeightId);
320+
mBaseStatusBarHeight = getSystemUiDimensionPixelSize(resources, "status_bar_height");
321+
mStatusBarHeight = mBaseStatusBarHeight;
322+
323+
// get navigation bar height
324+
final boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey();
325+
final boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
326+
if (hasMenuKey || hasBackKey) {
327+
mBaseNavigationBarHeight = 0;
328+
mBaseNavigationBarRotatedHeight = 0;
278329
} else {
279-
mStatusBarHeight = 0;
330+
mBaseNavigationBarHeight = getSystemUiDimensionPixelSize(resources, "navigation_bar_height");
331+
final String resName = mIsTablet ? "navigation_bar_height_landscape" : "navigation_bar_width";
332+
mBaseNavigationBarRotatedHeight = getSystemUiDimensionPixelSize(resources, resName);
280333
}
281334

282335
// 初回描画処理用
283336
getViewTreeObserver().addOnPreDrawListener(this);
284337
}
285338

339+
/**
340+
* Get the System ui dimension(pixel)
341+
*
342+
* @param resources {@link Resources}
343+
* @param resName dimension resource name
344+
* @return pixel size
345+
*/
346+
private static int getSystemUiDimensionPixelSize(Resources resources, String resName) {
347+
int pixelSize = 0;
348+
final int resId = resources.getIdentifier(resName, "dimen", "android");
349+
if (resId > 0) {
350+
pixelSize = resources.getDimensionPixelSize(resId);
351+
}
352+
return pixelSize;
353+
}
354+
355+
286356
/**
287357
* 表示位置を決定します。
288358
*/
289359
@Override
290360
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
291361
super.onSizeChanged(w, h, oldw, oldh);
292-
updateViewLayout();
362+
final boolean isSizeChanged = w != oldw || h != oldh;
363+
updateViewLayout(isSizeChanged);
293364
}
294365

295366
/**
@@ -298,7 +369,7 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
298369
@Override
299370
protected void onConfigurationChanged(Configuration newConfig) {
300371
super.onConfigurationChanged(newConfig);
301-
updateViewLayout();
372+
updateViewLayout(false);
302373
}
303374

304375
/**
@@ -332,10 +403,58 @@ public boolean onPreDraw() {
332403
return true;
333404
}
334405

406+
/**
407+
* Called when the layout of the system has changed.
408+
*
409+
* @param isHideStatusBar If true, the status bar is hidden
410+
* @param isHideNavigationBar If true, the navigation bar is hidden
411+
* @param isPortrait If true, the device orientation is portrait
412+
*/
413+
void onUpdateSystemLayout(boolean isHideStatusBar, boolean isHideNavigationBar, boolean isPortrait) {
414+
// status bar
415+
mStatusBarHeight = isHideStatusBar ? 0 : mBaseStatusBarHeight;
416+
// navigation bar
417+
updateNavigationBarOffset(isHideNavigationBar, isPortrait);
418+
updateViewLayout(true);
419+
}
420+
421+
/**
422+
* Update offset of NavigationBar.
423+
*
424+
* @param isHideNavigationBar If true, the navigation bar is hidden
425+
* @param isPortrait If true, the device orientation is portrait
426+
*/
427+
private void updateNavigationBarOffset(boolean isHideNavigationBar, boolean isPortrait) {
428+
if (!isHideNavigationBar) {
429+
mNavigationBarVerticalOffset = 0;
430+
mNavigationBarHorizontalOffset = 0;
431+
return;
432+
}
433+
434+
// If the portrait, is displayed at the bottom of the screen
435+
if (isPortrait) {
436+
mNavigationBarVerticalOffset = mBaseNavigationBarHeight;
437+
mNavigationBarHorizontalOffset = 0;
438+
return;
439+
}
440+
441+
// If it is a Tablet, it will appear at the bottom of the screen.
442+
// If it is Phone, it will appear on the side of the screen
443+
if (mIsTablet) {
444+
mNavigationBarVerticalOffset = mBaseNavigationBarRotatedHeight;
445+
mNavigationBarHorizontalOffset = 0;
446+
} else {
447+
mNavigationBarVerticalOffset = 0;
448+
mNavigationBarHorizontalOffset = mBaseNavigationBarRotatedHeight;
449+
}
450+
}
451+
335452
/**
336453
* 画面サイズから自位置を決定します。
454+
*
455+
* @param isSizeChanged If true, FloatingView has changed size
337456
*/
338-
private void updateViewLayout() {
457+
private void updateViewLayout(boolean isSizeChanged) {
339458
cancelAnimation();
340459

341460
// 前の画面座標を保存
@@ -352,11 +471,11 @@ private void updateViewLayout() {
352471
final int newScreenHeight = mMetrics.heightPixels;
353472

354473
// 移動範囲の設定
355-
mMoveLimitRect.set(-width, -height * 2, newScreenWidth + width, newScreenHeight + height);
356-
mPositionLimitRect.set(-mOverMargin, 0, newScreenWidth - width + mOverMargin, newScreenHeight - mStatusBarHeight - height);
474+
mMoveLimitRect.set(-width, -height * 2, newScreenWidth + width + mNavigationBarHorizontalOffset, newScreenHeight + height + mNavigationBarVerticalOffset);
475+
mPositionLimitRect.set(-mOverMargin, 0, newScreenWidth - width + mOverMargin + mNavigationBarHorizontalOffset, newScreenHeight - mStatusBarHeight - height + mNavigationBarVerticalOffset);
357476

358-
// 縦横切替の場合
359-
if (oldScreenWidth != newScreenWidth || oldScreenHeight != newScreenHeight) {
477+
// FloatingView size changed or device rotating
478+
if (isSizeChanged || oldScreenWidth != newScreenWidth || oldScreenHeight != newScreenHeight) {
360479
// 画面端に移動する場合は現在の位置から左右端を設定
361480
if (mMoveDirection == FloatingViewManager.MOVE_DIRECTION_DEFAULT) {
362481
// 右半分にある場合
@@ -758,7 +877,7 @@ private int getXByTouch() {
758877
* @return FloatingViewのY座標
759878
*/
760879
private int getYByTouch() {
761-
return (int) (mMetrics.heightPixels - (mScreenTouchY - mLocalTouchY + getHeight()));
880+
return (int) (mMetrics.heightPixels + mNavigationBarVerticalOffset - (mScreenTouchY - mLocalTouchY + getHeight()));
762881
}
763882

764883
/**

library/src/main/java/jp/co/recruit_lifestyle/android/floatingview/FloatingViewListener.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/**
22
* Copyright 2015 RECRUIT LIFESTYLE CO., LTD.
3-
*
3+
* <p>
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

0 commit comments

Comments
 (0)