diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b7ccb25..cf8e4e6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,7 +16,7 @@ { +// nativeAndroid.callExternalInterface("changeAccount", ""); + com.quicksdk.User.getInstance().logout(MainActivity.this); + }); + //设置取消按钮 + builder.setNegativeButton("取消",null); + //显示弹框 + builder.show(); + + } + }); } @Override protected void onStart() { super.onStart(); com.quicksdk.Sdk.getInstance().onStart(this); + FloatingView.get().attach(this); } @Override @@ -148,6 +176,7 @@ public class MainActivity extends Activity { protected void onStop() { super.onStop(); com.quicksdk.Sdk.getInstance().onStop(this); + FloatingView.get().detach(this); } @Override diff --git a/app/src/main/java/com/hnjc/wjtx/floatingview/EnFloatingView.java b/app/src/main/java/com/hnjc/wjtx/floatingview/EnFloatingView.java new file mode 100644 index 0000000..d94dc21 --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/floatingview/EnFloatingView.java @@ -0,0 +1,29 @@ +package com.hnjc.wjtx.floatingview; + +import android.content.Context; +import android.support.annotation.DrawableRes; +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; +import android.widget.ImageView; + +import com.hnjc.wjtx.R; + +public class EnFloatingView extends FloatingMagnetView { + + private final ImageView mIcon; + + public EnFloatingView(@NonNull Context context) { + this(context, R.layout.en_floating_view); + } + + public EnFloatingView(@NonNull Context context, @LayoutRes int resource) { + super(context, null); + inflate(context, resource, this); + mIcon = findViewById(R.id.icon); + } + + public void setIconImage(@DrawableRes int resId){ + mIcon.setImageResource(resId); + } + +} diff --git a/app/src/main/java/com/hnjc/wjtx/floatingview/FloatingMagnetView.java b/app/src/main/java/com/hnjc/wjtx/floatingview/FloatingMagnetView.java new file mode 100644 index 0000000..d458770 --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/floatingview/FloatingMagnetView.java @@ -0,0 +1,210 @@ +package com.hnjc.wjtx.floatingview; + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Handler; +import android.os.Looper; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import com.hnjc.wjtx.util.SystemUtils; + +public class FloatingMagnetView extends FrameLayout { + + public static final int MARGIN_EDGE = 13; + private float mOriginalRawX; + private float mOriginalRawY; + private float mOriginalX; + private float mOriginalY; + private MagnetViewListener mMagnetViewListener; + private static final int TOUCH_TIME_THRESHOLD = 150; + private long mLastTouchDownTime; + protected MoveAnimator mMoveAnimator; + protected int mScreenWidth; + private int mScreenHeight; + private int mStatusBarHeight; + private boolean isNearestLeft = true; + private float mPortraitY; + + public void setMagnetViewListener(MagnetViewListener magnetViewListener) { + this.mMagnetViewListener = magnetViewListener; + } + + public FloatingMagnetView(Context context) { + this(context, null); + } + + public FloatingMagnetView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public FloatingMagnetView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + mMoveAnimator = new MoveAnimator(); + mStatusBarHeight = SystemUtils.getStatusBarHeight(getContext()); + setClickable(true); +// updateSize(); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event == null) { + return false; + } + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + changeOriginalTouchParams(event); + updateSize(); + mMoveAnimator.stop(); + break; + case MotionEvent.ACTION_MOVE: + updateViewPosition(event); + break; + case MotionEvent.ACTION_UP: + clearPortraitY(); + moveToEdge(); + if (isOnClickEvent()) { + dealClickEvent(); + } + break; + } + return true; + } + + protected void dealClickEvent() { + if (mMagnetViewListener != null) { + mMagnetViewListener.onClick(this); + } + } + + protected boolean isOnClickEvent() { + return System.currentTimeMillis() - mLastTouchDownTime < TOUCH_TIME_THRESHOLD; + } + + private void updateViewPosition(MotionEvent event) { + setX(mOriginalX + event.getRawX() - mOriginalRawX); + // 限制不可超出屏幕高度 + float desY = mOriginalY + event.getRawY() - mOriginalRawY; + if (desY < mStatusBarHeight) { + desY = mStatusBarHeight; + } + if (desY > mScreenHeight - getHeight()) { + desY = mScreenHeight - getHeight(); + } + setY(desY); + } + + private void changeOriginalTouchParams(MotionEvent event) { + mOriginalX = getX(); + mOriginalY = getY(); + mOriginalRawX = event.getRawX(); + mOriginalRawY = event.getRawY(); + mLastTouchDownTime = System.currentTimeMillis(); + } + + protected void updateSize() { + ViewGroup viewGroup = (ViewGroup) getParent(); + if (viewGroup != null) { + mScreenWidth = viewGroup.getWidth() - getWidth(); + mScreenHeight = viewGroup.getHeight(); + } +// mScreenWidth = (SystemUtils.getScreenWidth(getContext()) - this.getWidth()); +// mScreenHeight = SystemUtils.getScreenHeight(getContext()); + } + + public void moveToEdge() { + moveToEdge(isNearestLeft(), false); + } + + public void moveToEdge(boolean isLeft, boolean isLandscape) { + float moveDistance = isLeft ? MARGIN_EDGE : mScreenWidth - MARGIN_EDGE; + float y = getY(); + if (!isLandscape && mPortraitY != 0) { + y = mPortraitY; + clearPortraitY(); + } + mMoveAnimator.start(moveDistance, Math.min(Math.max(0, y), mScreenHeight - getHeight())); + } + + private void clearPortraitY() { + mPortraitY = 0; + } + + protected boolean isNearestLeft() { + int middle = mScreenWidth / 2; + isNearestLeft = getX() < middle; + return isNearestLeft; + } + + public void onRemove() { + if (mMagnetViewListener != null) { + mMagnetViewListener.onRemove(this); + } + } + + protected class MoveAnimator implements Runnable { + + private Handler handler = new Handler(Looper.getMainLooper()); + private float destinationX; + private float destinationY; + private long startingTime; + + void start(float x, float y) { + this.destinationX = x; + this.destinationY = y; + startingTime = System.currentTimeMillis(); + handler.post(this); + } + + @Override + public void run() { + if (getRootView() == null || getRootView().getParent() == null) { + return; + } + float progress = Math.min(1, (System.currentTimeMillis() - startingTime) / 400f); + float deltaX = (destinationX - getX()) * progress; + float deltaY = (destinationY - getY()) * progress; + move(deltaX, deltaY); + if (progress < 1) { + handler.post(this); + } + } + + private void stop() { + handler.removeCallbacks(this); + } + } + + private void move(float deltaX, float deltaY) { + setX(getX() + deltaX); + setY(getY() + deltaY); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (getParent() != null) { + final boolean isLandscape = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE; + markPortraitY(isLandscape); + ((ViewGroup) getParent()).post(new Runnable() { + @Override + public void run() { + updateSize(); + moveToEdge(isNearestLeft, isLandscape); + } + }); + } + } + + private void markPortraitY(boolean isLandscape) { + if (isLandscape) { + mPortraitY = getY(); + } + } +} diff --git a/app/src/main/java/com/hnjc/wjtx/floatingview/FloatingView.java b/app/src/main/java/com/hnjc/wjtx/floatingview/FloatingView.java new file mode 100644 index 0000000..5758e76 --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/floatingview/FloatingView.java @@ -0,0 +1,196 @@ +package com.hnjc.wjtx.floatingview; + +import android.app.Activity; +import android.os.Handler; +import android.os.Looper; +import android.support.annotation.DrawableRes; +import android.support.annotation.LayoutRes; +import android.support.v4.view.ViewCompat; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.RelativeLayout; + +import com.hnjc.wjtx.R; +import com.hnjc.wjtx.util.EnContext; + +import java.lang.ref.WeakReference; + +public class FloatingView implements IFloatingView { + + private FloatingMagnetView mEnFloatingView; + private static volatile FloatingView mInstance; + private WeakReference mContainer; + @LayoutRes + private int mLayoutId = R.layout.en_floating_view; + @DrawableRes + private int mIconRes = R.drawable.change_acct; + + private ViewGroup.LayoutParams mLayoutParams = getParams(); + + private FloatingView() { + } + + public static FloatingView get() { + if (mInstance == null) { + synchronized (FloatingView.class) { + if (mInstance == null) { + mInstance = new FloatingView(); + } + } + } + return mInstance; + } + + @Override + public FloatingView remove() { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + if (mEnFloatingView == null) { + return; + } + if (ViewCompat.isAttachedToWindow(mEnFloatingView) && getContainer() != null) { + getContainer().removeView(mEnFloatingView); + } + mEnFloatingView = null; + } + }); + return this; + } + + private void ensureFloatingView() { + synchronized (this) { + if (mEnFloatingView != null) { + return; + } + EnFloatingView enFloatingView = new EnFloatingView(EnContext.get(), mLayoutId); + mEnFloatingView = enFloatingView; + enFloatingView.setLayoutParams(mLayoutParams); + enFloatingView.setIconImage(mIconRes); + addViewToWindow(enFloatingView); + } + } + + @Override + public FloatingView add() { + ensureFloatingView(); + return this; + } + + @Override + public FloatingView attach(Activity activity) { + attach(getActivityRoot(activity)); + return this; + } + + @Override + public FloatingView attach(FrameLayout container) { + if (container == null || mEnFloatingView == null) { + mContainer = new WeakReference<>(container); + return this; + } + if (mEnFloatingView.getParent() == container) { + return this; + } + if (mEnFloatingView.getParent() != null) { + ((ViewGroup) mEnFloatingView.getParent()).removeView(mEnFloatingView); + } + mContainer = new WeakReference<>(container); + container.addView(mEnFloatingView); + return this; + } + + @Override + public FloatingView detach(Activity activity) { + detach(getActivityRoot(activity)); + return this; + } + + @Override + public FloatingView detach(FrameLayout container) { + if (mEnFloatingView != null && container != null && ViewCompat.isAttachedToWindow(mEnFloatingView)) { + container.removeView(mEnFloatingView); + } + if (getContainer() == container) { + mContainer = null; + } + return this; + } + + @Override + public FloatingMagnetView getView() { + return mEnFloatingView; + } + + @Override + public FloatingView icon(@DrawableRes int resId) { + mIconRes = resId; + return this; + } + + @Override + public FloatingView customView(FloatingMagnetView viewGroup) { + mEnFloatingView = viewGroup; + return this; + } + + @Override + public FloatingView customView(@LayoutRes int resource) { + mLayoutId = resource; + return this; + } + + @Override + public FloatingView layoutParams(ViewGroup.LayoutParams params) { + mLayoutParams = params; + if (mEnFloatingView != null) { + mEnFloatingView.setLayoutParams(params); + } + return this; + } + + @Override + public FloatingView listener(MagnetViewListener magnetViewListener) { + if (mEnFloatingView != null) { + mEnFloatingView.setMagnetViewListener(magnetViewListener); + } + return this; + } + + private void addViewToWindow(final View view) { + if (getContainer() == null) { + return; + } + getContainer().addView(view); + } + + private FrameLayout getContainer() { + if (mContainer == null) { + return null; + } + return mContainer.get(); + } + + private FrameLayout.LayoutParams getParams() { + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, + RelativeLayout.LayoutParams.WRAP_CONTENT); + params.gravity = Gravity.BOTTOM | Gravity.START; + params.setMargins(13, params.topMargin, params.rightMargin, 500); + return params; + } + + private FrameLayout getActivityRoot(Activity activity) { + if (activity == null) { + return null; + } + try { + return (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/app/src/main/java/com/hnjc/wjtx/floatingview/IFloatingView.java b/app/src/main/java/com/hnjc/wjtx/floatingview/IFloatingView.java new file mode 100644 index 0000000..642d327 --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/floatingview/IFloatingView.java @@ -0,0 +1,35 @@ +package com.hnjc.wjtx.floatingview; + +import android.app.Activity; +import android.support.annotation.DrawableRes; +import android.support.annotation.LayoutRes; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +public interface IFloatingView { + + FloatingView remove(); + + FloatingView add(); + + FloatingView attach(Activity activity); + + FloatingView attach(FrameLayout container); + + FloatingView detach(Activity activity); + + FloatingView detach(FrameLayout container); + + FloatingMagnetView getView(); + + FloatingView icon(@DrawableRes int resId); + + FloatingView customView(FloatingMagnetView viewGroup); + + FloatingView customView(@LayoutRes int resource); + + FloatingView layoutParams(ViewGroup.LayoutParams params); + + FloatingView listener(MagnetViewListener magnetViewListener); + +} diff --git a/app/src/main/java/com/hnjc/wjtx/floatingview/MagnetViewListener.java b/app/src/main/java/com/hnjc/wjtx/floatingview/MagnetViewListener.java new file mode 100644 index 0000000..a783aa9 --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/floatingview/MagnetViewListener.java @@ -0,0 +1,8 @@ +package com.hnjc.wjtx.floatingview; + +public interface MagnetViewListener { + + void onRemove(FloatingMagnetView magnetView); + + void onClick(FloatingMagnetView magnetView); +} diff --git a/app/src/main/java/com/hnjc/wjtx/util/EnContext.java b/app/src/main/java/com/hnjc/wjtx/util/EnContext.java new file mode 100644 index 0000000..b7234b2 --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/util/EnContext.java @@ -0,0 +1,31 @@ +package com.hnjc.wjtx.util; + +import android.app.Application; + +public class EnContext { + + private static final Application INSTANCE; + + static { + Application app = null; + try { + app = (Application) Class.forName("android.app.AppGlobals").getMethod("getInitialApplication").invoke(null); + if (app == null) + throw new IllegalStateException("Static initialization of Applications must be on main thread."); + } catch (final Exception e) { + e.printStackTrace(); + try { + app = (Application) Class.forName("android.app.ActivityThread").getMethod("currentApplication").invoke(null); + } catch (final Exception ex) { + e.printStackTrace(); + } + } finally { + INSTANCE = app; + } + } + + public static Application get() { + return INSTANCE; + } +} + diff --git a/app/src/main/java/com/hnjc/wjtx/util/SystemUtils.java b/app/src/main/java/com/hnjc/wjtx/util/SystemUtils.java new file mode 100644 index 0000000..c7b68bf --- /dev/null +++ b/app/src/main/java/com/hnjc/wjtx/util/SystemUtils.java @@ -0,0 +1,36 @@ +package com.hnjc.wjtx.util; + +import android.content.Context; + +public class SystemUtils { + + public static int getStatusBarHeight(Context context) { + int result = 0; + int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = context.getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + public static int getScreenWidth(Context context) { + int screenWith = -1; + try { + screenWith = context.getResources().getDisplayMetrics().widthPixels; + } catch (Exception e) { + e.printStackTrace(); + } + return screenWith; + } + + public static int getScreenHeight(Context context) { + int screenHeight = -1; + try { + screenHeight = context.getResources().getDisplayMetrics().heightPixels; + } catch (Exception e) { + e.printStackTrace(); + } + return screenHeight; + } + +} diff --git a/app/src/main/res/drawable/change_acct.png b/app/src/main/res/drawable/change_acct.png new file mode 100644 index 0000000..f16309d Binary files /dev/null and b/app/src/main/res/drawable/change_acct.png differ diff --git a/app/src/main/res/drawable/icon.png b/app/src/main/res/drawable/icon.png index 5307d52..5c5a49b 100644 Binary files a/app/src/main/res/drawable/icon.png and b/app/src/main/res/drawable/icon.png differ diff --git a/app/src/main/res/layout/en_floating_view.xml b/app/src/main/res/layout/en_floating_view.xml new file mode 100644 index 0000000..144c297 --- /dev/null +++ b/app/src/main/res/layout/en_floating_view.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file