fix(ui): circular menu keep to edge behavior on screen orientation change

This commit is contained in:
hyb1996 2018-04-21 16:53:00 +08:00
parent 188347be34
commit c488e9ccbb
4 changed files with 266 additions and 4 deletions

View File

@ -76,7 +76,7 @@ public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInsp
private static final int IC_ACTION_VIEW = R.drawable.ic_android_eat_js;
CircularActionMenuFloatingWindow mWindow;
CircularMenuWindow mWindow;
private int mState;
private RoundedImageView mActionViewIcon;
private Context mContext;
@ -110,17 +110,17 @@ public class CircularMenu implements Recorder.OnStateChangedListener, LayoutInsp
}
private void initFloaty() {
mWindow = new CircularActionMenuFloatingWindow(new CircularActionMenuFloaty() {
mWindow = new CircularMenuWindow(mContext, new CircularMenuFloaty() {
@Override
public View inflateActionView(FloatyService service, CircularActionMenuFloatingWindow window) {
public View inflateActionView(FloatyService service, CircularMenuWindow window) {
View actionView = View.inflate(service, R.layout.circular_action_view, null);
mActionViewIcon = (RoundedImageView) actionView.findViewById(R.id.icon);
return actionView;
}
@Override
public CircularActionMenu inflateMenuItems(FloatyService service, CircularActionMenuFloatingWindow window) {
public CircularActionMenu inflateMenuItems(FloatyService service, CircularMenuWindow window) {
CircularActionMenu menu = (CircularActionMenu) View.inflate(new ContextThemeWrapper(service, R.style.AppTheme), R.layout.circular_action_menu, null);
ButterKnife.bind(CircularMenu.this, menu);
return menu;

View File

@ -0,0 +1,13 @@
package com.stardust.scriptdroid.ui.floating;
import android.view.View;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.floatingcircularactionmenu.CircularActionMenu;
public interface CircularMenuFloaty {
View inflateActionView(FloatyService service, CircularMenuWindow window);
CircularActionMenu inflateMenuItems(FloatyService service, CircularMenuWindow window);
}

View File

@ -0,0 +1,202 @@
package com.stardust.scriptdroid.ui.floating;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.WindowManager;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.FloatyWindow;
import com.stardust.enhancedfloaty.WindowBridge;
import com.stardust.floatingcircularactionmenu.CircularActionMenu;
import com.stardust.floatingcircularactionmenu.gesture.BounceDragGesture;
public class CircularMenuWindow implements FloatyWindow, SensorEventListener {
protected CircularMenuFloaty mFloaty;
protected WindowManager mWindowManager;
protected CircularActionMenu mCircularActionMenu;
protected View mCircularActionView;
protected BounceDragGesture mDragGesture;
protected OrientationAwareWindowBridge mActionViewWindowBridge;
protected WindowBridge mMenuWindowBridge;
protected WindowManager.LayoutParams mActionViewWindowLayoutParams;
protected WindowManager.LayoutParams mMenuWindowLayoutParams;
protected View.OnClickListener mActionViewOnClickListener;
protected float mKeepToSideHiddenWidthRadio;
protected float mActiveAlpha = 1.0F;
protected float mInactiveAlpha = 0.4F;
private Context mContext;
private OrientationEventListener mOrientationEventListener;
public CircularMenuWindow(Context context, CircularMenuFloaty floaty) {
this.mFloaty = floaty;
mContext = context;
}
public void onCreate(FloatyService service, WindowManager manager) {
this.mWindowManager = manager;
this.mActionViewWindowLayoutParams = this.createWindowLayoutParams();
this.mMenuWindowLayoutParams = this.createWindowLayoutParams();
this.inflateWindowViews(service);
this.initWindowBridge();
this.initGestures();
this.setListeners();
this.setInitialState();
mOrientationEventListener = new OrientationEventListener(mContext) {
@Override
public void onOrientationChanged(int orientation) {
if (mActionViewWindowBridge.isOrientationChanged(orientation)) {
mDragGesture.keepToEdge();
}
}
};
if (mOrientationEventListener.canDetectOrientation()) {
mOrientationEventListener.enable();
}
}
private void setInitialState() {
this.mDragGesture.keepToEdge();
}
private void initGestures() {
this.mDragGesture = new BounceDragGesture(this.mActionViewWindowBridge, this.mCircularActionView);
this.mDragGesture.setKeepToSideHiddenWidthRadio(this.mKeepToSideHiddenWidthRadio);
this.mDragGesture.setPressedAlpha(this.mActiveAlpha);
this.mDragGesture.setUnpressedAlpha(this.mInactiveAlpha);
}
private void initWindowBridge() {
this.mActionViewWindowBridge = new OrientationAwareWindowBridge(this.mActionViewWindowLayoutParams, this.mWindowManager, this.mCircularActionView, mContext);
this.mMenuWindowBridge = new WindowBridge.DefaultImpl(this.mMenuWindowLayoutParams, this.mWindowManager, this.mCircularActionMenu);
}
public void setKeepToSideHiddenWidthRadio(float keepToSideHiddenWidthRadio) {
this.mKeepToSideHiddenWidthRadio = keepToSideHiddenWidthRadio;
if (this.mDragGesture != null) {
this.mDragGesture.setKeepToSideHiddenWidthRadio(this.mKeepToSideHiddenWidthRadio);
}
}
private WindowManager.LayoutParams createWindowLayoutParams() {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(-2, -2, 2003, 520, -3);
layoutParams.gravity = 51;
return layoutParams;
}
private void setListeners() {
this.setOnActionViewClickListener(v -> {
if (isExpanded()) {
collapse();
} else {
expand();
}
});
if (this.mActionViewOnClickListener != null) {
this.mDragGesture.setOnDraggedViewClickListener(this.mActionViewOnClickListener);
}
this.mCircularActionMenu.addOnStateChangeListener(new CircularActionMenu.OnStateChangeListenerAdapter() {
public void onCollapsed(CircularActionMenu menu) {
mCircularActionView.setAlpha(mInactiveAlpha);
}
public void onExpanded(CircularActionMenu menu) {
mCircularActionView.setAlpha(mActiveAlpha);
}
});
}
public void setOnActionViewClickListener(View.OnClickListener listener) {
if (this.mDragGesture == null) {
this.mActionViewOnClickListener = listener;
} else {
this.mDragGesture.setOnDraggedViewClickListener(listener);
}
}
public void expand() {
this.mDragGesture.setEnabled(false);
this.setMenuPositionAtActionView();
if (this.mActionViewWindowBridge.getX() > this.mActionViewWindowBridge.getScreenWidth() / 2) {
this.mCircularActionMenu.expand(3);
} else {
this.mCircularActionMenu.expand(5);
}
}
public void setActiveAlpha(float activeAlpha) {
this.mActiveAlpha = activeAlpha;
if (this.mDragGesture != null) {
this.mDragGesture.setPressedAlpha(activeAlpha);
}
}
public void setInactiveAlpha(float inactiveAlpha) {
this.mInactiveAlpha = inactiveAlpha;
if (this.mDragGesture != null) {
this.mDragGesture.setUnpressedAlpha(this.mInactiveAlpha);
}
}
public void collapse() {
this.mDragGesture.setEnabled(true);
this.setMenuPositionAtActionView();
this.mCircularActionMenu.collapse();
this.mCircularActionView.setAlpha(this.mDragGesture.getUnpressedAlpha());
}
public boolean isExpanded() {
return this.mCircularActionMenu.isExpanded();
}
private void setMenuPositionAtActionView() {
int y = this.mActionViewWindowBridge.getY() - this.mCircularActionMenu.getMeasuredHeight() / 2 + this.mCircularActionView.getMeasuredHeight() / 2;
int x;
if (this.mActionViewWindowBridge.getX() > this.mActionViewWindowBridge.getScreenWidth() / 2) {
x = this.mActionViewWindowBridge.getX() - this.mCircularActionMenu.getExpandedWidth() + this.mCircularActionView.getMeasuredWidth() / 2;
} else {
x = this.mActionViewWindowBridge.getX() - this.mCircularActionMenu.getExpandedWidth() + this.mCircularActionView.getMeasuredWidth();
}
this.mMenuWindowBridge.updatePosition(x, y);
}
private void inflateWindowViews(FloatyService service) {
this.mCircularActionMenu = this.mFloaty.inflateMenuItems(service, this);
this.mCircularActionView = this.mFloaty.inflateActionView(service, this);
this.mCircularActionMenu.setVisibility(View.GONE);
this.mWindowManager.addView(this.mCircularActionMenu, this.mActionViewWindowLayoutParams);
this.mWindowManager.addView(this.mCircularActionView, this.mMenuWindowLayoutParams);
}
public void onServiceDestroy(FloatyService floatyService) {
this.close();
}
public void close() {
mOrientationEventListener.disable();
this.mWindowManager.removeView(this.mCircularActionMenu);
this.mWindowManager.removeView(this.mCircularActionView);
FloatyService.removeWindow(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
mDragGesture.keepToEdge();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}

View File

@ -0,0 +1,47 @@
package com.stardust.scriptdroid.ui.floating;
import android.content.Context;
import android.content.res.Configuration;
import android.view.View;
import android.view.WindowManager;
import com.stardust.enhancedfloaty.WindowBridge;
public class OrientationAwareWindowBridge extends WindowBridge.DefaultImpl {
private Context mContext;
private int mOrientation;
public OrientationAwareWindowBridge(WindowManager.LayoutParams windowLayoutParams, WindowManager windowManager, View windowView, Context context) {
super(windowLayoutParams, windowManager, windowView);
mContext = context;
mOrientation = mContext.getResources().getConfiguration().orientation;
}
public boolean isOrientationChanged(int newOrientation) {
if (mOrientation != newOrientation) {
mOrientation = newOrientation;
return true;
}
return false;
}
@Override
public int getScreenHeight() {
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
return super.getScreenWidth();
} else {
return super.getScreenHeight();
}
}
@Override
public int getScreenWidth() {
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
return super.getScreenHeight();
} else {
return super.getScreenWidth();
}
}
}