diff --git a/layer-core/src/main/java/per/goweii/layer/core/FrameLayer.java b/layer-core/src/main/java/per/goweii/layer/core/FrameLayer.java index f5a6a64..6649995 100644 --- a/layer-core/src/main/java/per/goweii/layer/core/FrameLayer.java +++ b/layer-core/src/main/java/per/goweii/layer/core/FrameLayer.java @@ -164,9 +164,9 @@ public FrameLayer setCancelableOnClickKeyBack(boolean cancelable) { @NonNull private ViewGroup installParent() { - LayerRootLayout layerRootLayout = findLayerLayoutFromRoot(); - if (layerRootLayout == null) layerRootLayout = tryGetLayerLayoutFormHolder(); - if (layerRootLayout == null) layerRootLayout = createLayerLayout(); + LayerRootLayout layerRootLayout = findLayerRootLayoutFromRoot(); + if (layerRootLayout == null) layerRootLayout = tryGetLayerRootLayoutFormHolder(); + if (layerRootLayout == null) layerRootLayout = createLayerRootLayout(); if (layerRootLayout.getParent() == null) { getViewHolder().getRoot().addView(layerRootLayout); } else if (layerRootLayout.getParent() != getViewHolder().getRoot()) { @@ -174,9 +174,9 @@ private ViewGroup installParent() { getViewHolder().getRoot().addView(layerRootLayout); } layerRootLayout.registerOnConfigurationChangedListener(mOnConfigurationChangedListener); - LayerLevelLayout layerLevelLayout = findLevelLayoutFromLayerLayout(layerRootLayout); - if (layerLevelLayout == null) layerLevelLayout = tryGetLevelLayoutFormHolder(); - if (layerLevelLayout == null) layerLevelLayout = createLevelLayout(); + LayerLevelLayout layerLevelLayout = findLayerLevelLayoutFromLayerLayout(layerRootLayout); + if (layerLevelLayout == null) layerLevelLayout = tryGetLayerLevelLayoutFormHolder(); + if (layerLevelLayout == null) layerLevelLayout = createLayerLevelLayout(); if (layerLevelLayout.getParent() == null) { layerRootLayout.addView(layerLevelLayout); } else if (layerLevelLayout.getParent() != layerRootLayout) { @@ -187,10 +187,10 @@ private ViewGroup installParent() { } private void uninstallParent() { - final LayerRootLayout layerRootLayout = findLayerLayoutFromRoot(); + final LayerRootLayout layerRootLayout = findLayerRootLayoutFromRoot(); if (layerRootLayout == null) return; layerRootLayout.unregisterOnConfigurationChangedListener(mOnConfigurationChangedListener); - final LayerLevelLayout layerLevelLayout = findLevelLayoutFromLayerLayout(layerRootLayout); + final LayerLevelLayout layerLevelLayout = findLayerLevelLayoutFromLayerLayout(layerRootLayout); if (layerLevelLayout == null) return; if (layerLevelLayout.getChildCount() == 0) { layerRootLayout.removeView(layerLevelLayout); @@ -204,7 +204,7 @@ private void ensureLayerLayoutIsFront() { final ViewGroup root = getViewHolder().getRoot(); int count = root.getChildCount(); if (count <= 1) return; - LayerRootLayout layerRootLayout = findLayerLayoutFromRoot(); + LayerRootLayout layerRootLayout = findLayerRootLayoutFromRoot(); if (layerRootLayout == null) return; int index = root.indexOfChild(layerRootLayout); if (index < 0) return; @@ -213,7 +213,7 @@ private void ensureLayerLayoutIsFront() { } @Nullable - private LayerRootLayout findLayerLayoutFromRoot() { + protected LayerRootLayout findLayerRootLayoutFromRoot() { final ViewGroup root = getViewHolder().getRoot(); LayerRootLayout layerRootLayout = null; final int count = root.getChildCount(); @@ -233,7 +233,7 @@ private LayerRootLayout findLayerLayoutFromRoot() { } @Nullable - private LayerRootLayout tryGetLayerLayoutFormHolder() { + private LayerRootLayout tryGetLayerRootLayoutFormHolder() { if (getViewHolder().getLayerRootLayout() == null) return null; LayerRootLayout layerRootLayout = getViewHolder().getLayerRootLayout(); Utils.removeViewParent(layerRootLayout); @@ -241,7 +241,7 @@ private LayerRootLayout tryGetLayerLayoutFormHolder() { } @NonNull - private LayerRootLayout createLayerLayout() { + private LayerRootLayout createLayerRootLayout() { final ViewGroup root = getViewHolder().getRoot(); LayerRootLayout layerRootLayout = new LayerRootLayout(root.getContext()); layerRootLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); @@ -250,7 +250,7 @@ private LayerRootLayout createLayerLayout() { } @Nullable - private LayerLevelLayout findLevelLayoutFromLayerLayout(LayerRootLayout group) { + protected LayerLevelLayout findLayerLevelLayoutFromLayerLayout(@NonNull LayerRootLayout group) { LayerLevelLayout layerLevelLayout = group.findLevelLayout(getRealLevel()); if (layerLevelLayout != null) { if (layerLevelLayout != getViewHolder().getLayerLevelLayout()) { @@ -261,7 +261,7 @@ private LayerLevelLayout findLevelLayoutFromLayerLayout(LayerRootLayout group) { } @Nullable - private LayerLevelLayout tryGetLevelLayoutFormHolder() { + private LayerLevelLayout tryGetLayerLevelLayoutFormHolder() { if (getViewHolder().getLayerLevelLayout() == null) { return null; } @@ -278,7 +278,7 @@ private LayerLevelLayout tryGetLevelLayoutFormHolder() { } @NonNull - private LayerLevelLayout createLevelLayout() { + private LayerLevelLayout createLayerLevelLayout() { final ViewGroup root = getViewHolder().getRoot(); LayerLevelLayout layerLevelLayout = new LayerLevelLayout(root.getContext(), getRealLevel()); layerLevelLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); diff --git a/layer-core/src/main/java/per/goweii/layer/core/Layer.java b/layer-core/src/main/java/per/goweii/layer/core/Layer.java index 74953cb..ca93837 100644 --- a/layer-core/src/main/java/per/goweii/layer/core/Layer.java +++ b/layer-core/src/main/java/per/goweii/layer/core/Layer.java @@ -268,7 +268,7 @@ protected boolean onGlobalPreDraw() { return true; } - private void handleShow() { + protected void handleShow() { if (isShown()) { if (isOutAnimRunning()) { startAnimatorIn(); @@ -327,7 +327,7 @@ private void handleInAnimEnd() { onPostShow(); } - private void handleDismiss() { + protected void handleDismiss() { if (!isShown()) return; if (isOutAnimRunning()) return; if (mShowOnPreDrawListener != null) { diff --git a/layer-core/src/main/java/per/goweii/layer/core/widget/SwipeLayout.java b/layer-core/src/main/java/per/goweii/layer/core/widget/SwipeLayout.java index 112929f..66693c1 100644 --- a/layer-core/src/main/java/per/goweii/layer/core/widget/SwipeLayout.java +++ b/layer-core/src/main/java/per/goweii/layer/core/widget/SwipeLayout.java @@ -32,7 +32,7 @@ @SuppressWarnings("NullableProblems") public class SwipeLayout extends FrameLayout implements NestedScrollingParent3 { - @IntDef({Direction.NONE, Direction.LEFT, Direction.TOP, Direction.RIGHT, Direction.BOTTOM}) + @IntDef(value = {Direction.NONE, Direction.LEFT, Direction.TOP, Direction.RIGHT, Direction.BOTTOM}, flag = true) @Retention(RetentionPolicy.SOURCE) public @interface Direction { int NONE = 0; diff --git a/layer-notification-ktx/src/main/java/per/goweii/layer/notification/ktx/NotificationLayer.kt b/layer-notification-ktx/src/main/java/per/goweii/layer/notification/ktx/NotificationLayer.kt index ac7d129..c87dee5 100644 --- a/layer-notification-ktx/src/main/java/per/goweii/layer/notification/ktx/NotificationLayer.kt +++ b/layer-notification-ktx/src/main/java/per/goweii/layer/notification/ktx/NotificationLayer.kt @@ -6,6 +6,7 @@ import androidx.annotation.LayoutRes import per.goweii.layer.core.widget.SwipeLayout import per.goweii.layer.notification.DefaultNotificationOnSwipeListener import per.goweii.layer.notification.NotificationLayer +import per.goweii.layer.notification.NotificationLayer.SwipeTransformer fun T.contentView(contentView: View) = this.apply { this.setContentView(contentView) @@ -23,6 +24,18 @@ fun T.maxHeight(maxHeight: Int) = this.apply { this.setMaxHeight(maxHeight) } +fun T.removeOthers(removeOthers: Boolean) = this.apply { + this.setRemoveOthers(removeOthers) +} + +fun T.swipeDirection(@SwipeLayout.Direction direction: Int) = this.apply { + this.setSwipeDirection(direction) +} + +fun T.swipeTransformer(swipeTransformer: SwipeTransformer) = this.apply { + this.setSwipeTransformer(swipeTransformer) +} + fun T.duration(duration: Long) = this.apply { this.setDuration(duration) } diff --git a/layer-notification/src/main/java/per/goweii/layer/notification/NotificationLayer.java b/layer-notification/src/main/java/per/goweii/layer/notification/NotificationLayer.java index 27f5448..938ce5f 100644 --- a/layer-notification/src/main/java/per/goweii/layer/notification/NotificationLayer.java +++ b/layer-notification/src/main/java/per/goweii/layer/notification/NotificationLayer.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.graphics.Rect; +import android.os.SystemClock; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -22,13 +23,16 @@ import java.util.List; import per.goweii.layer.core.DecorLayer; +import per.goweii.layer.core.Layer; import per.goweii.layer.core.anim.AnimatorHelper; import per.goweii.layer.core.utils.Utils; import per.goweii.layer.core.widget.MaxSizeFrameLayout; import per.goweii.layer.core.widget.SwipeLayout; public class NotificationLayer extends DecorLayer { + private static long sShowAfterTime = 0L; + private long mShowTime = 0L; private Runnable mDismissRunnable = null; private boolean mSwiping = false; @@ -82,11 +86,34 @@ public ListenerHolder getListenerHolder() { return (ListenerHolder) super.getListenerHolder(); } + @Override + public void show(final boolean withAnim) { + mShowTime = SystemClock.elapsedRealtimeNanos(); + if (getConfig().mRemoveOthers) { + sShowAfterTime = mShowTime; + removeAndWaitOthersDismissed(new Runnable() { + @Override + public void run() { + NotificationLayer.super.show(withAnim); + } + }); + } else { + NotificationLayer.super.show(withAnim); + } + } + + @Override + protected void handleShow() { + if (sShowAfterTime <= mShowTime) { + super.handleShow(); + } + } + @CallSuper @Override protected void onAttach() { super.onAttach(); - getViewHolder().getChild().setSwipeDirection(SwipeLayout.Direction.TOP | SwipeLayout.Direction.LEFT | SwipeLayout.Direction.RIGHT); + getViewHolder().getChild().setSwipeDirection(getConfig().mSwipeDirection); getViewHolder().getChild().setOnSwipeListener(new SwipeLayout.OnSwipeListener() { @Override public void onStart(@SwipeLayout.Direction int direction, @FloatRange(from = 0F, to = 1F) float fraction) { @@ -164,6 +191,11 @@ protected void onPreDismiss() { super.onPreDismiss(); } + @Override + protected void onDetach() { + super.onDetach(); + } + @NonNull @Override protected View onCreateChild(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) { @@ -305,12 +337,24 @@ public void run() { } } + @NonNull + public NotificationLayer setRemoveOthers(boolean removeOthers) { + getConfig().mRemoveOthers = removeOthers; + return this; + } + @NonNull public NotificationLayer setDuration(long duration) { getConfig().mDuration = duration; return this; } + @NonNull + public NotificationLayer setSwipeDirection(@SwipeLayout.Direction int swipeDirection) { + getConfig().mSwipeDirection = swipeDirection; + return this; + } + @NonNull public NotificationLayer setSwipeTransformer(@Nullable SwipeTransformer swipeTransformer) { getConfig().mSwipeTransformer = swipeTransformer; @@ -328,6 +372,48 @@ public NotificationLayer addOnSwipeListener(@NonNull OnSwipeListener swipeListen return this; } + private void removeAndWaitOthersDismissed(@NonNull final Runnable onDismissed) { + final LayerRootLayout layerRootLayout = findLayerRootLayoutFromRoot(); + if (layerRootLayout == null) { + onDismissed.run(); + return; + } + final LayerLevelLayout layerLevelLayout = findLayerLevelLayoutFromLayerLayout(layerRootLayout); + if (layerLevelLayout == null) { + onDismissed.run(); + return; + } + final List shownLayers = new ArrayList<>(); + final List layers = layerLevelLayout.getLayers(); + for (Layer layer : layers) { + if (layer.isShown()) { + shownLayers.add(layer); + } else { + layer.dismiss(false); + } + } + if (shownLayers.isEmpty()) { + onDismissed.run(); + return; + } + for (final Layer layer : shownLayers) { + layer.addOnDismissListener(new OnDismissListener() { + @Override + public void onPreDismiss(@NonNull Layer layer) { + } + + @Override + public void onPostDismiss(@NonNull Layer layer) { + shownLayers.remove(layer); + if (shownLayers.isEmpty()) { + onDismissed.run(); + } + } + }); + layer.dismiss(); + } + } + public static class ViewHolder extends DecorLayer.ViewHolder { private MaxSizeFrameLayout mContentWrapper; private View mContent; @@ -368,10 +454,13 @@ protected static class Config extends DecorLayer.Config { protected View mContentView = null; protected int mContentViewId = -1; + protected boolean mRemoveOthers = true; protected long mDuration = 5000L; protected int mMaxWidth = -1; protected int mMaxHeight = -1; + @SwipeLayout.Direction + protected int mSwipeDirection = SwipeLayout.Direction.TOP | SwipeLayout.Direction.LEFT | SwipeLayout.Direction.RIGHT; @Nullable protected SwipeTransformer mSwipeTransformer = null; }