├── layer-core
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ └── values
│ │ │ ├── ids.xml
│ │ │ ├── attrs.xml
│ │ │ └── styles.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── core
│ │ ├── listener
│ │ ├── DefaultOnShowListener.java
│ │ ├── DefaultOnDismissListener.java
│ │ ├── DefaultOnVisibleChangedListener.java
│ │ ├── DefaultAnimatorListener.java
│ │ └── WindowCallbackDelegate.java
│ │ ├── anim
│ │ ├── NullAnimatorCreator.java
│ │ ├── CircularRevealAnimatorCreator.java
│ │ └── AnimStyle.java
│ │ ├── Layers.java
│ │ ├── widget
│ │ ├── LayerContainer.java
│ │ └── MaxSizeFrameLayout.java
│ │ ├── utils
│ │ └── ScrollCompat.java
│ │ └── ActivityHolder.java
└── build.gradle
├── layer-guide
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── guide
│ │ └── HoleView.java
└── build.gradle
├── layer-popup
├── .gitignore
├── src
│ └── main
│ │ └── AndroidManifest.xml
└── build.gradle
├── layer-toast
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ └── values
│ │ └── ids.xml
└── build.gradle
├── layer-core-ktx
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── core
│ │ └── ktx
│ │ ├── FrameLayer.kt
│ │ └── Layer.kt
└── build.gradle
├── layer-design-res
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ ├── values-night
│ │ └── colors.xml
│ │ └── values
│ │ ├── colors.xml
│ │ └── dimens.xml
└── build.gradle
├── layer-dialog-ktx
├── .gitignore
├── src
│ └── main
│ │ └── AndroidManifest.xml
└── build.gradle
├── layer-dialog
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── java
│ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── dialog
│ │ ├── DefaultDialogOnSwipeListener.java
│ │ ├── DialogLayerActivity.java
│ │ └── ContainerLayout.java
│ └── AndroidManifest.xml
├── layer-guide-ktx
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── guide
│ │ └── ktx
│ │ └── GuideLayer.kt
└── build.gradle
├── layer-keyboard
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── raw
│ │ │ └── layer_keyboard_click.mp3
│ │ ├── drawable-hdpi
│ │ │ ├── layer_keyboard_ic_del.png
│ │ │ ├── layer_keyboard_ic_caps.png
│ │ │ ├── layer_keyboard_ic_enter.png
│ │ │ ├── layer_keyboard_ic_space.png
│ │ │ ├── layer_keyboard_ic_arrow_down.png
│ │ │ └── layer_keyboard_ic_caps_lock.png
│ │ ├── drawable-mdpi
│ │ │ ├── layer_keyboard_ic_del.png
│ │ │ ├── layer_keyboard_ic_caps.png
│ │ │ ├── layer_keyboard_ic_enter.png
│ │ │ ├── layer_keyboard_ic_space.png
│ │ │ ├── layer_keyboard_ic_arrow_down.png
│ │ │ └── layer_keyboard_ic_caps_lock.png
│ │ ├── drawable-xhdpi
│ │ │ ├── layer_keyboard_ic_caps.png
│ │ │ ├── layer_keyboard_ic_del.png
│ │ │ ├── layer_keyboard_ic_enter.png
│ │ │ ├── layer_keyboard_ic_space.png
│ │ │ ├── layer_keyboard_ic_arrow_down.png
│ │ │ └── layer_keyboard_ic_caps_lock.png
│ │ ├── drawable-xxhdpi
│ │ │ ├── layer_keyboard_ic_caps.png
│ │ │ ├── layer_keyboard_ic_del.png
│ │ │ ├── layer_keyboard_ic_enter.png
│ │ │ ├── layer_keyboard_ic_space.png
│ │ │ ├── layer_keyboard_ic_caps_lock.png
│ │ │ └── layer_keyboard_ic_arrow_down.png
│ │ ├── values
│ │ │ ├── dimens.xml
│ │ │ ├── colors.xml
│ │ │ └── styles.xml
│ │ ├── drawable
│ │ │ ├── layer_keyboard_ic_caps_selector.xml
│ │ │ ├── layer_keyboard_btn_bg_selector.xml
│ │ │ ├── layer_keyboard_btn_bg_normal.xml
│ │ │ └── layer_keyboard_btn_bg_pressed.xml
│ │ ├── drawable-anydpi
│ │ │ ├── layer_keyboard_ic_space.xml
│ │ │ ├── layer_keyboard_ic_caps.xml
│ │ │ ├── layer_keyboard_ic_arrow_down.xml
│ │ │ ├── layer_keyboard_ic_enter.xml
│ │ │ ├── layer_keyboard_ic_caps_lock.xml
│ │ │ └── layer_keyboard_ic_del.xml
│ │ ├── values-night
│ │ │ └── colors.xml
│ │ └── layout
│ │ │ └── layer_keyboard.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── keyboard
│ │ ├── BindingActionListener.java
│ │ ├── KeyboardVibratorEffect.java
│ │ ├── KeyboardSoundEffect.java
│ │ ├── DefaultBindingActionListener.java
│ │ ├── KeyAction.java
│ │ └── KeyboardGesture.java
└── build.gradle
├── layer-overlay
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ └── values
│ │ └── ids.xml
└── build.gradle
├── layer-popup-ktx
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── popup
│ │ └── ktx
│ │ └── PopupLayer.kt
└── build.gradle
├── layer-startup
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── per
│ └── goweii
│ └── layer
│ └── startup
│ └── LayerInitializer.java
├── layer-toast-ktx
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── toast
│ │ └── ktx
│ │ └── ToastLayer.kt
└── build.gradle
├── layer-design-material
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ ├── values
│ │ │ ├── colors.xml
│ │ │ └── dimens.xml
│ │ ├── values-night
│ │ │ └── colors.xml
│ │ ├── drawable
│ │ │ ├── layer_design_material_dialog_actions_gap.xml
│ │ │ ├── layer_design_material_dialog_btn_bg_normal.xml
│ │ │ ├── layer_design_material_dialog_btn_bg_pressed.xml
│ │ │ ├── layer_design_material_dialog_btn_bg.xml
│ │ │ └── layer_design_material_toast_bg.xml
│ │ ├── drawable-v21
│ │ │ └── layer_design_material_dialog_btn_bg.xml
│ │ └── layout
│ │ │ ├── layer_design_material_dialog_action.xml
│ │ │ ├── layer_design_material_toast.xml
│ │ │ └── layer_design_material_dialog.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── design
│ │ └── material
│ │ └── MaterialPopupLayer.java
└── build.gradle
├── layer-keyboard-ktx
├── .gitignore
├── src
│ └── main
│ │ └── AndroidManifest.xml
└── build.gradle
├── layer-notification
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── notification
│ │ └── DefaultNotificationOnSwipeListener.java
└── build.gradle
├── layer-overlay-ktx
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── overlay
│ │ └── ktx
│ │ └── OverlayLayer.kt
└── build.gradle
├── layer-design-cupertino
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── res
│ │ ├── values
│ │ ├── ids.xml
│ │ ├── colors.xml
│ │ └── dimens.xml
│ │ ├── drawable
│ │ ├── layer_design_cupertino_divider_h.xml
│ │ ├── layer_design_cupertino_divider_v.xml
│ │ ├── layer_design_cupertino_alert_bg.xml
│ │ └── layer_design_cupertino_toast_bg.xml
│ │ ├── values-night
│ │ └── colors.xml
│ │ └── layout
│ │ ├── layer_design_cupertino_alert_action.xml
│ │ ├── layer_design_cupertino_toast.xml
│ │ ├── layer_design_cupertino_alert.xml
│ │ └── layer_design_cupertino_notification.xml
└── build.gradle
├── layer-notification-ktx
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── notification
│ │ └── ktx
│ │ └── NotificationLayer.kt
└── build.gradle
├── layer-visualeffectview
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ └── values
│ │ │ └── attrs.xml
│ │ └── java
│ │ └── per
│ │ └── goweii
│ │ └── layer
│ │ └── visualeffectview
│ │ ├── BackdropIgnoreView.java
│ │ └── BackdropBlurView.java
└── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── simple
├── release
│ ├── per.goweii.layer.simple.apk
│ └── output-metadata.json
├── src
│ └── main
│ │ ├── ic_launcher-playstore.png
│ │ ├── res
│ │ ├── drawable-xxhdpi
│ │ │ ├── ic_back.png
│ │ │ ├── ic_fail.png
│ │ │ ├── ic_more.png
│ │ │ ├── ic_success.png
│ │ │ ├── ic_warning.png
│ │ │ ├── ic_fail_big.png
│ │ │ ├── ic_notification.png
│ │ │ ├── ic_success_big.png
│ │ │ └── ic_warning_big.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ ├── drawable-night-xxhdpi
│ │ │ ├── ic_back.png
│ │ │ ├── ic_fail.png
│ │ │ ├── ic_more.png
│ │ │ ├── ic_success.png
│ │ │ └── ic_warning.png
│ │ ├── drawable
│ │ │ ├── shape_divider_h.xml
│ │ │ ├── popup_bg.xml
│ │ │ ├── shape_send_bg.xml
│ │ │ ├── shape_input_bg.xml
│ │ │ └── shape_dialog_fullscreen_bg.xml
│ │ ├── layout
│ │ │ ├── guide_i_know.xml
│ │ │ ├── overlay.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── guide_content.xml
│ │ │ ├── dialog_fullscreen.xml
│ │ │ ├── activity_material_simple.xml
│ │ │ ├── toast.xml
│ │ │ ├── dialog_input.xml
│ │ │ ├── activity_cupertino_simple.xml
│ │ │ ├── layout_list_20.xml
│ │ │ ├── activity_layers_simple.xml
│ │ │ ├── popup_meun.xml
│ │ │ ├── dialog_normal.xml
│ │ │ └── bottom_sheet.xml
│ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-night
│ │ │ └── colors.xml
│ │ ├── java
│ │ └── per
│ │ │ └── goweii
│ │ │ └── layer
│ │ │ └── simple
│ │ │ ├── App.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MaterialSimpleActivity.kt
│ │ │ └── CupertinoSimpleActivity.kt
│ │ └── AndroidManifest.xml
├── proguard-rules.pro
└── build.gradle
├── maven-upload.gradle
├── settings.gradle
├── library.gradle
├── gradle.properties
├── .github
└── FUNDING.yml
├── .gitignore
├── gradlew.bat
└── README.md
/layer-core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-guide/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-popup/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-toast/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-core-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-design-res/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-dialog-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-dialog/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-guide-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-keyboard/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-overlay/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-popup-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-startup/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-toast-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-design-material/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-keyboard-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-notification/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-overlay-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-design-cupertino/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-notification-ktx/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/layer-visualeffectview/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/simple/release/per.goweii.layer.simple.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/release/per.goweii.layer.simple.apk
--------------------------------------------------------------------------------
/simple/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/layer-core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_back.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_fail.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_more.png
--------------------------------------------------------------------------------
/layer-guide/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-popup/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-toast/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_success.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_warning.png
--------------------------------------------------------------------------------
/simple/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/layer-core-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-core/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-overlay/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_fail_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_fail_big.png
--------------------------------------------------------------------------------
/layer-core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | }
9 |
--------------------------------------------------------------------------------
/layer-design-res/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-dialog-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-guide-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-popup-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-toast-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-night-xxhdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-night-xxhdpi/ic_back.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-night-xxhdpi/ic_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-night-xxhdpi/ic_fail.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-night-xxhdpi/ic_more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-night-xxhdpi/ic_more.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_notification.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_success_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_success_big.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-xxhdpi/ic_warning_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-xxhdpi/ic_warning_big.png
--------------------------------------------------------------------------------
/simple/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/layer-design-res/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | }
9 |
--------------------------------------------------------------------------------
/layer-keyboard-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/raw/layer_keyboard_click.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/raw/layer_keyboard_click.mp3
--------------------------------------------------------------------------------
/layer-notification/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-overlay-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-toast/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-night-xxhdpi/ic_success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-night-xxhdpi/ic_success.png
--------------------------------------------------------------------------------
/simple/src/main/res/drawable-night-xxhdpi/ic_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/drawable-night-xxhdpi/ic_warning.png
--------------------------------------------------------------------------------
/layer-design-material/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/simple/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/simple/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-notification-ktx/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-overlay/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-visualeffectview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_del.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_del.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_caps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_caps.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_enter.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_space.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_caps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_caps.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_enter.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_space.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_caps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_caps.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_del.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_enter.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_space.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_caps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_caps.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_del.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_enter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_enter.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_space.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_arrow_down.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_caps_lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-hdpi/layer_keyboard_ic_caps_lock.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_arrow_down.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_caps_lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-mdpi/layer_keyboard_ic_caps_lock.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_arrow_down.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_caps_lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xhdpi/layer_keyboard_ic_caps_lock.png
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_caps_lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_caps_lock.png
--------------------------------------------------------------------------------
/layer-dialog/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core")
9 | }
10 |
--------------------------------------------------------------------------------
/layer-guide/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core")
9 | }
10 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/goweii/Layer/HEAD/layer-keyboard/src/main/res/drawable-xxhdpi/layer_keyboard_ic_arrow_down.png
--------------------------------------------------------------------------------
/layer-overlay/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core")
9 | }
10 |
--------------------------------------------------------------------------------
/layer-popup/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-dialog")
9 | }
10 |
--------------------------------------------------------------------------------
/layer-toast/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core")
9 | }
10 |
--------------------------------------------------------------------------------
/layer-keyboard/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-dialog")
9 | }
10 |
--------------------------------------------------------------------------------
/layer-notification/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core")
9 | }
10 |
--------------------------------------------------------------------------------
/simple/src/main/java/per/goweii/layer/simple/App.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.simple
2 |
3 | import android.app.Application
4 |
5 | class App : Application() {
6 | override fun onCreate() {
7 | super.onCreate()
8 | }
9 | }
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8dp
4 | 6dp
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable/shape_divider_h.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable/popup_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-startup/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | implementation project(":layer-core")
9 | compileOnly "androidx.startup:startup-runtime:$androidx_startup_version"
10 | }
11 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable/shape_send_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable/shape_input_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-core-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core")
9 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
10 | compileOnly "androidx.core:core-ktx:1.6.0"
11 | }
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @color/layer_design_res_color_surface
4 |
5 | #14000000
6 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @color/layer_design_res_color_surface
4 |
5 | #14ffffff
6 |
--------------------------------------------------------------------------------
/layer-core/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/drawable/layer_design_cupertino_divider_h.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/drawable/layer_design_cupertino_divider_v.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/drawable/layer_design_material_dialog_actions_gap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable/layer_keyboard_ic_caps_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/drawable/layer_design_material_dialog_btn_bg_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-dialog-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core-ktx")
9 | api project(":layer-dialog")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-guide-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core-ktx")
9 | api project(":layer-guide")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable/layer_keyboard_btn_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-popup-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-dialog-ktx")
9 | api project(":layer-popup")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-toast-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core-ktx")
9 | api project(":layer-toast")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/drawable/layer_design_material_dialog_btn_bg_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-overlay-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core-ktx")
9 | api project(":layer-overlay")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-keyboard-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-dialog-ktx")
9 | api project(":layer-keyboard")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable/layer_keyboard_btn_bg_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable/layer_keyboard_btn_bg_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/layer-notification-ktx/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../library.gradle"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-core-ktx")
9 | api project(":layer-notification")
10 | compileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
11 | compileOnly "androidx.core:core-ktx:$androidx_core_ktx_version"
12 | }
--------------------------------------------------------------------------------
/layer-core-ktx/src/main/java/per/goweii/layer/core/ktx/FrameLayer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.ktx
2 |
3 | import per.goweii.layer.core.FrameLayer
4 |
5 | fun T.level(level: Int) = this.apply {
6 | this.setLevel(level)
7 | }
8 |
9 | fun T.cancelableOnClickKeyBack(enable: Boolean) = this.apply {
10 | this.setCancelableOnClickKeyBack(enable)
11 | }
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/drawable/layer_design_material_dialog_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/drawable-v21/layer_design_material_dialog_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
--------------------------------------------------------------------------------
/layer-visualeffectview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api "com.github.goweii.VisualEffect:visualeffect-core:$visual_effect_version"
9 | api "com.github.goweii.VisualEffect:visualeffect-blur:$visual_effect_version"
10 | api "com.github.goweii.VisualEffect:visualeffect-view:$visual_effect_version"
11 | }
12 |
--------------------------------------------------------------------------------
/maven-upload.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "maven"
2 |
3 | group layer_group
4 | version layer_version
5 |
6 | uploadArchives {
7 | repositories {
8 | mavenDeployer {
9 | snapshotRepository(url: uri("/Users/cuizhen/StudioProjects/maven-repository/snapshots"))
10 | repository(url: uri("/Users/cuizhen/StudioProjects/maven-repository/releases"))
11 | pom.packaging = "aar"
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #B3FFFFFF
4 | #B3FFFFFF
5 | #D9FFFFFF
6 | #14000000
7 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #B31E1E1E
4 | #B31E1E1E
5 | #F2333333
6 | #14000000
7 |
--------------------------------------------------------------------------------
/simple/release/output-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "artifactType": {
4 | "type": "APK",
5 | "kind": "Directory"
6 | },
7 | "applicationId": "per.goweii.layer.simple",
8 | "variantName": "processReleaseResources",
9 | "elements": [
10 | {
11 | "type": "SINGLE",
12 | "filters": [],
13 | "versionCode": 1,
14 | "versionName": "1.0.0",
15 | "outputFile": "per.goweii.layer.simple.apk"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/listener/DefaultOnShowListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.listener;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import per.goweii.layer.core.Layer;
6 |
7 | public class DefaultOnShowListener implements Layer.OnShowListener {
8 | @Override
9 | public void onPreShow(@NonNull Layer layer) {
10 | }
11 |
12 | @Override
13 | public void onPostShow(@NonNull Layer layer) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/listener/DefaultOnDismissListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.listener;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import per.goweii.layer.core.Layer;
6 |
7 | public class DefaultOnDismissListener implements Layer.OnDismissListener {
8 | @Override
9 | public void onPreDismiss(@NonNull Layer layer) {
10 | }
11 |
12 | @Override
13 | public void onPostDismiss(@NonNull Layer layer) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/simple/src/main/res/drawable/shape_dialog_fullscreen_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/listener/DefaultOnVisibleChangedListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.listener;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | import per.goweii.layer.core.Layer;
6 |
7 | public class DefaultOnVisibleChangedListener implements Layer.OnVisibleChangedListener {
8 | @Override
9 | public void onShow(@NonNull Layer layer) {
10 | }
11 |
12 | @Override
13 | public void onDismiss(@NonNull Layer layer) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/layer-design-material/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-dialog")
9 | api project(":layer-popup")
10 | api project(":layer-notification")
11 | api project(":layer-guide")
12 | api project(":layer-overlay")
13 | api project(":layer-toast")
14 | api project(":layer-keyboard")
15 | api project(":layer-design-res")
16 | compileOnly "androidx.cardview:cardview:$cardview_version"
17 | }
18 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFFFF
4 | #FFF7F7F7
5 | #FFF5F5F5
6 | #FFF5F5F5
7 | #1A000000
8 | #FF232323
9 | #FFFFFFFF
10 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-anydpi/layer_keyboard_ic_space.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF333333
4 | #FF222222
5 | #FF111111
6 | #FF111111
7 | #CC000000
8 | #E6FFFFFF
9 | #E6000000
10 |
--------------------------------------------------------------------------------
/layer-dialog/src/main/java/per/goweii/layer/dialog/DefaultDialogOnSwipeListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.dialog;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | public class DefaultDialogOnSwipeListener implements DialogLayer.OnSwipeListener {
6 | @Override
7 | public void onStart(@NonNull DialogLayer layer) {
8 | }
9 |
10 | @Override
11 | public void onSwiping(@NonNull DialogLayer layer, int direction, float fraction) {
12 | }
13 |
14 | @Override
15 | public void onEnd(@NonNull DialogLayer layer, int direction) {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/layer-design-cupertino/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../library.gradle"
3 |
4 | android {
5 | }
6 |
7 | dependencies {
8 | api project(":layer-dialog")
9 | api project(":layer-popup")
10 | api project(":layer-notification")
11 | api project(":layer-guide")
12 | api project(":layer-overlay")
13 | api project(":layer-toast")
14 | api project(":layer-keyboard")
15 | api project(":layer-design-res")
16 | api project(":layer-visualeffectview")
17 | api "com.github.goweii:ShadowLayout:$shadowlayout_version"
18 | }
19 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/drawable/layer_design_material_toast_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/guide_i_know.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/layer-dialog/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/drawable/layer_design_cupertino_alert_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/drawable/layer_design_cupertino_toast_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/layer-notification/src/main/java/per/goweii/layer/notification/DefaultNotificationOnSwipeListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.notification;
2 |
3 | import androidx.annotation.NonNull;
4 |
5 | public class DefaultNotificationOnSwipeListener implements NotificationLayer.OnSwipeListener {
6 | @Override
7 | public void onStart(@NonNull NotificationLayer layer) {
8 | }
9 |
10 | @Override
11 | public void onSwiping(@NonNull NotificationLayer layer, int direction, float fraction) {
12 | }
13 |
14 | @Override
15 | public void onEnd(@NonNull NotificationLayer layer, int direction) {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-anydpi/layer_keyboard_ic_caps.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-anydpi/layer_keyboard_ic_arrow_down.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/layout/layer_design_cupertino_alert_action.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-anydpi/layer_keyboard_ic_enter.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/simple/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #526BFA
4 | #2949FB
5 | #1F36B6
6 | #F62343
7 | #B3000000
8 | #FFFFFF
9 | #FFFFFF
10 | #08000000
11 | #26000000
12 | #33000000
13 | #661F36B6
14 |
15 |
--------------------------------------------------------------------------------
/simple/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #657BF8
4 | #3E5BFB
5 | #2E44BC
6 | #F83A57
7 | #B3ffffff
8 | #CC000000
9 | #333333
10 | #08FFFFFF
11 | #33000000
12 | #99000000
13 | #662E44BC
14 |
15 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-anydpi/layer_keyboard_ic_caps_lock.xml:
--------------------------------------------------------------------------------
1 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/simple/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Layer
3 | 关闭
4 | 确定
5 | 取消
6 | 我知道了
7 | 菜单项
8 | 给个Star
9 | 这么好用的框架,动动手指给个Star吧!
10 | 你有一条新短消息
11 | 点击查看详情
12 | 这也太秀了~
13 | 实现一个引导层就是这么简单!
14 | 发送
15 |
16 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/anim/NullAnimatorCreator.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.anim;
2 |
3 | import android.animation.Animator;
4 | import android.view.View;
5 |
6 | import androidx.annotation.NonNull;
7 | import androidx.annotation.Nullable;
8 |
9 | import per.goweii.layer.core.Layer;
10 |
11 | /**
12 | * @author CuiZhen
13 | */
14 | public class NullAnimatorCreator implements Layer.AnimatorCreator {
15 | @Nullable
16 | @Override
17 | public Animator createInAnimator(@NonNull View target) {
18 | return null;
19 | }
20 |
21 | @Nullable
22 | @Override
23 | public Animator createOutAnimator(@NonNull View target) {
24 | return null;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/java/per/goweii/layer/design/material/MaterialPopupLayer.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.design.material;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.view.View;
6 |
7 | import androidx.annotation.NonNull;
8 |
9 | import per.goweii.layer.popup.PopupLayer;
10 |
11 | public class MaterialPopupLayer extends PopupLayer {
12 | public MaterialPopupLayer(@NonNull Context context) {
13 | super(context);
14 | }
15 |
16 | public MaterialPopupLayer(@NonNull Activity activity) {
17 | super(activity);
18 | }
19 |
20 | public MaterialPopupLayer(@NonNull View targetView) {
21 | super(targetView);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':layer-visualeffectview'
2 | include ":simple"
3 |
4 | include ":layer-core"
5 | include ":layer-core-ktx"
6 |
7 | include ":layer-startup"
8 |
9 | include ":layer-dialog"
10 | include ":layer-dialog-ktx"
11 | include ":layer-popup"
12 | include ":layer-popup-ktx"
13 | include ":layer-notification"
14 | include ":layer-notification-ktx"
15 | include ":layer-guide"
16 | include ":layer-guide-ktx"
17 | include ":layer-overlay"
18 | include ":layer-overlay-ktx"
19 | include ":layer-toast"
20 | include ":layer-toast-ktx"
21 | include ":layer-keyboard"
22 | include ":layer-keyboard-ktx"
23 |
24 | include ":layer-design-res"
25 | include ":layer-design-cupertino"
26 | include ":layer-design-material"
27 |
--------------------------------------------------------------------------------
/layer-design-res/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF222222
4 | #99000000
5 | #BFFFFFFF
6 | #80FFFFFF
7 | #59FFFFFF
8 | #33FFFFFF
9 |
10 | #FA444444
11 | #BFFFFFFF
12 |
--------------------------------------------------------------------------------
/layer-startup/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/layer-core/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/java/per/goweii/layer/keyboard/BindingActionListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.keyboard;
2 |
3 | import android.widget.TextView;
4 |
5 | import androidx.annotation.NonNull;
6 |
7 | public abstract class BindingActionListener implements KeyboardLayer.OnActionListener {
8 | @Override
9 | public boolean onAction(@NonNull KeyboardLayer layer, @NonNull KeyAction action) {
10 | final TextView textView = layer.getViewHolder().getAttachedTextView();
11 | if (textView == null) return false;
12 | return onBind(layer, textView, action);
13 | }
14 |
15 | protected abstract boolean onBind(
16 | @NonNull KeyboardLayer layer,
17 | @NonNull TextView view,
18 | @NonNull KeyAction action
19 | );
20 | }
--------------------------------------------------------------------------------
/layer-design-res/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFFFF
4 | #FFFFFFFF
5 | #1A000000
6 | #BF000000
7 | #80000000
8 | #59000000
9 | #33000000
10 |
11 | #FAEEEEEE
12 | #BF000000
13 |
--------------------------------------------------------------------------------
/layer-startup/src/main/java/per/goweii/layer/startup/LayerInitializer.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.startup;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import androidx.annotation.NonNull;
7 | import androidx.startup.Initializer;
8 |
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | import per.goweii.layer.core.Layers;
13 |
14 | public class LayerInitializer implements Initializer {
15 | @NonNull
16 | @Override
17 | public Layers create(@NonNull Context context) {
18 | return Layers.init((Application) context.getApplicationContext());
19 | }
20 |
21 | @NonNull
22 | @Override
23 | public List>> dependencies() {
24 | return Collections.emptyList();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/library.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.library"
2 | apply from: "../maven-upload.gradle"
3 |
4 | android {
5 | compileSdkVersion android_compile_sdk_version
6 | buildToolsVersion android_build_tools_version
7 | defaultConfig {
8 | minSdkVersion android_min_sdk_version
9 | targetSdkVersion android_target_sdk_version
10 | }
11 | buildTypes {
12 | release {
13 | minifyEnabled false
14 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
15 | }
16 | }
17 | compileOptions {
18 | sourceCompatibility JavaVersion.VERSION_1_7
19 | targetCompatibility JavaVersion.VERSION_1_7
20 | }
21 | }
22 |
23 | dependencies {
24 | compileOnly "androidx.appcompat:appcompat:$androidx_appcompat_version"
25 | }
26 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/overlay.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | android.useAndroidX=true
15 | android.enableJetifier=true
16 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: https://goweii.github.io/resource/payment_code/all_qrcode.jpg
14 |
--------------------------------------------------------------------------------
/simple/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView attach JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/simple/src/main/java/per/goweii/layer/simple/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.simple
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.view.View
6 | import androidx.appcompat.app.AppCompatActivity
7 |
8 | class MainActivity : AppCompatActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | setContentView(R.layout.activity_main)
12 | }
13 |
14 | fun onBtnLayers(view: View) {
15 | startActivity(Intent(this@MainActivity, LayersSimpleActivity::class.java))
16 | }
17 |
18 | fun onBtnMaterial(view: View) {
19 | startActivity(Intent(this@MainActivity, MaterialSimpleActivity::class.java))
20 | }
21 |
22 | fun onBtnCupertino(view: View) {
23 | startActivity(Intent(this@MainActivity, CupertinoSimpleActivity::class.java))
24 | }
25 | }
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/listener/DefaultAnimatorListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.listener;
2 |
3 | import android.animation.Animator;
4 |
5 | public class DefaultAnimatorListener implements Animator.AnimatorListener {
6 | private boolean beenCanceled = false;
7 |
8 | @Override
9 | public void onAnimationStart(Animator animation) {
10 | beenCanceled = false;
11 | }
12 |
13 | @Override
14 | public void onAnimationEnd(Animator animation) {
15 | if (!beenCanceled) {
16 | onAnimationEndNotCanceled(animation);
17 | }
18 | }
19 |
20 | @Override
21 | public void onAnimationCancel(Animator animation) {
22 | beenCanceled = true;
23 | }
24 |
25 | @Override
26 | public void onAnimationRepeat(Animator animation) {
27 | }
28 |
29 | public void onAnimationEndNotCanceled(Animator animation) {
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/drawable-anydpi/layer_keyboard_ic_del.xml:
--------------------------------------------------------------------------------
1 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/java/per/goweii/layer/keyboard/KeyboardVibratorEffect.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.keyboard;
2 |
3 | import android.content.Context;
4 | import android.os.VibrationEffect;
5 | import android.os.Vibrator;
6 |
7 | public class KeyboardVibratorEffect {
8 | private final Context mContext;
9 | private final Vibrator mVibrator;
10 |
11 | public KeyboardVibratorEffect(Context context) {
12 | this.mContext = context;
13 | this.mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
14 | }
15 |
16 | public void release() {
17 | mVibrator.cancel();
18 | }
19 |
20 | public void performClick() {
21 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
22 | VibrationEffect effect = VibrationEffect.createOneShot(1, 1);
23 | mVibrator.vibrate(effect);
24 | } else {
25 | mVibrator.vibrate(1);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 300dp
4 | 300dp
5 |
6 | 20dp
7 |
8 | 24dp
9 | 16dp
10 | 8dp
11 | 4dp
12 |
13 | 4dp
14 | 12dp
15 |
16 | 17sp
17 | 15sp
18 | 15sp
19 | 44dp
20 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/layout/layer_design_material_dialog_action.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/layer-guide-ktx/src/main/java/per/goweii/layer/guide/ktx/GuideLayer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.guide.ktx
2 |
3 | import android.view.View
4 | import androidx.annotation.ColorInt
5 | import androidx.annotation.ColorRes
6 | import androidx.annotation.IdRes
7 | import per.goweii.layer.guide.GuideLayer
8 |
9 | fun T.backgroundColorInt(@ColorInt colorInt: Int) = this.apply {
10 | this.setBackgroundColorInt(colorInt)
11 | }
12 |
13 | fun T.backgroundColorRes(@ColorRes colorRes: Int) = this.apply {
14 | this.setBackgroundColorRes(colorRes)
15 | }
16 |
17 | fun T.mapping(mapping: GuideLayer.Mapping) = this.apply {
18 | this.addMapping(mapping)
19 | }
20 |
21 | fun T.mapping(init: GuideLayer.Mapping.() -> Unit) = this.apply {
22 | this.addMapping(GuideLayer.Mapping().apply { init() })
23 | }
24 |
25 | fun GuideLayer.Mapping.onClick(
26 | @IdRes viewId: Int,
27 | onClickListener: GuideLayer.(view: View) -> Unit
28 | ) = this.apply {
29 | this.addOnClickListener({ layer, v ->
30 | layer as GuideLayer
31 | layer.onClickListener(v)
32 | }, viewId)
33 | }
--------------------------------------------------------------------------------
/simple/src/main/res/layout/guide_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/layer-design-res/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 48dp
4 | 32dp
5 | 24dp
6 | 16dp
7 | 8dp
8 |
9 | 0.5dp
10 |
11 | 8dp
12 | 12dp
13 |
14 | 24dp
15 |
16 | 48dp
17 |
18 | 18sp
19 | 16sp
20 | 16sp
21 | 14sp
22 | 14sp
23 | 12sp
24 | 10sp
25 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/java/per/goweii/layer/keyboard/KeyboardSoundEffect.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.keyboard;
2 |
3 | import android.content.Context;
4 | import android.media.AudioManager;
5 | import android.media.SoundPool;
6 |
7 | import androidx.annotation.NonNull;
8 |
9 | public class KeyboardSoundEffect {
10 | private static final int SOUND_CLICK = R.raw.layer_keyboard_click;
11 |
12 | private final Context mContext;
13 | private final SoundPool mSoundPool;
14 |
15 | private int mIdClick = 0;
16 |
17 | public KeyboardSoundEffect(@NonNull Context context) {
18 | mContext = context.getApplicationContext();
19 | mSoundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 0);
20 | load();
21 | }
22 |
23 | public void release() {
24 | unload();
25 | mSoundPool.release();
26 | }
27 |
28 | public void performClick() {
29 | play(mIdClick);
30 | }
31 |
32 | private void load() {
33 | mIdClick = mSoundPool.load(mContext, SOUND_CLICK, 1);
34 | }
35 |
36 | private void unload() {
37 | if (mIdClick != 0) mSoundPool.unload(mIdClick);
38 | }
39 |
40 | private int play(int id) {
41 | if (id == 0) return 0;
42 | return mSoundPool.play(id, 0.5F, 0.5F, 0, 0, 1F);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/layer-toast-ktx/src/main/java/per/goweii/layer/toast/ktx/ToastLayer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.toast.ktx
2 |
3 | import android.view.View
4 | import androidx.annotation.LayoutRes
5 | import per.goweii.layer.toast.ToastLayer
6 |
7 | fun T.contentView(contentView: View) = this.apply {
8 | this.setContentView(contentView)
9 | }
10 |
11 | fun T.contentView(@LayoutRes contentViewId: Int) = this.apply {
12 | this.setContentView(contentViewId)
13 | }
14 |
15 | fun T.removeOthers(removeOthers: Boolean) = this.apply {
16 | this.setRemoveOthers(removeOthers)
17 | }
18 |
19 | fun T.duration(duration: Long) = this.apply {
20 | this.setDuration(duration)
21 | }
22 |
23 | fun T.gravity(gravity: Int) = this.apply {
24 | this.setGravity(gravity)
25 | }
26 |
27 | fun T.marginLeft(margin: Int?) = this.apply {
28 | this.setMarginLeft(margin)
29 | }
30 |
31 | fun T.marginTop(margin: Int?) = this.apply {
32 | this.setMarginTop(margin)
33 | }
34 |
35 | fun T.marginRight(margin: Int?) = this.apply {
36 | this.setMarginRight(margin)
37 | }
38 |
39 | fun T.marginBottom(margin: Int?) = this.apply {
40 | this.setMarginBottom(margin)
41 | }
42 |
43 | fun T.alpha(alpha: Float) = this.apply {
44 | this.setAlpha(alpha)
45 | }
46 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/dialog_fullscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
24 |
25 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/Layers.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 |
6 | import androidx.annotation.NonNull;
7 |
8 | import per.goweii.layer.core.utils.Utils;
9 |
10 | /**
11 | * 保存 Application 实例。
12 | * 维护 activity 队列,用于弹出全局的浮层。
13 | */
14 | public final class Layers {
15 | private static Layers sLayers = null;
16 |
17 | private final Application mApplication;
18 | private final ActivityHolder mActivityHolder;
19 |
20 | private Layers(@NonNull Application application) {
21 | mApplication = application;
22 | mActivityHolder = new ActivityHolder(application);
23 | }
24 |
25 | public static Layers init(@NonNull Application application) {
26 | if (sLayers == null) {
27 | sLayers = new Layers(application);
28 | }
29 | return sLayers;
30 | }
31 |
32 | @NonNull
33 | public static Layers getInstance() {
34 | return Utils.requireNonNull(sLayers, "需要先在Application中初始化");
35 | }
36 |
37 | @NonNull
38 | public static ActivityHolder getActivityHolder() {
39 | return getInstance().mActivityHolder;
40 | }
41 |
42 | @NonNull
43 | public static Application getApplication() {
44 | return getInstance().mApplication;
45 | }
46 |
47 | @NonNull
48 | public static Activity requireCurrentActivity() {
49 | return getActivityHolder().requireCurrentActivity();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/activity_material_simple.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
24 |
25 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/simple/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
28 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 20dp
4 | 10dp
5 | 6dp
6 | 2dp
7 |
8 | 20dp
9 |
10 | 44dp
11 |
12 | 14dp
13 |
14 | 17sp
15 | 16sp
16 | 13sp
17 | 17sp
18 |
19 | 270dp
20 | 20dp
21 | 8dp
22 |
23 | 270dp
24 |
25 | 12dp
26 | 4dp
27 |
28 | 12dp
29 | 3dp
30 | 24dp
31 | 12dp
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Android template
3 | # Built application files
4 | app/release/
5 | *.ap_
6 | *.aab
7 |
8 | # Files for the ART/Dalvik VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # Generated files
15 | bin/
16 | gen/
17 | out/
18 |
19 | # Gradle files
20 | .gradle/
21 | build/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Proguard folder generated by Eclipse
27 | proguard/
28 |
29 | # Log Files
30 | *.log
31 |
32 | # Android Studio Navigation editor temp files
33 | .navigation/
34 |
35 | # Android Studio captures folder
36 | captures/
37 |
38 | # IntelliJ
39 | *.iml
40 | .idea/
41 | .idea/workspace.xml
42 | .idea/tasks.xml
43 | .idea/gradle.xml
44 | .idea/assetWizardSettings.xml
45 | .idea/dictionaries
46 | .idea/libraries
47 | # Android Studio 3 in .gitignore file.
48 | .idea/caches
49 | .idea/modules.xml
50 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you
51 | .idea/navEditor.xml
52 |
53 | # Keystore files
54 | # Uncomment the following lines if you do not want to check your keystore files in.
55 | #*.jks
56 | #*.keystore
57 |
58 | # External native build folder generated in Android Studio 2.2 and later
59 | .externalNativeBuild
60 |
61 | # Google Services (e.g. APIs or Firebase)
62 | # google-services.json
63 |
64 | # Freeline
65 | freeline.py
66 | freeline/
67 | freeline_project_description.json
68 |
69 | # fastlane
70 | fastlane/report.xml
71 | fastlane/Preview.html
72 | fastlane/screenshots
73 | fastlane/test_output
74 | fastlane/readme.md
75 |
76 | # Version control
77 | vcs.xml
78 |
79 | # lint
80 | lint/intermediates/
81 | lint/generated/
82 | lint/outputs/
83 | lint/tmp/
84 | # lint/reports/
85 |
86 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/widget/LayerContainer.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.FocusFinder;
6 | import android.view.View;
7 | import android.widget.FrameLayout;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 |
12 | public class LayerContainer extends FrameLayout {
13 | private boolean mForceFocusInside = false;
14 |
15 | public LayerContainer(@NonNull Context context) {
16 | this(context, null);
17 | }
18 |
19 | public LayerContainer(@NonNull Context context, @Nullable AttributeSet attrs) {
20 | this(context, attrs, 0);
21 | }
22 |
23 | public LayerContainer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
24 | super(context, attrs, defStyleAttr);
25 | setFocusable(true);
26 | }
27 |
28 | public void setForceFocusInside(boolean forceFocusInside) {
29 | mForceFocusInside = forceFocusInside;
30 | if (forceFocusInside) {
31 | if (!hasFocus()) {
32 | requestFocus();
33 | }
34 | }
35 | }
36 |
37 | @Override
38 | public View focusSearch(View focused, int direction) {
39 | if (!mForceFocusInside) {
40 | return super.focusSearch(focused, direction);
41 | }
42 | FocusFinder focusFinder = FocusFinder.getInstance();
43 | View nextFocus = focusFinder.findNextFocus(this, focused, direction);
44 | if (nextFocus != null) {
45 | return nextFocus;
46 | }
47 | if (hasFocus()) {
48 | return focused;
49 | }
50 | if (!isFocusable()) {
51 | return focused;
52 | }
53 | return this;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
24 |
25 |
32 |
33 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/layout/layer_keyboard.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
23 |
24 |
30 |
31 |
37 |
38 |
44 |
45 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/dialog_input.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
35 |
36 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/java/per/goweii/layer/keyboard/DefaultBindingActionListener.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.keyboard;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.text.Editable;
5 | import android.text.TextUtils;
6 | import android.widget.TextView;
7 |
8 | import androidx.annotation.NonNull;
9 |
10 | public class DefaultBindingActionListener extends BindingActionListener {
11 | @Override
12 | protected boolean onBind(@NonNull KeyboardLayer layer, @NonNull TextView view, @NonNull KeyAction action) {
13 | if (action.getCode() == KeyCodes.KEYCODE_ENTER) {
14 | return onEnter(layer, view, action);
15 | }
16 | if (action.getCode() == KeyCodes.KEYCODE_DEL) {
17 | return onDelete(layer, view, action);
18 | }
19 | if (action.hasInput()) {
20 | return onInput(layer, view, action);
21 | }
22 | return false;
23 | }
24 |
25 | protected boolean onEnter(@NonNull KeyboardLayer layer, @NonNull TextView view, @NonNull KeyAction action) {
26 | view.clearFocus();
27 | layer.dismiss();
28 | return true;
29 | }
30 |
31 | protected boolean onDelete(@NonNull KeyboardLayer layer, @NonNull TextView view, @NonNull KeyAction action) {
32 | CharSequence text = view.getText();
33 | if (text.length() <= 0) {
34 | return false;
35 | }
36 | if (text instanceof Editable) {
37 | Editable editable = (Editable) text;
38 | editable.delete(text.length() - 1, text.length());
39 | } else {
40 | view.setText(text.subSequence(0, text.length() - 1));
41 | }
42 | return true;
43 | }
44 |
45 | @SuppressLint("SetTextI18n")
46 | protected boolean onInput(@NonNull KeyboardLayer layer, @NonNull TextView view, @NonNull KeyAction action) {
47 | if (TextUtils.isEmpty(action.getText())) {
48 | return false;
49 | }
50 | view.setText(view.getText() + action.getText());
51 | return true;
52 | }
53 | }
--------------------------------------------------------------------------------
/layer-visualeffectview/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/java/per/goweii/layer/keyboard/KeyAction.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.keyboard;
2 |
3 | import androidx.annotation.IdRes;
4 | import androidx.annotation.NonNull;
5 | import androidx.annotation.Nullable;
6 |
7 | import java.util.LinkedList;
8 | import java.util.List;
9 |
10 | public class KeyAction {
11 | @IdRes
12 | private int mCode;
13 | @Nullable
14 | private String mText;
15 |
16 | public KeyAction(@IdRes int code, @Nullable String text) {
17 | this.mCode = code;
18 | this.mText = text;
19 | }
20 |
21 | public boolean hasInput() {
22 | return KeyCodes.hasInput(mCode);
23 | }
24 |
25 | public boolean isLetter() {
26 | return KeyCodes.isLetter(mCode);
27 | }
28 |
29 | public boolean isNumber() {
30 | return KeyCodes.isNumber(mCode);
31 | }
32 |
33 | public boolean isSymbol() {
34 | return KeyCodes.isSymbol(mCode);
35 | }
36 |
37 | public void reset() {
38 | this.mCode = 0;
39 | this.mText = null;
40 | }
41 |
42 | public void recycle() {
43 | recycle(this);
44 | }
45 |
46 | @NonNull
47 | public KeyAction copy() {
48 | return obtain(mCode, mText);
49 | }
50 |
51 | @IdRes
52 | public int getCode() {
53 | return mCode;
54 | }
55 |
56 | @Nullable
57 | public String getText() {
58 | return mText;
59 | }
60 |
61 | private void setCode(@IdRes int code) {
62 | mCode = code;
63 | }
64 |
65 | private void setText(@Nullable String text) {
66 | mText = text;
67 | }
68 |
69 | private static final List sPool = new LinkedList<>();
70 |
71 | public static KeyAction obtain(@IdRes int code, @Nullable String text) {
72 | if (sPool.isEmpty()) {
73 | return new KeyAction(code, text);
74 | }
75 | KeyAction action = sPool.remove(0);
76 | action.setCode(code);
77 | action.setText(text);
78 | return action;
79 | }
80 |
81 | public static void recycle(@NonNull KeyAction action) {
82 | action.reset();
83 | sPool.add(action);
84 | }
85 | }
--------------------------------------------------------------------------------
/simple/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "kotlin-android"
3 |
4 | android {
5 | compileSdkVersion android_compile_sdk_version
6 | buildToolsVersion android_build_tools_version
7 | defaultConfig {
8 | applicationId android_application_id
9 | minSdkVersion android_min_sdk_version
10 | targetSdkVersion android_target_sdk_version
11 | versionCode android_version_code
12 | versionName android_version_name
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
19 | }
20 | }
21 | compileOptions {
22 | sourceCompatibility JavaVersion.VERSION_1_8
23 | targetCompatibility JavaVersion.VERSION_1_8
24 | }
25 | applicationVariants.all { variant ->
26 | variant.outputs.each { output ->
27 | output.outputFileName = "${applicationId}.apk"
28 | }
29 | }
30 | }
31 |
32 | dependencies {
33 | implementation fileTree(include: ["*.jar"], dir: "libs")
34 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
35 | implementation "androidx.core:core-ktx:$androidx_core_ktx_version"
36 | implementation "androidx.appcompat:appcompat:1.3.1"
37 | implementation "androidx.cardview:cardview:1.0.0"
38 | implementation "androidx.startup:startup-runtime:1.1.0"
39 | implementation "com.github.goweii:ActionBarEx:3.3.0"
40 | implementation project(":layer-startup")
41 | implementation project(":layer-dialog-ktx")
42 | implementation project(":layer-popup-ktx")
43 | implementation project(":layer-notification-ktx")
44 | implementation project(":layer-guide-ktx")
45 | implementation project(":layer-overlay-ktx")
46 | implementation project(":layer-toast-ktx")
47 | implementation project(":layer-keyboard-ktx")
48 | implementation project(":layer-visualeffectview")
49 | implementation project(":layer-design-cupertino")
50 | implementation project(":layer-design-material")
51 | }
52 |
--------------------------------------------------------------------------------
/layer-dialog/src/main/java/per/goweii/layer/dialog/DialogLayerActivity.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.dialog;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.Nullable;
10 |
11 | import java.lang.ref.WeakReference;
12 |
13 | import per.goweii.layer.core.Layer;
14 | import per.goweii.layer.core.utils.Utils;
15 |
16 | public class DialogLayerActivity extends Activity implements Layer.OnVisibleChangedListener {
17 |
18 | @Nullable
19 | private static WeakReference sOnLayerCreatedCallback = null;
20 |
21 | static void start(@NonNull Context context, @NonNull OnLayerCreatedCallback callback) {
22 | sOnLayerCreatedCallback = new WeakReference<>(callback);
23 | Intent intent = new Intent(context, DialogLayerActivity.class);
24 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
25 | context.startActivity(intent);
26 | }
27 |
28 | @Override
29 | protected void onCreate(@Nullable Bundle savedInstanceState) {
30 | overridePendingTransition(0, 0);
31 | super.onCreate(savedInstanceState);
32 | Utils.transparent(this);
33 | DialogLayer dialogLayer = new DialogLayer(this);
34 | dialogLayer.addOnVisibleChangeListener(this);
35 | if (sOnLayerCreatedCallback != null) {
36 | OnLayerCreatedCallback callback = sOnLayerCreatedCallback.get();
37 | if (callback != null) {
38 | callback.onLayerCreated(dialogLayer);
39 | }
40 | sOnLayerCreatedCallback.clear();
41 | sOnLayerCreatedCallback = null;
42 | }
43 | }
44 |
45 | @Override
46 | public void onShow(@NonNull Layer layer) {
47 | }
48 |
49 | @Override
50 | public void onDismiss(@NonNull Layer layer) {
51 | finish();
52 | overridePendingTransition(0, 0);
53 | }
54 |
55 | public interface OnLayerCreatedCallback {
56 | /**
57 | * 浮层已创建,可在这里进行浮层的初始化和数据绑定
58 | */
59 | void onLayerCreated(@NonNull DialogLayer dialogLayer);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/simple/src/main/java/per/goweii/layer/simple/MaterialSimpleActivity.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.simple
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import androidx.appcompat.app.AppCompatActivity
6 | import per.goweii.layer.core.anim.DelayedZoomAnimatorCreator
7 | import per.goweii.layer.design.material.MaterialDialogLayer
8 | import per.goweii.layer.design.material.MaterialNotificationLayer
9 | import per.goweii.layer.design.material.MaterialPopupLayer
10 | import per.goweii.layer.design.material.MaterialToastLayer
11 | import per.goweii.layer.dialog.ktx.contentAnimator
12 | import per.goweii.layer.dialog.ktx.contentView
13 |
14 | class MaterialSimpleActivity : AppCompatActivity() {
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.activity_material_simple)
18 | }
19 |
20 | fun onBtnDialogClick(view: View) {
21 | MaterialDialogLayer(this)
22 | .setTitle(R.string.dialog_title)
23 | .setDesc(R.string.dialog_msg)
24 | .addAction(R.string.i_know) { layer, _ -> layer.dismiss() }
25 | .addAction(R.string.send) { layer, _ -> layer.dismiss() }
26 | .addAction(R.string.close) { layer, _ -> layer.dismiss() }
27 | .show()
28 | }
29 |
30 | fun onBtnPopupClick(view: View) {
31 | MaterialPopupLayer(view)
32 | .contentView(R.layout.popup_meun)
33 | .contentAnimator(DelayedZoomAnimatorCreator().setCenterPercentX(0.5F))
34 | .show()
35 | }
36 |
37 | fun onBtnToastClick(view: View) {
38 | MaterialToastLayer(this)
39 | .setIcon(R.drawable.ic_success)
40 | .setMessage(R.string.toast_msg)
41 | .show()
42 | }
43 |
44 | fun onBtnNotificationClick(view: View) {
45 | MaterialNotificationLayer(this)
46 | .setIcon(R.drawable.ic_notification)
47 | .setLabel(R.string.app_name)
48 | .setTitle(R.string.notification_title)
49 | .setDesc(R.string.notification_desc)
50 | .setTimePattern("yyyy-MM-dd")
51 | .setOnNotificationClickListener { layer, _ -> layer.dismiss() }
52 | .show()
53 | }
54 | }
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/layout/layer_design_cupertino_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
25 |
26 |
34 |
35 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/layout/layer_design_material_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
25 |
26 |
36 |
37 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/utils/ScrollCompat.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.utils;
2 |
3 | import android.view.View;
4 |
5 | import androidx.annotation.NonNull;
6 | import androidx.core.view.ScrollingView;
7 |
8 | public class ScrollCompat {
9 |
10 | public static boolean canScrollUp(@NonNull View view) {
11 | return ScrollCompat.canScrollVertically(view, -1);
12 | }
13 |
14 | public static boolean canScrollDown(@NonNull View view) {
15 | return ScrollCompat.canScrollVertically(view, 1);
16 | }
17 |
18 | public static boolean canScrollLeft(@NonNull View view) {
19 | return ScrollCompat.canScrollHorizontally(view, -1);
20 | }
21 |
22 | public static boolean canScrollRight(@NonNull View view) {
23 | return ScrollCompat.canScrollHorizontally(view, 1);
24 | }
25 |
26 | public static boolean canScrollHorizontally(@NonNull View v, int direction) {
27 | if (v instanceof ScrollingView) {
28 | return canScrollingViewScrollHorizontally((ScrollingView) v, direction);
29 | } else {
30 | return v.canScrollHorizontally(direction);
31 | }
32 | }
33 |
34 | public static boolean canScrollVertically(@NonNull View v, int direction) {
35 | if (v instanceof ScrollingView) {
36 | return canScrollingViewScrollVertically((ScrollingView) v, direction);
37 | } else {
38 | return v.canScrollVertically(direction);
39 | }
40 | }
41 |
42 | private static boolean canScrollingViewScrollHorizontally(@NonNull ScrollingView view, int direction) {
43 | final int offset = view.computeHorizontalScrollOffset();
44 | final int range = view.computeHorizontalScrollRange() - view.computeHorizontalScrollExtent();
45 | if (range == 0) return false;
46 | if (direction < 0) {
47 | return offset > 0;
48 | } else {
49 | return offset < range - 1;
50 | }
51 | }
52 |
53 | private static boolean canScrollingViewScrollVertically(@NonNull ScrollingView view, int direction) {
54 | final int offset = view.computeVerticalScrollOffset();
55 | final int range = view.computeVerticalScrollRange() - view.computeVerticalScrollExtent();
56 | if (range == 0) return false;
57 | if (direction < 0) {
58 | return offset > 0;
59 | } else {
60 | return offset < range - 1;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/activity_cupertino_simple.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
20 |
21 |
26 |
27 |
32 |
33 |
38 |
39 |
44 |
45 |
50 |
51 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/simple/src/main/java/per/goweii/layer/simple/CupertinoSimpleActivity.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.simple
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import androidx.appcompat.app.AppCompatActivity
6 | import per.goweii.actionbarex.common.ActionBarCommon
7 | import per.goweii.layer.core.ktx.onBindData
8 | import per.goweii.layer.design.cupertino.*
9 | import per.goweii.layer.dialog.ktx.contentView
10 |
11 | class CupertinoSimpleActivity : AppCompatActivity() {
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | setContentView(R.layout.activity_cupertino_simple)
15 | }
16 |
17 | fun onBtnDialogClick(view: View) {
18 | CupertinoAlertLayer(this)
19 | .setTitle(R.string.dialog_title)
20 | .setDesc(R.string.dialog_msg)
21 | .addAction(R.string.i_know) { layer, _ ->
22 | layer.dismiss()
23 | }
24 | .addAction(R.string.send) { layer, _ ->
25 | layer.dismiss()
26 | }
27 | .addAction(R.string.close) { layer, _ ->
28 | layer.dismiss()
29 | }
30 | .show()
31 | }
32 |
33 | fun onBtnPopoverClick(view: View) {
34 | CupertinoPopoverLayer(view)
35 | .contentView(R.layout.popup_meun)
36 | .setUseDefaultConfig()
37 | .setSolidColor(resources.getColor(R.color.colorSurface))
38 | .show()
39 | }
40 |
41 | fun onBtnModalityClick(view: View) {
42 | CupertinoModalityLayer(this)
43 | .contentView(R.layout.dialog_fullscreen)
44 | .onBindData {
45 | val actionBar = requireViewById(R.id.dialog_actionbar)
46 | actionBar.leftTextView.setOnClickListener { dismiss() }
47 | actionBar.rightTextView.setOnClickListener { dismiss() }
48 | }
49 | .show()
50 | }
51 |
52 | fun onBtnToastClick(view: View) {
53 | CupertinoToastLayer(this)
54 | .setIcon(R.drawable.ic_success_big)
55 | .setMessage(R.string.toast_msg)
56 | .show()
57 | }
58 |
59 | fun onBtnNotificationClick(view: View) {
60 | CupertinoNotificationLayer(this)
61 | .setIcon(R.drawable.ic_notification)
62 | .setLabel(R.string.app_name)
63 | .setTitle(R.string.notification_title)
64 | .setDesc(R.string.notification_desc)
65 | .setTimePattern("yyyy-MM-dd")
66 | .setOnNotificationClickListener { layer, _ -> layer.dismiss() }
67 | .show()
68 | }
69 | }
--------------------------------------------------------------------------------
/simple/src/main/res/layout/layout_list_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
14 |
15 |
18 |
19 |
22 |
23 |
26 |
27 |
30 |
31 |
34 |
35 |
38 |
39 |
42 |
43 |
46 |
47 |
50 |
51 |
54 |
55 |
58 |
59 |
62 |
63 |
66 |
67 |
70 |
71 |
74 |
75 |
78 |
79 |
82 |
83 |
86 |
87 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
27 |
28 |
39 |
40 |
51 |
52 |
--------------------------------------------------------------------------------
/layer-dialog/src/main/java/per/goweii/layer/dialog/ContainerLayout.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.dialog;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.view.GestureDetector;
7 | import android.view.MotionEvent;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 |
12 | import per.goweii.layer.core.widget.LayerContainer;
13 |
14 | public class ContainerLayout extends LayerContainer {
15 | private final GestureDetector mGestureDetector;
16 |
17 | private boolean mHandleTouchEvent = false;
18 |
19 | private OnTouchedListener mOnTouchedListener = null;
20 | private OnTappedListener mOnTappedListener = null;
21 |
22 | public ContainerLayout(@NonNull Context context) {
23 | this(context, null);
24 | }
25 |
26 | public ContainerLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
27 | this(context, attrs, 0);
28 | }
29 |
30 | public ContainerLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
31 | super(context, attrs, defStyleAttr);
32 | mGestureDetector = new GestureDetector(context, new OnGestureListener());
33 | }
34 |
35 | @SuppressLint("ClickableViewAccessibility")
36 | @Override
37 | public boolean onTouchEvent(MotionEvent ev) {
38 | return mGestureDetector.onTouchEvent(ev);
39 | }
40 |
41 | public void setHandleTouchEvent(boolean handleTouchEvent) {
42 | this.mHandleTouchEvent = handleTouchEvent;
43 | }
44 |
45 | public void setOnTouchedListener(@Nullable OnTouchedListener onTouchedListener) {
46 | this.mOnTouchedListener = onTouchedListener;
47 | }
48 |
49 | public void setOnTappedListener(@Nullable OnTappedListener onTappedListener) {
50 | this.mOnTappedListener = onTappedListener;
51 | }
52 |
53 | private class OnGestureListener extends GestureDetector.SimpleOnGestureListener {
54 | @Override
55 | public boolean onDown(MotionEvent e) {
56 | if (mOnTouchedListener != null) {
57 | mOnTouchedListener.onTouched();
58 | }
59 | return mHandleTouchEvent;
60 | }
61 |
62 | @Override
63 | public boolean onSingleTapUp(MotionEvent e) {
64 | if (mOnTappedListener != null) {
65 | mOnTappedListener.onTapped();
66 | }
67 | return true;
68 | }
69 | }
70 |
71 | public interface OnTouchedListener {
72 | void onTouched();
73 | }
74 |
75 | public interface OnTappedListener {
76 | void onTapped();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/layer-popup-ktx/src/main/java/per/goweii/layer/popup/ktx/PopupLayer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.popup.ktx
2 |
3 | import android.view.View
4 | import per.goweii.layer.popup.PopupLayer
5 | import per.goweii.layer.popup.PopupLayer.Align
6 |
7 | fun T.updateLocationInterceptor(interceptor: PopupLayer.UpdateLocationInterceptor) =
8 | this.apply {
9 | this.setUpdateLocationInterceptor(interceptor)
10 | }
11 |
12 | fun T.onViewTreeScrollChanged(onScrollChanged: T.() -> Unit) = this.apply {
13 | this.setOnViewTreeScrollChangedListener { this.onScrollChanged() }
14 | }
15 |
16 | fun T.scrollChangedToDismiss(enable: Boolean) = this.apply {
17 | this.setScrollChangedToDismiss(enable)
18 | }
19 |
20 | fun T.targetView(target: View) = this.apply {
21 | this.setTargetView(target)
22 | }
23 |
24 | fun T.contentClip(enable: Boolean) = this.apply {
25 | this.setContentClip(enable)
26 | }
27 |
28 | fun T.backgroundAlign(enable: Boolean) = this.apply {
29 | this.setBackgroundAlign(enable)
30 | }
31 |
32 | fun T.backgroundOffset(enable: Boolean) = this.apply {
33 | this.setBackgroundOffset(enable)
34 | }
35 |
36 | fun T.backgroundResize(enable: Boolean) = this.apply {
37 | this.setBackgroundResize(enable)
38 | }
39 |
40 | fun T.align(
41 | direction: Align.Direction,
42 | horizontal: Align.Horizontal,
43 | vertical: Align.Vertical,
44 | inside: Boolean
45 | ) = this.apply {
46 | this.setAlign(direction, horizontal, vertical, inside)
47 | }
48 |
49 | fun T.direction(direction: Align.Direction) = this.apply {
50 | this.setDirection(direction)
51 | }
52 |
53 | fun T.horizontal(horizontal: Align.Horizontal) = this.apply {
54 | this.setHorizontal(horizontal)
55 | }
56 |
57 | fun T.vertical(vertical: Align.Vertical) = this.apply {
58 | this.setVertical(vertical)
59 | }
60 |
61 | fun T.inside(inside: Boolean) = this.apply {
62 | this.setInside(inside)
63 | }
64 |
65 | fun T.offsetX(offsetX: Float, unit: Int) = this.apply {
66 | this.setOffsetX(offsetX, unit)
67 | }
68 |
69 | fun T.offsetXdp(offsetX: Float) = this.apply {
70 | this.setOffsetXdp(offsetX)
71 | }
72 |
73 | fun T.offsetXpx(offsetX: Float) = this.apply {
74 | this.setOffsetXpx(offsetX)
75 | }
76 |
77 | fun T.offsetY(offsetY: Float, unit: Int) = this.apply {
78 | this.setOffsetY(offsetY, unit)
79 | }
80 |
81 | fun T.offsetYdp(offsetY: Float) = this.apply {
82 | this.setOffsetYdp(offsetY)
83 | }
84 |
85 | fun T.offsetYpx(offsetY: Float) = this.apply {
86 | this.setOffsetYpx(offsetY)
87 | }
--------------------------------------------------------------------------------
/layer-visualeffectview/src/main/java/per/goweii/layer/visualeffectview/BackdropIgnoreView.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.visualeffectview;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.util.AttributeSet;
6 | import android.widget.FrameLayout;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.Nullable;
10 |
11 | import java.lang.ref.WeakReference;
12 | import java.util.Iterator;
13 | import java.util.LinkedList;
14 | import java.util.List;
15 |
16 | public class BackdropIgnoreView extends FrameLayout {
17 | private final List> mBackdropBlurViews = new LinkedList<>();
18 |
19 | public BackdropIgnoreView(@NonNull Context context) {
20 | super(context);
21 | }
22 |
23 | public BackdropIgnoreView(@NonNull Context context, @Nullable AttributeSet attrs) {
24 | super(context, attrs);
25 | }
26 |
27 | public BackdropIgnoreView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
28 | super(context, attrs, defStyleAttr);
29 | }
30 |
31 | public void clearBackdropBlurViews() {
32 | mBackdropBlurViews.clear();
33 | }
34 |
35 | public boolean containBackdropBlurView(@Nullable BackdropBlurView backdropBlurView) {
36 | Iterator> iterator = mBackdropBlurViews.iterator();
37 | boolean contain = false;
38 | while (iterator.hasNext()) {
39 | WeakReference reference = iterator.next();
40 | if (reference.get() == null) {
41 | iterator.remove();
42 | } else {
43 | if (reference.get() == backdropBlurView) {
44 | contain = true;
45 | }
46 | }
47 | }
48 | return contain;
49 | }
50 |
51 | public void addBackdropBlurView(@Nullable BackdropBlurView backdropBlurView) {
52 | if (containBackdropBlurView(backdropBlurView)) {
53 | return;
54 | }
55 | if (backdropBlurView != null) {
56 | mBackdropBlurViews.add(new WeakReference<>(backdropBlurView));
57 | }
58 | }
59 |
60 | @Override
61 | public void draw(Canvas canvas) {
62 | boolean hasRendering = false;
63 | Iterator> iterator = mBackdropBlurViews.iterator();
64 | while (iterator.hasNext()) {
65 | WeakReference reference = iterator.next();
66 | if (reference.get() == null) {
67 | iterator.remove();
68 | } else {
69 | if (!hasRendering && reference.get().isRendering()) {
70 | hasRendering = true;
71 | }
72 | }
73 | }
74 | if (!hasRendering) {
75 | super.draw(canvas);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/activity_layers_simple.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
16 |
17 |
22 |
23 |
28 |
29 |
34 |
35 |
40 |
41 |
46 |
47 |
52 |
53 |
58 |
59 |
64 |
65 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/layout/layer_design_cupertino_alert.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
27 |
28 |
41 |
42 |
47 |
48 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/widget/MaxSizeFrameLayout.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.widget;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 | import android.widget.FrameLayout;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 |
12 | import per.goweii.layer.core.R;
13 |
14 | public class MaxSizeFrameLayout extends FrameLayout {
15 |
16 | private int mMaxWidth = -1;
17 | private int mMaxHeight = -1;
18 |
19 | private OnDispatchTouchListener mOnDispatchTouchListener = null;
20 |
21 | public MaxSizeFrameLayout(@NonNull Context context) {
22 | this(context, null);
23 | }
24 |
25 | public MaxSizeFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
26 | this(context, attrs, 0);
27 | }
28 |
29 | public MaxSizeFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
30 | super(context, attrs, defStyleAttr);
31 | TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MaxSizeFrameLayout);
32 | mMaxWidth = (int) array.getDimension(R.styleable.MaxSizeFrameLayout_android_maxWidth, mMaxWidth);
33 | mMaxHeight = (int) array.getDimension(R.styleable.MaxSizeFrameLayout_android_maxHeight, mMaxHeight);
34 | array.recycle();
35 | }
36 |
37 | public void setMaxWidth(int maxWidth) {
38 | this.mMaxWidth = maxWidth;
39 | requestLayout();
40 | }
41 |
42 | public void setMaxHeight(int maxHeight) {
43 | this.mMaxHeight = maxHeight;
44 | requestLayout();
45 | }
46 |
47 | @Override
48 | public boolean dispatchTouchEvent(MotionEvent e) {
49 | if (mOnDispatchTouchListener != null) {
50 | mOnDispatchTouchListener.onDispatch(e);
51 | }
52 | return super.dispatchTouchEvent(e);
53 | }
54 |
55 | @Override
56 | public boolean onInterceptTouchEvent(MotionEvent e) {
57 | return super.onInterceptTouchEvent(e);
58 | }
59 |
60 | @Override
61 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
62 | int widthMode = MeasureSpec.getMode(widthMeasureSpec);
63 | int widthSize = MeasureSpec.getSize(widthMeasureSpec);
64 | int heightMode = MeasureSpec.getMode(heightMeasureSpec);
65 | int heightSize = MeasureSpec.getSize(heightMeasureSpec);
66 | int newWidthSize = widthSize;
67 | int newHeightSize = heightSize;
68 | if (mMaxWidth >= 0) {
69 | newWidthSize = Math.min(mMaxWidth, widthSize);
70 | }
71 | if (mMaxHeight >= 0) {
72 | newHeightSize = Math.min(mMaxHeight, heightSize);
73 | }
74 | int newWidthSpec = MeasureSpec.makeMeasureSpec(newWidthSize, widthMode);
75 | int newHeightSpec = MeasureSpec.makeMeasureSpec(newHeightSize, heightMode);
76 | super.onMeasure(newWidthSpec, newHeightSpec);
77 | }
78 |
79 | public void setOnDispatchTouchListener(@Nullable OnDispatchTouchListener onDispatchTouchListener) {
80 | this.mOnDispatchTouchListener = onDispatchTouchListener;
81 | }
82 |
83 | public interface OnDispatchTouchListener {
84 | void onDispatch(MotionEvent e);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 简介
2 |
3 | Android稳定高效的浮层创建管理框架。
4 |
5 | [GitHub主页](https://github.com/goweii/Layer)
6 |
7 | [Wiki](https://github.com/goweii/Layer/wiki)
8 |
9 | 可实现Dialog,PopupWindow,引导层,悬浮按钮,通知,吐司,安全键盘等效果。
10 |
11 | 已实现几种常用效果
12 | - DialogLayer:AlertDialog/BottomSheetDialog
13 | - 占用区域不会超过当前Activity避免导航栏遮挡
14 | - 支持自定义大小和显示位置
15 | - 支持自定义数据绑定
16 | - 支持自定义进出场动画
17 | - 支持自定义背景颜色/图片/高斯模糊
18 | - 支持在Activity的onCreate生命周期弹出
19 | - 支持从ApplicationContext中弹出
20 | - 支持拖拽关闭
21 | - 支持不拦截外部事件
22 | - PopupLayer:PopupWindow
23 | - 拥有Dialog效果特性
24 | - 支持跟随目标View移动
25 | - ToastLayer:吐司
26 | - 支持自定义图标和文字
27 | - 支持自定义显示时长
28 | - 支持自定义位置
29 | - 支持自定义背景资源和颜色
30 | - 支持自定义透明度
31 | - 支持自定义进出场动画
32 | - GuideLayer:引导层
33 | - 支持自定义遮罩颜色和圆角半径
34 | - OverlayLayer:悬浮按钮
35 | - 支持自定义吸附边
36 | - 支持自定义正常和低姿态2中模式
37 | - 支持自定义低姿态显示效果
38 | - NotificationLayer:通知
39 | - 支持滑动关闭
40 | - KeyboardLayer:软键盘
41 | - 支持大小写字母/数字/常用符号
42 |
43 | # 截图
44 |
45 | 截图效果较差,建议[下载Demo](https://raw.githubusercontent.com/goweii/Layer/master/simple/release/per.goweii.layer.simple.apk)体验最新功能
46 |
47 | |  |  |  |
48 | | --- | --- | --- |
49 |
50 | # 如何集成
51 |
52 | - 添加仓库
53 |
54 | ```groovy
55 | // build.gradle(Project:)
56 | allprojects {
57 | repositories {
58 | maven { url 'https://jitpack.io' }
59 | }
60 | }
61 | ```
62 |
63 | - 添加依赖
64 |
65 | 
66 |
67 | ```groovy
68 | // build.gradle(Module:)
69 | dependencies {
70 | def version = "1.0.0"
71 |
72 | // 完整引入
73 | implementation "com.github.goweii:Layer:$version"
74 |
75 | // 按需引入
76 |
77 | // 核心功能
78 | // implementation "com.github.goweii.Layer:layer-core:$version"
79 | // 核心功能Kotlin扩展库
80 | // implementation "com.github.goweii.Layer:layer-ktx:$version"
81 | // 自动初始化
82 | // implementation "com.github.goweii.Layer:layer-startup:$version"
83 |
84 | // 各个浮层效果(xxx为module名)
85 | // implementation "com.github.goweii.Layer:layer-xxx:$version"
86 | // implementation "com.github.goweii.Layer:layer-xxx-ktx:$version"
87 | }
88 | ```
89 |
90 | # 如何使用
91 |
92 | 具体使用可参考simple
93 |
94 | - [LayersSimpleActivity](https://raw.githubusercontent.com/goweii/Layer/master/simple/src/main/java/per/goweii/layer/simple/LayersSimpleActivity.kt)
95 | - [MaterialSimpleActivity](https://raw.githubusercontent.com/goweii/Layer/master/simple/src/main/java/per/goweii/layer/simple/MaterialSimpleActivity.kt)
96 | - [CupertinoSimpleActivity](https://raw.githubusercontent.com/goweii/Layer/master/simple/src/main/java/per/goweii/layer/simple/CupertinoSimpleActivity.kt)
97 |
98 | # 更新说明
99 |
100 | [点击查看](https://github.com/goweii/Layer/releases)
101 |
102 | # 如果你觉得还不错,就请我喝杯咖啡吧~
103 |
104 | | 微信 | 支付宝 | QQ |
105 | | :---: | :---: | :---: |
106 | |  |  |  |
107 |
108 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/popup_meun.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
24 |
25 |
26 |
27 |
31 |
32 |
40 |
41 |
42 |
43 |
47 |
48 |
56 |
57 |
58 |
59 |
63 |
64 |
72 |
73 |
74 |
75 |
79 |
80 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/layer-notification-ktx/src/main/java/per/goweii/layer/notification/ktx/NotificationLayer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.notification.ktx
2 |
3 | import android.view.View
4 | import androidx.annotation.FloatRange
5 | import androidx.annotation.LayoutRes
6 | import per.goweii.layer.core.widget.SwipeLayout
7 | import per.goweii.layer.notification.DefaultNotificationOnSwipeListener
8 | import per.goweii.layer.notification.NotificationLayer
9 | import per.goweii.layer.notification.NotificationLayer.SwipeTransformer
10 |
11 | fun T.contentView(contentView: View) = this.apply {
12 | this.setContentView(contentView)
13 | }
14 |
15 | fun T.contentView(@LayoutRes contentViewId: Int) = this.apply {
16 | this.setContentView(contentViewId)
17 | }
18 |
19 | fun T.maxWidth(maxWidth: Int) = this.apply {
20 | this.setMaxWidth(maxWidth)
21 | }
22 |
23 | fun T.maxHeight(maxHeight: Int) = this.apply {
24 | this.setMaxHeight(maxHeight)
25 | }
26 |
27 | fun T.removeOthers(removeOthers: Boolean) = this.apply {
28 | this.setRemoveOthers(removeOthers)
29 | }
30 |
31 | fun T.swipeDirection(@SwipeLayout.Direction direction: Int) = this.apply {
32 | this.setSwipeDirection(direction)
33 | }
34 |
35 | fun T.swipeTransformer(swipeTransformer: SwipeTransformer) = this.apply {
36 | this.setSwipeTransformer(swipeTransformer)
37 | }
38 |
39 | fun T.duration(duration: Long) = this.apply {
40 | this.setDuration(duration)
41 | }
42 |
43 | fun T.onNotificationClick(onClick: T.(view: View) -> Unit) =
44 | this.apply {
45 | this.setOnNotificationClickListener { _, view -> this.onClick(view) }
46 | }
47 |
48 | fun T.onNotificationLongClick(onLongClick: T.(view: View) -> Boolean) =
49 | this.apply {
50 | this.setOnNotificationLongClickListener { _, view -> this.onLongClick(view) }
51 | }
52 |
53 | fun T.autoDismiss(autoDismiss: Boolean) = this.apply {
54 | this.setAutoDismiss(autoDismiss)
55 | }
56 |
57 | fun T.onSwipeStart(onStart: T.() -> Unit) = this.apply {
58 | this.addOnSwipeListener(object : DefaultNotificationOnSwipeListener() {
59 | override fun onStart(layer: NotificationLayer) {
60 | this@apply.onStart()
61 | }
62 | })
63 | }
64 |
65 | fun T.onSwiping(onSwiping: T.(direction: Int, fraction: Float) -> Unit) =
66 | this.apply {
67 | this.addOnSwipeListener(object : DefaultNotificationOnSwipeListener() {
68 | override fun onSwiping(
69 | layer: NotificationLayer,
70 | @SwipeLayout.Direction direction: Int,
71 | @FloatRange(from = 0.0, to = 1.0) fraction: Float
72 | ) {
73 | this@apply.onSwiping(direction, fraction)
74 | }
75 | })
76 | }
77 |
78 | fun T.onSwipeEnd(onEnd: T.(direction: Int) -> Unit) = this.apply {
79 | this.addOnSwipeListener(object : DefaultNotificationOnSwipeListener() {
80 | override fun onEnd(layer: NotificationLayer, @SwipeLayout.Direction direction: Int) {
81 | this@apply.onEnd(direction)
82 | }
83 | })
84 | }
--------------------------------------------------------------------------------
/layer-guide/src/main/java/per/goweii/layer/guide/HoleView.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.guide;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.graphics.Rect;
9 | import android.graphics.RectF;
10 | import android.graphics.Region;
11 | import android.os.Build;
12 | import android.util.AttributeSet;
13 | import android.view.View;
14 |
15 | import androidx.annotation.ColorInt;
16 | import androidx.annotation.NonNull;
17 | import androidx.annotation.Nullable;
18 | import androidx.core.graphics.ColorUtils;
19 |
20 | import per.goweii.layer.core.utils.Utils;
21 |
22 | public class HoleView extends View {
23 | private final Paint mPaint;
24 | private final Path mTempPath = new Path();
25 | private final Path mHolePath = new Path();
26 | @ColorInt
27 | private int mOuterColor = ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.5));
28 |
29 | public HoleView(Context context) {
30 | this(context, null);
31 | }
32 |
33 | public HoleView(Context context, @Nullable AttributeSet attrs) {
34 | this(context, attrs, 0);
35 | }
36 |
37 | public HoleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
38 | super(context, attrs, defStyleAttr);
39 | mPaint = new Paint();
40 | mPaint.setAntiAlias(true);
41 | }
42 |
43 | public void setOuterColor(@ColorInt int colorInt) {
44 | mOuterColor = colorInt;
45 | }
46 |
47 | public void clear() {
48 | mTempPath.reset();
49 | mTempPath.rewind();
50 | }
51 |
52 | public void addCircle(float centerX, float centerY, float radius) {
53 | mTempPath.addCircle(centerX, centerY, radius, Path.Direction.CW);
54 | }
55 |
56 | public void addRect(float left, float top, float right, float bottom, float radii) {
57 | addRect(new RectF(left, top, right, bottom), radii);
58 | }
59 |
60 | public void addRect(@NonNull Rect rect, float radii) {
61 | addRect(new RectF(rect), radii);
62 | }
63 |
64 | public void addRect(@NonNull RectF rectF, float radii) {
65 | radii = Utils.floatRange(radii, 0F, Math.min(rectF.width(), rectF.height()) / 2F);
66 | mTempPath.addRoundRect(
67 | rectF,
68 | new float[]{radii, radii, radii, radii, radii, radii, radii, radii},
69 | Path.Direction.CW
70 | );
71 | }
72 |
73 | public void addPath(@NonNull Path path) {
74 | mTempPath.addPath(path);
75 | invalidate();
76 | }
77 |
78 | @Override
79 | protected void onDraw(Canvas canvas) {
80 | super.onDraw(canvas);
81 | canvas.save();
82 | mPaint.setColor(mOuterColor);
83 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
84 | mHolePath.reset();
85 | mHolePath.rewind();
86 | mHolePath.addRect(0F, 0F, getWidth(), getHeight(), Path.Direction.CW);
87 | mHolePath.op(mHolePath, mTempPath, Path.Op.DIFFERENCE);
88 | canvas.drawPath(mHolePath, mPaint);
89 | } else {
90 | canvas.clipPath(mTempPath, Region.Op.DIFFERENCE);
91 | canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
92 | }
93 | canvas.restore();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/layer-overlay-ktx/src/main/java/per/goweii/layer/overlay/ktx/OverlayLayer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.overlay.ktx
2 |
3 | import android.view.View
4 | import androidx.annotation.FloatRange
5 | import androidx.annotation.LayoutRes
6 | import per.goweii.layer.overlay.OverlayLayer
7 |
8 | fun T.overlayView(@LayoutRes layoutId: Int) = this.apply {
9 | this.setOverlayView(layoutId)
10 | }
11 |
12 | fun T.overlayView(floatView: View) = this.apply {
13 | this.setOverlayView(floatView)
14 | }
15 |
16 | fun T.defPercentX(p: Float) = this.apply {
17 | this.setDefPercentX(p)
18 | }
19 |
20 | fun T.defPercentY(p: Float) = this.apply {
21 | this.setDefPercentY(p)
22 | }
23 |
24 | fun T.defAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) = this.apply {
25 | this.setDefAlpha(alpha)
26 | }
27 |
28 | fun T.defScale(scale: Float) = this.apply {
29 | this.setDefScale(scale)
30 | }
31 |
32 | fun T.normalAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) = this.apply {
33 | this.setNormalAlpha(alpha)
34 | }
35 |
36 | fun T.normalScale(scale: Float) = this.apply {
37 | this.setNormalScale(scale)
38 | }
39 |
40 | fun T.lowProfileAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) =
41 | this.apply {
42 | this.setLowProfileAlpha(alpha)
43 | }
44 |
45 | fun T.lowProfileScale(scale: Float) = this.apply {
46 | this.setLowProfileScale(scale)
47 | }
48 |
49 | fun T.lowProfileIndent(@FloatRange(from = 0.0, to = 1.0) indent: Float) =
50 | this.apply {
51 | this.setLowProfileIndent(indent)
52 | }
53 |
54 | fun T.lowProfileDelay(delay: Long) = this.apply {
55 | this.setLowProfileDelay(delay)
56 | }
57 |
58 | fun T.snapEdge(edge: Int) = this.apply {
59 | this.setSnapEdge(edge)
60 | }
61 |
62 | fun T.pivotX(pivot: Float) = this.apply {
63 | this.setPivotX(pivot)
64 | }
65 |
66 | fun T.pivotY(pivot: Float) = this.apply {
67 | this.setPivotY(pivot)
68 | }
69 |
70 | fun T.outside(outside: Boolean) = this.apply {
71 | this.setOutside(outside)
72 | }
73 |
74 | fun T.marginLeft(margin: Int?) = this.apply {
75 | this.setMarginLeft(margin)
76 | }
77 |
78 | fun T.marginTop(margin: Int?) = this.apply {
79 | this.setMarginTop(margin)
80 | }
81 |
82 | fun T.marginRight(margin: Int?) = this.apply {
83 | this.setMarginRight(margin)
84 | }
85 |
86 | fun T.marginBottom(margin: Int?) = this.apply {
87 | this.setMarginBottom(margin)
88 | }
89 |
90 | fun T.paddingLeft(padding: Int) = this.apply {
91 | this.setPaddingLeft(padding)
92 | }
93 |
94 | fun T.paddingTop(padding: Int) = this.apply {
95 | this.setPaddingTop(padding)
96 | }
97 |
98 | fun T.paddingRight(padding: Int) = this.apply {
99 | this.setPaddingRight(padding)
100 | }
101 |
102 | fun T.paddingBottom(padding: Int) = this.apply {
103 | this.setPaddingBottom(padding)
104 | }
105 |
106 | fun T.onOverlayClick(onClick: T.(view: View) -> Unit) = this.apply {
107 | this.addOnOverlayClickListener { _, view -> this.onClick(view) }
108 | }
109 |
110 | fun T.onOverlayLongClick(onLongClick: T.(view: View) -> Boolean) = this.apply {
111 | this.setOnOverlayLongClickListener { _, view -> this.onLongClick(view) }
112 | }
--------------------------------------------------------------------------------
/layer-design-material/src/main/res/layout/layer_design_material_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
19 |
20 |
24 |
25 |
36 |
37 |
49 |
50 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/simple/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
22 |
23 |
33 |
34 |
40 |
41 |
47 |
48 |
53 |
54 |
59 |
60 |
76 |
77 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/anim/CircularRevealAnimatorCreator.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.anim;
2 |
3 | import android.animation.Animator;
4 | import android.animation.TimeInterpolator;
5 | import android.os.Build;
6 | import android.view.View;
7 | import android.view.ViewAnimationUtils;
8 | import android.view.animation.AccelerateInterpolator;
9 | import android.view.animation.DecelerateInterpolator;
10 |
11 | import androidx.annotation.NonNull;
12 | import androidx.annotation.Nullable;
13 | import androidx.annotation.RequiresApi;
14 |
15 | import per.goweii.layer.core.Layer;
16 |
17 | @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
18 | public class CircularRevealAnimatorCreator implements Layer.AnimatorCreator {
19 | private boolean mUsePercentX = true;
20 | private boolean mUsePercentY = true;
21 | private float mCenterPercentX = 0.5F;
22 | private float mCenterPercentY = 0.5F;
23 | private int mCenterX = 0;
24 | private int mCenterY = 0;
25 | private TimeInterpolator mInTimeInterpolator = null;
26 | private TimeInterpolator mOutTimeInterpolator = null;
27 |
28 | public CircularRevealAnimatorCreator setCenterPercentX(float centerPercentX) {
29 | mUsePercentX = true;
30 | mCenterPercentX = centerPercentX;
31 | return this;
32 | }
33 |
34 | public CircularRevealAnimatorCreator setCenterPercentY(float centerPercentY) {
35 | mUsePercentY = true;
36 | mCenterPercentY = centerPercentY;
37 | return this;
38 | }
39 |
40 | public CircularRevealAnimatorCreator setCenterX(int centerX) {
41 | mUsePercentX = false;
42 | mCenterX = centerX;
43 | return this;
44 | }
45 |
46 | public CircularRevealAnimatorCreator setCenterY(int centerY) {
47 | mUsePercentY = false;
48 | mCenterY = centerY;
49 | return this;
50 | }
51 |
52 | public void setInTimeInterpolator(TimeInterpolator inTimeInterpolator) {
53 | mInTimeInterpolator = inTimeInterpolator;
54 | }
55 |
56 | public void setOutTimeInterpolator(TimeInterpolator outTimeInterpolator) {
57 | mOutTimeInterpolator = outTimeInterpolator;
58 | }
59 |
60 | @Nullable
61 | @Override
62 | public Animator createInAnimator(@NonNull View target) {
63 | int x = target.getWidth();
64 | int y = target.getHeight();
65 | int centerX = mUsePercentX ? (int) (mCenterPercentX * x) : mCenterX;
66 | int centerY = mUsePercentY ? (int) (mCenterPercentY * y) : mCenterY;
67 | int r = (int) Math.sqrt(Math.pow(Math.max(centerX, x - centerX), 2) + Math.pow(Math.max(centerY, y - centerY), 2));
68 | Animator animator = ViewAnimationUtils.createCircularReveal(target, centerX, centerY, 0, r);
69 | if (mInTimeInterpolator != null) {
70 | animator.setInterpolator(mInTimeInterpolator);
71 | } else {
72 | animator.setInterpolator(new DecelerateInterpolator());
73 | }
74 | return animator;
75 | }
76 |
77 | @Nullable
78 | @Override
79 | public Animator createOutAnimator(@NonNull View target) {
80 | int x = target.getWidth();
81 | int y = target.getHeight();
82 | int centerX = mUsePercentX ? (int) (mCenterPercentX * x) : mCenterX;
83 | int centerY = mUsePercentY ? (int) (mCenterPercentY * y) : mCenterY;
84 | int r = (int) Math.sqrt(Math.pow(Math.max(centerX, x - centerX), 2) + Math.pow(Math.max(centerY, y - centerY), 2));
85 | Animator animator = ViewAnimationUtils.createCircularReveal(target, centerX, centerY, r, 0);
86 | if (mOutTimeInterpolator != null) {
87 | animator.setInterpolator(mOutTimeInterpolator);
88 | } else {
89 | animator.setInterpolator(new AccelerateInterpolator());
90 | }
91 | return animator;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/simple/src/main/res/layout/dialog_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
18 |
19 |
31 |
32 |
43 |
44 |
49 |
50 |
57 |
58 |
65 |
66 |
67 |
68 |
74 |
75 |
82 |
83 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/layer-keyboard/src/main/java/per/goweii/layer/keyboard/KeyboardGesture.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.keyboard;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.view.GestureDetector;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 |
8 | import androidx.annotation.NonNull;
9 |
10 | public class KeyboardGesture {
11 | private final KeyboardLayer mLayer;
12 | private final View mView;
13 | private final boolean mRepeatable;
14 | private final Runnable mOnKeyAction;
15 | private final KeyboardGestureListener mGestureListener;
16 |
17 | public KeyboardGesture(
18 | @NonNull KeyboardLayer layer,
19 | @NonNull View view,
20 | boolean repeatable,
21 | @NonNull Runnable action
22 | ) {
23 | this.mLayer = layer;
24 | this.mView = view;
25 | this.mRepeatable = repeatable;
26 | this.mOnKeyAction = action;
27 | this.mGestureListener = new KeyboardGestureListener();
28 | final GestureDetector gestureDetector = new GestureDetector(view.getContext(), mGestureListener);
29 | mView.setOnTouchListener(new View.OnTouchListener() {
30 | @SuppressLint("ClickableViewAccessibility")
31 | @Override
32 | public boolean onTouch(View v, MotionEvent event) {
33 | gestureDetector.onTouchEvent(event);
34 | switch (event.getAction()) {
35 | case MotionEvent.ACTION_UP:
36 | mGestureListener.onUp(event);
37 | case MotionEvent.ACTION_CANCEL:
38 | mGestureListener.onCancel(event);
39 | break;
40 | }
41 | return true;
42 | }
43 | });
44 | }
45 |
46 | private class KeyboardGestureListener implements GestureDetector.OnGestureListener {
47 | private final Runnable mRepeatRunnable = new Runnable() {
48 | @Override
49 | public void run() {
50 | if (mRepeatable && mRepeating) {
51 | mOnKeyAction.run();
52 | mLayer.performFeedback();
53 | mView.postDelayed(mRepeatRunnable, 50);
54 | }
55 | }
56 | };
57 |
58 | private boolean mRepeating = false;
59 |
60 | @Override
61 | public boolean onDown(MotionEvent e) {
62 | mRepeating = false;
63 | mView.removeCallbacks(mRepeatRunnable);
64 | mView.setPressed(true);
65 | return true;
66 | }
67 |
68 | public void onUp(MotionEvent e) {
69 | mRepeating = false;
70 | mView.removeCallbacks(mRepeatRunnable);
71 | mView.setPressed(false);
72 | }
73 |
74 | public void onCancel(MotionEvent e) {
75 | mRepeating = false;
76 | mView.removeCallbacks(mRepeatRunnable);
77 | mView.setPressed(false);
78 | }
79 |
80 | @Override
81 | public void onShowPress(MotionEvent e) {
82 | }
83 |
84 | @Override
85 | public boolean onSingleTapUp(MotionEvent e) {
86 | mOnKeyAction.run();
87 | mLayer.performFeedback();
88 | return true;
89 | }
90 |
91 | @Override
92 | public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
93 | mRepeating = false;
94 | mView.removeCallbacks(mRepeatRunnable);
95 | return false;
96 | }
97 |
98 | @Override
99 | public void onLongPress(MotionEvent e) {
100 | if (mRepeatable) {
101 | mRepeating = true;
102 | mView.post(mRepeatRunnable);
103 | }
104 | }
105 |
106 | @Override
107 | public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
108 | return false;
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/ActivityHolder.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.os.Bundle;
6 | import android.text.TextUtils;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.annotation.Nullable;
10 |
11 | import java.lang.ref.WeakReference;
12 | import java.util.LinkedList;
13 | import java.util.List;
14 |
15 | import per.goweii.layer.core.utils.Utils;
16 |
17 | public final class ActivityHolder {
18 | private final List> mActivityStack = new LinkedList<>();
19 |
20 | public ActivityHolder(@NonNull Application application) {
21 | application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacksImpl());
22 | }
23 |
24 | @NonNull
25 | public Activity requireActivity(@NonNull Class clazz) {
26 | Activity activity = getActivity(clazz);
27 | Utils.requireNonNull(activity, "请确保有已启动的Activity实例:" + clazz.getName());
28 | return activity;
29 | }
30 |
31 | @Nullable
32 | public Activity getActivity(@NonNull Class clazz) {
33 | final List> stack = mActivityStack;
34 | if (stack.isEmpty()) return null;
35 | final int size = stack.size();
36 | Activity find = null;
37 | for (int i = size - 1; i >= 0; i--) {
38 | WeakReference ref = stack.get(i);
39 | final Activity activity = ref.get();
40 | if (activity == null) {
41 | ref.clear();
42 | stack.remove(i);
43 | } else {
44 | if (find == null) {
45 | if (TextUtils.equals(clazz.getName(), activity.getClass().getName())) {
46 | find = activity;
47 | }
48 | }
49 | }
50 | }
51 | return find;
52 | }
53 |
54 | @NonNull
55 | public Activity requireCurrentActivity() {
56 | Activity activity = getCurrentActivity();
57 | Utils.requireNonNull(activity, "请确保有已启动的Activity实例");
58 | return activity;
59 | }
60 |
61 | @Nullable
62 | public Activity getCurrentActivity() {
63 | final List> stack = mActivityStack;
64 | if (stack.isEmpty()) return null;
65 | final int size = stack.size();
66 | for (int i = size - 1; i >= 0; i--) {
67 | WeakReference ref = stack.get(i);
68 | if (ref.get() == null) {
69 | ref.clear();
70 | stack.remove(i);
71 | }
72 | }
73 | if (stack.isEmpty()) return null;
74 | return stack.get(stack.size() - 1).get();
75 | }
76 |
77 | private class ActivityLifecycleCallbacksImpl implements Application.ActivityLifecycleCallbacks {
78 | @Override
79 | public void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {
80 | mActivityStack.add(new WeakReference<>(activity));
81 | }
82 |
83 | @Override
84 | public void onActivityStarted(@NonNull Activity activity) {
85 | }
86 |
87 | @Override
88 | public void onActivityResumed(@NonNull Activity activity) {
89 | }
90 |
91 | @Override
92 | public void onActivityPaused(@NonNull Activity activity) {
93 | }
94 |
95 | @Override
96 | public void onActivityStopped(@NonNull Activity activity) {
97 | }
98 |
99 | @Override
100 | public void onActivityDestroyed(@NonNull Activity activity) {
101 | final int size = mActivityStack.size();
102 | for (int i = size - 1; i >= 0; i--) {
103 | WeakReference ref = mActivityStack.get(i);
104 | if (ref.get() == null || ref.get() == activity) {
105 | ref.clear();
106 | mActivityStack.remove(i);
107 | }
108 | }
109 | }
110 |
111 | @Override
112 | public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/layer-visualeffectview/src/main/java/per/goweii/layer/visualeffectview/BackdropBlurView.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.visualeffectview;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Path;
6 | import android.graphics.RectF;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 |
10 | import androidx.annotation.NonNull;
11 |
12 | import java.util.Arrays;
13 |
14 | import per.goweii.visualeffect.blur.BlurEffect;
15 | import per.goweii.visualeffect.blur.RSBlurEffect;
16 | import per.goweii.visualeffect.view.BackdropVisualEffectFrameLayout;
17 | import per.goweii.visualeffect.view.OutlineBuilder;
18 |
19 | public class BackdropBlurView extends BackdropVisualEffectFrameLayout {
20 | private final RoundedOutlineBuilder mOutlineBuilder = new RoundedOutlineBuilder();
21 |
22 | private float mCornerRadius = 0F;
23 | private float mBlurRadius = 8F;
24 | private float mBlurPercent = 0F;
25 |
26 | public BackdropBlurView(Context context) {
27 | this(context, null);
28 | }
29 |
30 | public BackdropBlurView(Context context, AttributeSet attrs) {
31 | this(context, attrs, 0);
32 | }
33 |
34 | public BackdropBlurView(Context context, AttributeSet attrs, int defStyleAttr) {
35 | super(context, attrs, defStyleAttr);
36 | setShowDebugInfo(false);
37 | }
38 |
39 | @Override
40 | public void draw(@NonNull Canvas canvas) {
41 | float simple = getSimpleSize();
42 | float radius;
43 | if (mBlurPercent > 0) {
44 | radius = Math.min(getWidth(), getHeight()) * mBlurPercent;
45 | mBlurPercent = 0F;
46 | } else {
47 | radius = mBlurRadius;
48 | }
49 | if (radius > 25) {
50 | simple = simple * (radius / 25);
51 | radius = 25;
52 | } else if (radius < 0) {
53 | radius = 0;
54 | }
55 | if (mBlurRadius != radius) {
56 | mBlurRadius = radius;
57 | }
58 | if (getSimpleSize() != simple) {
59 | setSimpleSize(simple);
60 | }
61 | if (radius == 0) {
62 | if (getVisualEffect() != null) {
63 | setVisualEffect(null);
64 | }
65 | } else {
66 | if (!(getVisualEffect() instanceof BlurEffect) || ((BlurEffect) getVisualEffect()).getRadius() != radius) {
67 | setVisualEffect(new RSBlurEffect(getContext(), radius));
68 | }
69 | }
70 | super.draw(canvas);
71 | }
72 |
73 | public void setCornerRadius(float cornerRadius) {
74 | if (mCornerRadius != cornerRadius) {
75 | mCornerRadius = cornerRadius;
76 | if (mCornerRadius == 0) {
77 | if (getOutlineBuilder() != null) {
78 | setOutlineBuilder(null);
79 | }
80 | } else {
81 | if (getOutlineBuilder() == null) {
82 | setOutlineBuilder(mOutlineBuilder);
83 | } else {
84 | mOutlineBuilder.invalidateOutline();
85 | }
86 | }
87 | }
88 | }
89 |
90 | public void setBlurPercent(float blurPercent) {
91 | if (mBlurPercent != blurPercent) {
92 | mBlurPercent = blurPercent;
93 | invalidate();
94 | }
95 | }
96 |
97 | public void setBlurRadius(float blurRadius) {
98 | if (mBlurRadius != blurRadius) {
99 | mBlurRadius = blurRadius;
100 | invalidate();
101 | }
102 | }
103 |
104 | private class RoundedOutlineBuilder extends OutlineBuilder {
105 | private final RectF rect = new RectF();
106 | private final float[] radii = new float[8];
107 |
108 | @Override
109 | public void buildOutline(@NonNull View view, @NonNull Path path) {
110 | float minSide = Math.min(view.getWidth(), view.getHeight());
111 | float r = Math.min(mCornerRadius, minSide / 2F);
112 | Arrays.fill(radii, r);
113 | rect.set(0, 0, view.getWidth(), view.getHeight());
114 | path.addRoundRect(rect, radii, Path.Direction.CW);
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/layer-core-ktx/src/main/java/per/goweii/layer/core/ktx/Layer.kt:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.ktx
2 |
3 | import android.animation.Animator
4 | import android.view.View
5 | import androidx.annotation.IdRes
6 | import per.goweii.layer.core.Layer
7 | import per.goweii.layer.core.listener.DefaultOnDismissListener
8 | import per.goweii.layer.core.listener.DefaultOnShowListener
9 | import per.goweii.layer.core.listener.DefaultOnVisibleChangedListener
10 |
11 | fun T.onClick(@IdRes viewId: Int, onClickListener: T.(view: View) -> Unit) =
12 | this.apply {
13 | this.addOnClickListener({ _, v -> this.onClickListener(v) }, viewId)
14 | }
15 |
16 | fun T.onClickToDismiss(
17 | @IdRes viewId: Int,
18 | onClickListener: (T.(view: View) -> Unit)? = null
19 | ) = this.apply {
20 | onClickListener?.let {
21 | this.addOnClickToDismissListener({ _, v -> this.it(v) }, viewId)
22 | } ?: addOnClickToDismissListener(null, viewId)
23 | }
24 |
25 | fun T.onLongClick(@IdRes viewId: Int, onLongClickListener: T.(view: View) -> Boolean) =
26 | this.apply {
27 | this.addOnLongClickListener({ _, v -> this.onLongClickListener(v) }, viewId)
28 | }
29 |
30 | fun T.onLongClickToDismiss(
31 | @IdRes viewId: Int,
32 | onLongClickListener: (T.(view: View) -> Boolean)? = null
33 | ) = this.apply {
34 | onLongClickListener?.let {
35 | this.addOnLongClickToDismissListener({ _, v -> this.it(v) }, viewId)
36 | } ?: addOnLongClickToDismissListener(null, viewId)
37 | }
38 |
39 | fun T.onBindData(dataBinder: T.() -> Unit) = this.apply {
40 | this.addOnBindDataListener { this.dataBinder() }
41 | }
42 |
43 | fun T.onInitialize(onInitialize: T.() -> Unit) = this.apply {
44 | this.addOnInitializeListener { this.onInitialize() }
45 | }
46 |
47 | fun T.onShow(onShow: T.() -> Unit) = this.apply {
48 | this.addOnVisibleChangeListener(object : DefaultOnVisibleChangedListener() {
49 | override fun onShow(layer: Layer) {
50 | onShow.invoke(this@apply)
51 | }
52 | })
53 | }
54 |
55 | fun T.onDismiss(onDismiss: T.() -> Unit) = this.apply {
56 | this.addOnVisibleChangeListener(object : DefaultOnVisibleChangedListener() {
57 | override fun onDismiss(layer: Layer) {
58 | onDismiss.invoke(this@apply)
59 | }
60 | })
61 | }
62 |
63 | fun T.onPreShow(onPreShow: T.() -> Unit) = this.apply {
64 | this.addOnShowListener(object : DefaultOnShowListener() {
65 | override fun onPreShow(layer: Layer) {
66 | this@apply.onPreShow()
67 | }
68 | })
69 | }
70 |
71 | fun T.onPostShow(onPostShow: T.() -> Unit) = this.apply {
72 | this.addOnShowListener(object : DefaultOnShowListener() {
73 | override fun onPostShow(layer: Layer) {
74 | this@apply.onPostShow()
75 | }
76 | })
77 | }
78 |
79 | fun T.onPreDismiss(onPreDismiss: T.() -> Unit) = this.apply {
80 | this.addOnDismissListener(object : DefaultOnDismissListener() {
81 | override fun onPreDismiss(layer: Layer) {
82 | this@apply.onPreDismiss()
83 | }
84 | })
85 | }
86 |
87 | fun T.onPostDismiss(onPostDismiss: T.() -> Unit) = this.apply {
88 | this.addOnDismissListener(object : DefaultOnDismissListener() {
89 | override fun onPostDismiss(layer: Layer) {
90 | this@apply.onPostDismiss()
91 | }
92 | })
93 | }
94 |
95 | fun T.animator(
96 | onIn: T.(target: View) -> R,
97 | onOut: T.(target: View) -> R
98 | ) = this.apply {
99 | this.setAnimator(object : Layer.AnimatorCreator {
100 | override fun createInAnimator(target: View): Animator? {
101 | return onIn.invoke(this@apply, target)
102 | }
103 |
104 | override fun createOutAnimator(target: View): Animator? {
105 | return onOut.invoke(this@apply, target)
106 | }
107 | })
108 | }
109 |
110 | fun T.animator(creator: Layer.AnimatorCreator) = this.apply {
111 | this.setAnimator(creator)
112 | }
113 |
114 | fun T.interceptKeyEvent(enable: Boolean) = this.apply {
115 | this.isInterceptKeyEvent = enable
116 | }
117 |
118 | fun T.cancelableOnClickKeyBack(enable: Boolean) = this.apply {
119 | this.isCancelableOnKeyBack = enable
120 | }
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/anim/AnimStyle.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.anim;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorSet;
5 | import android.view.View;
6 | import android.view.animation.AccelerateInterpolator;
7 | import android.view.animation.DecelerateInterpolator;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 |
12 | import per.goweii.layer.core.Layer;
13 |
14 | public enum AnimStyle implements Layer.AnimatorCreator {
15 | NONE,
16 | ALPHA,
17 | ZOOM,
18 | ZOOM_ALPHA,
19 | BOTTOM,
20 | BOTTOM_ALPHA,
21 | TOP,
22 | TOP_ALPHA,
23 | LEFT,
24 | LEFT_ALPHA,
25 | RIGHT,
26 | RIGHT_ALPHA,
27 | BOTTOM_ZOOM_ALPHA,
28 | ;
29 |
30 | @Nullable
31 | public Animator createInAnimator(@NonNull View target) {
32 | switch (this) {
33 | default:
34 | case NONE:
35 | return null;
36 | case ALPHA:
37 | return AnimatorHelper.createAlphaInAnim(target);
38 | case ZOOM:
39 | return AnimatorHelper.createZoomInAnim(target);
40 | case ZOOM_ALPHA:
41 | return AnimatorHelper.createZoomAlphaInAnim(target);
42 | case BOTTOM:
43 | return AnimatorHelper.createBottomInAnim(target);
44 | case BOTTOM_ALPHA:
45 | return AnimatorHelper.createBottomAlphaInAnim(target);
46 | case TOP:
47 | return AnimatorHelper.createTopInAnim(target);
48 | case TOP_ALPHA:
49 | return AnimatorHelper.createTopAlphaInAnim(target);
50 | case LEFT:
51 | return AnimatorHelper.createLeftInAnim(target);
52 | case LEFT_ALPHA:
53 | return AnimatorHelper.createLeftAlphaInAnim(target);
54 | case RIGHT:
55 | return AnimatorHelper.createRightInAnim(target);
56 | case RIGHT_ALPHA:
57 | return AnimatorHelper.createRightAlphaInAnim(target);
58 | case BOTTOM_ZOOM_ALPHA:
59 | AnimatorSet set = new AnimatorSet();
60 | Animator a1 = AnimatorHelper.createBottomAlphaInAnim(target, 0.3F);
61 | a1.setInterpolator(new DecelerateInterpolator(2.5f));
62 | Animator a2 = AnimatorHelper.createZoomAlphaInAnim(target, 0.9F);
63 | a2.setInterpolator(new DecelerateInterpolator(1.5f));
64 | set.playTogether(a1, a2);
65 | return set;
66 | }
67 | }
68 |
69 | @Nullable
70 | public Animator createOutAnimator(@NonNull View target) {
71 | switch (this) {
72 | default:
73 | case NONE:
74 | return null;
75 | case ALPHA:
76 | return AnimatorHelper.createAlphaOutAnim(target);
77 | case ZOOM:
78 | return AnimatorHelper.createZoomOutAnim(target);
79 | case ZOOM_ALPHA:
80 | return AnimatorHelper.createZoomAlphaOutAnim(target);
81 | case BOTTOM:
82 | return AnimatorHelper.createBottomOutAnim(target);
83 | case BOTTOM_ALPHA:
84 | return AnimatorHelper.createBottomAlphaOutAnim(target);
85 | case TOP:
86 | return AnimatorHelper.createTopOutAnim(target);
87 | case TOP_ALPHA:
88 | return AnimatorHelper.createTopAlphaOutAnim(target);
89 | case LEFT:
90 | return AnimatorHelper.createLeftOutAnim(target);
91 | case LEFT_ALPHA:
92 | return AnimatorHelper.createLeftAlphaOutAnim(target);
93 | case RIGHT:
94 | return AnimatorHelper.createRightOutAnim(target);
95 | case RIGHT_ALPHA:
96 | return AnimatorHelper.createRightAlphaOutAnim(target);
97 | case BOTTOM_ZOOM_ALPHA:
98 | AnimatorSet set = new AnimatorSet();
99 | Animator a1 = AnimatorHelper.createBottomAlphaOutAnim(target, 0.3F);
100 | a1.setInterpolator(new AccelerateInterpolator(2.5f));
101 | Animator a2 = AnimatorHelper.createZoomAlphaOutAnim(target, 0.9F);
102 | a2.setInterpolator(new AccelerateInterpolator(1.5f));
103 | set.playTogether(a1, a2);
104 | return set;
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/simple/src/main/res/layout/bottom_sheet.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
24 |
25 |
29 |
30 |
35 |
36 |
40 |
41 |
44 |
45 |
48 |
49 |
52 |
53 |
56 |
57 |
60 |
61 |
64 |
65 |
68 |
69 |
72 |
73 |
76 |
77 |
80 |
81 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
95 |
96 |
101 |
102 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/layer-design-cupertino/src/main/res/layout/layer_design_cupertino_notification.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
24 |
25 |
37 |
38 |
51 |
52 |
64 |
65 |
66 |
67 |
80 |
81 |
92 |
93 |
--------------------------------------------------------------------------------
/layer-core/src/main/java/per/goweii/layer/core/listener/WindowCallbackDelegate.java:
--------------------------------------------------------------------------------
1 | package per.goweii.layer.core.listener;
2 |
3 | import android.os.Build;
4 | import android.view.ActionMode;
5 | import android.view.KeyEvent;
6 | import android.view.Menu;
7 | import android.view.MenuItem;
8 | import android.view.MotionEvent;
9 | import android.view.SearchEvent;
10 | import android.view.View;
11 | import android.view.Window;
12 | import android.view.WindowManager;
13 | import android.view.accessibility.AccessibilityEvent;
14 |
15 | import androidx.annotation.NonNull;
16 | import androidx.annotation.Nullable;
17 | import androidx.annotation.RequiresApi;
18 |
19 | public class WindowCallbackDelegate implements Window.Callback {
20 | private final Window.Callback mOldCallback;
21 |
22 | public WindowCallbackDelegate(@NonNull Window.Callback callback) {
23 | mOldCallback = callback;
24 | }
25 |
26 | @Override
27 | public boolean dispatchKeyEvent(KeyEvent event) {
28 | return mOldCallback.dispatchKeyEvent(event);
29 | }
30 |
31 | @Override
32 | public boolean dispatchKeyShortcutEvent(KeyEvent event) {
33 | return mOldCallback.dispatchKeyShortcutEvent(event);
34 | }
35 |
36 | @Override
37 | public boolean dispatchTouchEvent(MotionEvent event) {
38 | return mOldCallback.dispatchTouchEvent(event);
39 | }
40 |
41 | @Override
42 | public boolean dispatchTrackballEvent(MotionEvent event) {
43 | return mOldCallback.dispatchTrackballEvent(event);
44 | }
45 |
46 | @Override
47 | public boolean dispatchGenericMotionEvent(MotionEvent event) {
48 | return mOldCallback.dispatchGenericMotionEvent(event);
49 | }
50 |
51 | @Override
52 | public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
53 | return mOldCallback.dispatchPopulateAccessibilityEvent(event);
54 | }
55 |
56 | @Nullable
57 | @Override
58 | public View onCreatePanelView(int featureId) {
59 | return mOldCallback.onCreatePanelView(featureId);
60 | }
61 |
62 | @Override
63 | public boolean onCreatePanelMenu(int featureId, @NonNull Menu menu) {
64 | return mOldCallback.onCreatePanelMenu(featureId, menu);
65 | }
66 |
67 | @Override
68 | public boolean onPreparePanel(int featureId, @Nullable View view, @NonNull Menu menu) {
69 | return mOldCallback.onPreparePanel(featureId, view, menu);
70 | }
71 |
72 | @Override
73 | public boolean onMenuOpened(int featureId, @NonNull Menu menu) {
74 | return mOldCallback.onMenuOpened(featureId, menu);
75 | }
76 |
77 | @Override
78 | public boolean onMenuItemSelected(int featureId, @NonNull MenuItem item) {
79 | return mOldCallback.onMenuItemSelected(featureId, item);
80 | }
81 |
82 | @Override
83 | public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
84 | mOldCallback.onWindowAttributesChanged(attrs);
85 | }
86 |
87 | @Override
88 | public void onContentChanged() {
89 | mOldCallback.onContentChanged();
90 | }
91 |
92 | @Override
93 | public void onWindowFocusChanged(boolean hasFocus) {
94 | mOldCallback.onWindowFocusChanged(hasFocus);
95 | }
96 |
97 | @Override
98 | public void onAttachedToWindow() {
99 | mOldCallback.onAttachedToWindow();
100 | }
101 |
102 | @Override
103 | public void onDetachedFromWindow() {
104 | mOldCallback.onDetachedFromWindow();
105 | }
106 |
107 | @Override
108 | public void onPanelClosed(int featureId, @NonNull Menu menu) {
109 | mOldCallback.onPanelClosed(featureId, menu);
110 | }
111 |
112 | @Override
113 | public boolean onSearchRequested() {
114 | return mOldCallback.onSearchRequested();
115 | }
116 |
117 | @RequiresApi(api = Build.VERSION_CODES.M)
118 | @Override
119 | public boolean onSearchRequested(SearchEvent searchEvent) {
120 | return mOldCallback.onSearchRequested(searchEvent);
121 | }
122 |
123 | @Nullable
124 | @Override
125 | public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
126 | return mOldCallback.onWindowStartingActionMode(callback);
127 | }
128 |
129 | @RequiresApi(api = Build.VERSION_CODES.M)
130 | @Nullable
131 | @Override
132 | public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
133 | return mOldCallback.onWindowStartingActionMode(callback, type);
134 | }
135 |
136 | @Override
137 | public void onActionModeStarted(ActionMode mode) {
138 | mOldCallback.onActionModeStarted(mode);
139 | }
140 |
141 | @Override
142 | public void onActionModeFinished(ActionMode mode) {
143 | mOldCallback.onActionModeFinished(mode);
144 | }
145 | }
146 |
--------------------------------------------------------------------------------