aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore27
-rw-r--r--.idea/codeStyles/Project.xml136
-rw-r--r--.idea/codeStyles/codeStyleConfig.xml5
-rw-r--r--.idea/copyright/Apache.xml6
-rw-r--r--.idea/encodings.xml4
-rw-r--r--.idea/inspectionProfiles/ktlint.xml7
-rw-r--r--.idea/inspectionProfiles/profiles_settings.xml6
-rw-r--r--.idea/kotlinScripting.xml6
-rw-r--r--.idea/misc.xml44
-rw-r--r--.idea/runConfigurations.xml12
-rw-r--r--.idea/vcs.xml6
-rw-r--r--.travis.yml15
-rw-r--r--README.md22
-rw-r--r--_layouts/default.html45
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt31
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/AboutBinder.kt21
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt66
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt23
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt22
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt41
-rw-r--r--about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt47
-rw-r--r--about/src/main/res/layout/kau_about_section_libraries.xml6
-rw-r--r--about/src/main/res/layout/kau_about_section_main.xml8
-rw-r--r--about/src/main/res/layout/kau_activity_about.xml2
-rw-r--r--about/src/main/res/layout/kau_iitem_library.xml8
-rw-r--r--about/src/main/res/values-da-rDK/strings_about.xml3
-rw-r--r--about/src/main/res/values-de-rDE/strings_about.xml3
-rw-r--r--about/src/main/res/values-es-rES/strings_about.xml3
-rw-r--r--about/src/main/res/values-fr-rFR/strings_about.xml3
-rw-r--r--about/src/main/res/values-gl-rES/strings_about.xml3
-rw-r--r--about/src/main/res/values-hu-rHU/strings_about.xml3
-rw-r--r--about/src/main/res/values-in-rID/strings_about.xml3
-rw-r--r--about/src/main/res/values-it-rIT/strings_about.xml3
-rw-r--r--about/src/main/res/values-ko-rKR/strings_about.xml3
-rw-r--r--about/src/main/res/values-nl-rNL/strings_about.xml6
-rw-r--r--about/src/main/res/values-no-rNO/strings_about.xml3
-rw-r--r--about/src/main/res/values-pl-rPL/strings_about.xml3
-rw-r--r--about/src/main/res/values-pt-rBR/strings_about.xml3
-rw-r--r--about/src/main/res/values-pt-rPT/strings_about.xml6
-rw-r--r--about/src/main/res/values-sr-rSP/strings_about.xml6
-rw-r--r--about/src/main/res/values-sv-rSE/strings_about.xml3
-rw-r--r--about/src/main/res/values-th-rTH/strings_about.xml3
-rw-r--r--about/src/main/res/values-tr-rTR/strings_about.xml3
-rw-r--r--about/src/main/res/values-uk-rUA/strings_about.xml3
-rw-r--r--about/src/main/res/values-vi-rVN/strings_about.xml3
-rw-r--r--about/src/main/res/values-zh-rCN/strings_about.xml3
-rw-r--r--about/src/main/res/values-zh-rTW/strings_about.xml6
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt19
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt25
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt36
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt23
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java13
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt20
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt32
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt32
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt26
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt29
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt35
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt27
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt27
-rw-r--r--adapter/src/main/res/layout/kau_iitem_card.xml8
-rw-r--r--adapter/src/main/res/layout/kau_iitem_header.xml4
-rw-r--r--android-lib.gradle3
-rw-r--r--build.gradle5
-rw-r--r--buildSrc/README.md2
-rw-r--r--buildSrc/build.gradle9
-rw-r--r--buildSrc/build.gradle.kts19
-rw-r--r--buildSrc/settings.gradle.kts0
-rw-r--r--buildSrc/src/main/groovy/ca/allanwang/kau/ChangelogGenerator.groovy76
-rw-r--r--buildSrc/src/main/groovy/ca/allanwang/kau/Dependencies.groovy12
-rw-r--r--buildSrc/src/main/groovy/ca/allanwang/kau/KauPlugin.groovy16
-rw-r--r--buildSrc/src/main/groovy/ca/allanwang/kau/Plugins.groovy17
-rw-r--r--buildSrc/src/main/kotlin/ca/allanwang/kau/ChangelogGenerator.kt105
-rw-r--r--buildSrc/src/main/kotlin/ca/allanwang/kau/Dependencies.kt14
-rw-r--r--buildSrc/src/main/kotlin/ca/allanwang/kau/KauPlugin.kt17
-rw-r--r--buildSrc/src/main/kotlin/ca/allanwang/kau/Plugins.kt16
-rw-r--r--buildSrc/src/main/kotlin/ca/allanwang/kau/Versions.kt80
-rw-r--r--buildSrc/src/main/resources/META-INF/gradle-plugins/ca.allanwang.kau.properties1
-rw-r--r--colorpicker/README.md9
-rw-r--r--colorpicker/build.gradle2
-rw-r--r--colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt60
-rw-r--r--colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPalette.kt171
-rw-r--r--colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt115
-rw-r--r--colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerView.kt319
-rw-r--r--colorpicker/src/main/res/values-da-rDK/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-de-rDE/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-es-rES/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-fr-rFR/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-gl-rES/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-hu-rHU/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-in-rID/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-it-rIT/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-ko-rKR/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-no-rNO/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-pl-rPL/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-pt-rBR/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-sv-rSE/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-th-rTH/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-tr-rTR/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-uk-rUA/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-vi-rVN/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values-zh-rCN/strings_colorpicker.xml5
-rw-r--r--colorpicker/src/main/res/values/dimens.xml3
-rw-r--r--colorpicker/src/main/res/values/strings_colorpicker.xml5
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt28
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/BoundedCardView.kt25
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt48
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/MeasuredImageView.kt24
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt115
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/InkPageIndicator.java4
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/TextSlider.kt50
-rw-r--r--core-ui/src/main/res-public/layout/kau_elastic_recycler_activity.xml16
-rw-r--r--core-ui/src/main/res-public/layout/kau_recycler_detached_background.xml4
-rw-r--r--core-ui/src/main/res-public/layout/kau_recycler_textslider.xml10
-rw-r--r--core/README.md4
-rw-r--r--core/build.gradle16
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt28
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt25
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt50
-rw-r--r--core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt53
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt60
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt47
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt16
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/FlyWeight.kt40
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyContext.kt22
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt17
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/Streams.kt18
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt17
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kotlin/Zip.kt89
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt18
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt50
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt21
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefTransaction.kt29
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/logging/KL.kt26
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt49
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt91
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionResult.kt21
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/permissions/Permissions.kt28
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt27
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt22
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt48
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt23
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt17
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java4
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt28
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt21
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/views/CollapsibleViewDelegate.kt32
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt25
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/views/RippleCanvas.kt49
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt88
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt20
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt66
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/BundleUtils.kt115
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt117
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt19
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt119
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/CoroutineUtils.kt75
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/DrawableUtils.kt21
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/FileUtils.kt18
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/FontUtils.kt23
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/FragmentUtils.kt22
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt26
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt309
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/NetworkUtils.kt20
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/NotificationUtils.kt20
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt17
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/RecyclerUtils.kt19
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt34
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt24
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt98
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt59
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt95
-rw-r--r--core/src/main/res-public/values-da-rDK/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-de-rDE/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-es-rES/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-fr-rFR/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-gl-rES/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-hu-rHU/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-in-rID/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-it-rIT/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-ko-rKR/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-nl-rNL/strings_commons.xml71
-rw-r--r--core/src/main/res-public/values-no-rNO/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-pl-rPL/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-pt-rBR/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-pt-rPT/strings_commons.xml71
-rw-r--r--core/src/main/res-public/values-sr-rSP/strings_commons.xml75
-rw-r--r--core/src/main/res-public/values-sv-rSE/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-th-rTH/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-tr-rTR/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-uk-rUA/strings_commons.xml28
-rw-r--r--core/src/main/res-public/values-vi-rVN/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-zh-rCN/strings_commons.xml4
-rw-r--r--core/src/main/res-public/values-zh-rTW/strings_commons.xml67
-rw-r--r--core/src/main/res/layout/kau_changelog_content.xml4
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/kotlin/CoroutineTest.kt73
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/kotlin/DebounceTest.kt18
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/kotlin/LazyResettableTest.kt18
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/kotlin/StreamsTest.kt18
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/kotlin/ZipTest.kt70
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt35
-rw-r--r--crowdin.yaml21
-rw-r--r--crowdin.yml9
-rw-r--r--docs/Changelog.md21
-rw-r--r--docs/Migration.md33
-rw-r--r--favicon/android-chrome-192x192.pngbin0 -> 6910 bytes
-rw-r--r--favicon/android-chrome-512x512.pngbin0 -> 14362 bytes
-rw-r--r--favicon/apple-touch-icon.pngbin0 -> 6510 bytes
-rw-r--r--favicon/browserconfig.xml9
-rw-r--r--favicon/favicon-16x16.pngbin0 -> 982 bytes
-rw-r--r--favicon/favicon-32x32.pngbin0 -> 1347 bytes
-rw-r--r--favicon/favicon.icobin0 -> 15086 bytes
-rw-r--r--favicon/mstile-150x150.pngbin0 -> 4442 bytes
-rw-r--r--favicon/safari-pinned-tab.svg17
-rw-r--r--favicon/site.webmanifest19
-rw-r--r--files/translation_migration.sh5
-rw-r--r--gradle.properties2
-rw-r--r--gradle/wrapper/gradle-wrapper.properties3
-rw-r--r--kpref-activity/build.gradle2
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KClick.kt17
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt85
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt128
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefItemActions.kt11
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefCheckbox.kt20
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt65
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefHeader.kt18
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemBase.kt34
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt66
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt22
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSeekbar.kt27
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt24
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt29
-rw-r--r--kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt32
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_activity.xml8
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_checkbox.xml2
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_core.xml12
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_header.xml2
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_seekbar.xml2
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_seekbar_text.xml2
-rw-r--r--kpref-activity/src/main/res/layout/kau_pref_text.xml2
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/BlurredImageView.kt29
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt17
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaActionItem.kt47
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt81
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt71
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt68
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityBase.kt37
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityOverlayBase.kt23
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt25
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt80
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaType.kt47
-rw-r--r--mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaUtils.kt33
-rw-r--r--mediapicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml2
-rw-r--r--mediapicker/src/main/res/layout/kau_activity_image_picker.xml16
-rw-r--r--mediapicker/src/main/res/values-da-rDK/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-de-rDE/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-es-rES/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-fr-rFR/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-gl-rES/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-hu-rHU/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-in-rID/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-it-rIT/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-ko-rKR/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-nl-rNL/strings_mediapicker.xml11
-rw-r--r--mediapicker/src/main/res/values-no-rNO/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-pl-rPL/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-pt-rBR/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-pt-rPT/strings_mediapicker.xml11
-rw-r--r--mediapicker/src/main/res/values-sr-rSP/strings_mediapicker.xml11
-rw-r--r--mediapicker/src/main/res/values-sv-rSE/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-th-rTH/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-tr-rTR/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-uk-rUA/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-vi-rVN/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-zh-rCN/strings_mediapicker.xml3
-rw-r--r--mediapicker/src/main/res/values-zh-rTW/strings_mediapicker.xml11
-rw-r--r--sample/build.gradle31
-rw-r--r--sample/src/androidTest/kotlin/ca/allanwang/kau/sample/ColorPickerTest.kt54
-rw-r--r--sample/src/androidTest/kotlin/ca/allanwang/kau/sample/KPrefViewTest.kt129
-rw-r--r--sample/src/androidTest/kotlin/ca/allanwang/kau/sample/utils/EspressoUtils.kt37
-rw-r--r--sample/src/main/AndroidManifest.xml2
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/AboutActivity.kt17
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/AdapterActivity.kt23
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt30
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt20
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt170
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/MediaPicker.kt30
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/PermissionCheckbox.kt21
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/SampleApp.kt17
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/SwipeActivity.kt35
-rw-r--r--sample/src/main/res/layout/activity_swipe.xml6
-rw-r--r--sample/src/main/res/xml/kau_changelog.xml31
-rw-r--r--searchview/README.md2
-rw-r--r--searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt51
-rw-r--r--searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt133
-rw-r--r--searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt18
-rw-r--r--searchview/src/main/res/layout/kau_search_iitem.xml4
-rw-r--r--searchview/src/main/res/layout/kau_search_view.xml4
-rw-r--r--spotless.gradle11
-rw-r--r--spotless.license.kt15
300 files changed, 5480 insertions, 2545 deletions
diff --git a/.gitignore b/.gitignore
index d741202..ef20a58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,3 @@
-*.iml
-/.idea
.gradle
/crowdin.properties
/local.properties
@@ -7,4 +5,27 @@
/build
/captures
.externalNativeBuild
-**/public.xml \ No newline at end of file
+**/public.xml
+
+# Intellij
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+*.iml
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+.idea/**/contentModel.xml
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+.idea/**/gradle.xml
+.idea/**/libraries
+.idea/**/assetWizardSettings.xml
+.idea/**/caches
+.idea/modules.xml
+.idea/modules \ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..be6976d
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,136 @@
+<component name="ProjectCodeStyleConfiguration">
+ <code_scheme name="Project" version="173">
+ <AndroidXmlCodeStyleSettings>
+ <option name="USE_CUSTOM_SETTINGS" value="true" />
+ </AndroidXmlCodeStyleSettings>
+ <JetCodeStyleSettings>
+ <option name="PACKAGES_TO_USE_STAR_IMPORTS">
+ <value>
+ <package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
+ </value>
+ </option>
+ <option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
+ <option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
+ <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+ </JetCodeStyleSettings>
+ <XML>
+ <option name="XML_KEEP_LINE_BREAKS" value="false" />
+ <option name="XML_ALIGN_ATTRIBUTES" value="false" />
+ <option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
+ </XML>
+ <codeStyleSettings language="XML">
+ <option name="FORCE_REARRANGE_MODE" value="1" />
+ <indentOptions>
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
+ </indentOptions>
+ <arrangement>
+ <rules>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>xmlns:android</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>xmlns:.*</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:id</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*:name</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>name</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>style</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*</NAME>
+ <XML_NAMESPACE>^$</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*</NAME>
+ <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>ANDROID_ATTRIBUTE_ORDER</order>
+ </rule>
+ </section>
+ <section>
+ <rule>
+ <match>
+ <AND>
+ <NAME>.*</NAME>
+ <XML_NAMESPACE>.*</XML_NAMESPACE>
+ </AND>
+ </match>
+ <order>BY_NAME</order>
+ </rule>
+ </section>
+ </rules>
+ </arrangement>
+ </codeStyleSettings>
+ <codeStyleSettings language="kotlin">
+ <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+ <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
+ <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
+ <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
+ <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+ <indentOptions>
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
+ </indentOptions>
+ </codeStyleSettings>
+ </code_scheme>
+</component> \ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..0f7bc51
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+ <state>
+ <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+ </state>
+</component>
diff --git a/.idea/copyright/Apache.xml b/.idea/copyright/Apache.xml
new file mode 100644
index 0000000..124b434
--- /dev/null
+++ b/.idea/copyright/Apache.xml
@@ -0,0 +1,6 @@
+<component name="CopyrightManager">
+ <copyright>
+ <option name="notice" value="/*&#10; * Copyright &amp;#36;year Allan Wang&#10; *&#10; * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10; * you may not use this file except in compliance with the License.&#10; * You may obtain a copy of the License at&#10; *&#10; * http://www.apache.org/licenses/LICENSE-2.0&#10; *&#10; * Unless required by applicable law or agreed to in writing, software&#10; * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10; * See the License for the specific language governing permissions and&#10; * limitations under the License.&#10; */" />
+ <option name="myName" value="Apache" />
+ </copyright>
+</component> \ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Encoding" addBOMForNewFiles="with NO BOM" />
+</project> \ No newline at end of file
diff --git a/.idea/inspectionProfiles/ktlint.xml b/.idea/inspectionProfiles/ktlint.xml
new file mode 100644
index 0000000..7d04a74
--- /dev/null
+++ b/.idea/inspectionProfiles/ktlint.xml
@@ -0,0 +1,7 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="ktlint" />
+ <inspection_tool class="KotlinUnusedImport" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="RedundantSemicolon" enabled="true" level="ERROR" enabled_by_default="true" />
+ </profile>
+</component>
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..64580d1
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="PROJECT_PROFILE" value="ktlint" />
+ <version value="1.0" />
+ </settings>
+</component>
diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml
new file mode 100644
index 0000000..a6fe551
--- /dev/null
+++ b/.idea/kotlinScripting.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="KotlinScriptingSettings">
+ <option name="isAutoReloadEnabled" value="true" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..51fa3e5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="NullableNotNullManager">
+ <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
+ <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
+ <option name="myNullables">
+ <value>
+ <list size="10">
+ <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
+ <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
+ <item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
+ <item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+ <item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+ <item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
+ <item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
+ <item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
+ <item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
+ <item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
+ </list>
+ </value>
+ </option>
+ <option name="myNotNulls">
+ <value>
+ <list size="9">
+ <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
+ <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
+ <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
+ <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+ <item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
+ <item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
+ <item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
+ <item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
+ <item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
+ </list>
+ </value>
+ </option>
+ </component>
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/build/classes" />
+ </component>
+ <component name="ProjectType">
+ <option name="id" value="Android" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="RunConfigurationProducerService">
+ <option name="ignoredProducers">
+ <set>
+ <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+ <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+ <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+ </set>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="Git" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 3dd7449..7bd509f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,22 +4,22 @@ jdk:
env:
global:
- ANDROID_API=28
- - EMULATOR_API=24
+ - EMULATOR_API=19
- ANDROID_BUILD_TOOLS=28.0.3
git:
depth: 500
android:
components:
- tools
-# - android-$EMULATOR_API
- platform-tools
- tools
- build-tools-$ANDROID_BUILD_TOOLS
- android-$ANDROID_API
- - extra-android-support
+# - android-$EMULATOR_API
- extra-android-m2repository
- extra-google-m2repository
-# - sys-img-armeabi-v7a-android-$EMULATOR_API
+# - sys-img-armeabi-v7a-addon-google_apis-google-$ANDROID_API_LEVEL
+# - sys-img-armeabi-v7a-addon-google_apis-google-$EMULATOR_API_LEVEL
licenses:
- ".+"
#before_script:
@@ -27,8 +27,11 @@ android:
#- echo "y" | android update sdk -a --no-ui --filter sys-img-armeabi-v7a-android-$EMULATOR_API
#- android list targets | grep -E '^id:' | awk -F '"' '{$1=""; print $2}' # list all targets
#- echo no | android create avd --force -n test -t android-$EMULATOR_API --abi armeabi-v7a
-#- emulator -avd test -no-skin -no-window &
+#- emulator -avd test -skin -no-audio -no-window &
#- android-wait-for-emulator
+#- adb shell settings put global window_animation_scale 0 &
+#- adb shell settings put global transition_animation_scale 0 &
+#- adb shell settings put global animator_duration_scale 0 &
#- adb shell input keyevent 82 &
script:
- chmod +x gradlew
@@ -52,7 +55,7 @@ cache:
- $HOME/.gradle/wrapper/
- $HOME/.android/build-cache
before_install:
-- yes | sdkmanager "platforms;android-28"
+- yes | sdkmanager "platforms;android-$ANDROID_API"
- openssl aes-256-cbc -K $encrypted_12e8842891a3_key -iv $encrypted_12e8842891a3_iv
-in files/kau.tar.enc -out kau.tar -d
- tar xvf kau.tar \ No newline at end of file
diff --git a/README.md b/README.md
index edf6878..0293545 100644
--- a/README.md
+++ b/README.md
@@ -35,8 +35,6 @@ allprojects {
}
```
-(If you are using gradle < 4.0, use `maven { url "https://maven.google.com" }` instead of `google()`)
-
And add the following dependencies (You can use a specific version, commit, or -SNAPSHOT):
Note that only `core` is required if you want the basic features.
@@ -71,8 +69,6 @@ buildscript {
```
-(If you are using gradle < 4.0, use `compile` instead of `implementation`)
-
-----------
# Submodules
@@ -99,10 +95,9 @@ This means that you'll need to explicitly include each submodule you'd like to u
* [Extension Functions](core#extension-functions)
* [Lazy Resettable](core#lazy-resettable)
* Includes
-[`AppCompat`](https://developer.android.com/topic/libraries/support-library/index.html),
+[`AndroidX Components`](https://developer.android.com/topic/libraries/support-library/index.html),
[`Material Dialogs (core)`](https://github.com/afollestad/material-dialogs),
[`Iconics`](https://github.com/mikepenz/Android-Iconics),
-[`Anko`](https://github.com/Kotlin/anko),
[`Kotlin stdlib`](https://kotlinlang.org/api/latest/jvm/stdlib/)
## [Core UI](core-ui#readme)
@@ -148,7 +143,6 @@ This means that you'll need to explicitly include each submodule you'd like to u
![About Activity Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_about_activity.gif)
![Ink Indicator Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_ink_indicator.gif)
![Color Picker Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_color_picker.gif)
-![Color Picker Custom Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_color_picker_custom.gif)
![KPref Items Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_kpref_items.gif)
![SearchView Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_search_view.gif)
![Swipe Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_swipe.gif)
@@ -172,7 +166,8 @@ Special thanks to the following awesome people for translating significant porti
| Language | Contributors |
|----------|--------------|
-| Chinese (Simplified) | |
+| Chinese (Simplified) | [Alcatelia](https://crowdin.com/profile/Alcatelia) |
+| Chinese (Traditional) | [yipinghuang](https://crowdin.com/profile/yipinghuang) &bull; [Su, Jun-Ming](https://crowdin.com/profile/sujunmin) &bull; [Wei](https://crowdin.com/profile/wei4green) |
| French | [Vincent Kulak](https://github.com/VonOx) &bull; [Jean-Philippe Gravel](https://crowdin.com/profile/wokija) |
| Galician | [Xesús M. Mosquera](https://twitter.com/xesusmmc?lang=en) |
| German | [Bushido1992](https://forum.xda-developers.com/member.php?u=5179246) &bull; [Marcel Soehnchen](https://crowdin.com/profile/msoehnchen) &bull; [3LD0mi HA](https://forum.xda-developers.com/member.php?u=5860523) |
@@ -180,11 +175,14 @@ Special thanks to the following awesome people for translating significant porti
| Italian | [Bonnee](https://github.com/Bonnee) |
| Korean | [잇스테이크](https://crowdin.com/profile/bexco2010) |
| Norwegian | |
-| Polish | |
-| Portuguese | [TheusKhan](https://crowdin.com/profile/TheusKhan) |
+| Polish | [pantinPL](https://crowdin.com/profile/pantinPL) |
+| Portuguese | [Sérgio Marques](https://crowdin.com/profile/smarquespt) &bull; [Miguel Dos Reis](https://crowdin.com/profile/siersod) |
+| Portuguese (Brazilian) | [TheusKhan](https://crowdin.com/profile/TheusKhan) |
+| Serbian | [Nikola Radmanović](https://crowdin.com/profile/nikoladradmanovic) |
| Spanish | [Jahir Fiquitiva](https://jahirfiquitiva.me/) &bull; [Nefi Salazar](https://plus.google.com/u/0/105547968033551087431)|
-| Thai | |
-| Turkish | |
+| Thai | [Thanawat Hanthong](https://crowdin.com/profile/peet6015) |
+| Turkish | [zuma17](https://crowdin.com/profile/zuma17) |
| Vietnamese | [Alienz](https://crowdin.com/profile/alienyd) |
The full activity stream for the translations can be found [here](https://crowdin.com/project/kotlin-android-utils/activity_stream)
+
diff --git a/_layouts/default.html b/_layouts/default.html
index 6868eca..c87a7b7 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,22 +1,34 @@
-<!doctype html>
-<!--https://help.github.com/articles/repository-metadata-on-github-pages/#available-repository-metadata-->
-<html>
+<!--See https://github.com/pages-themes/minimal/blob/master/_layouts/default.html-->
+<!DOCTYPE html>
+<html lang="{{ site.lang | default: "en-US" }}">
<head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="chrome=1">
- <title>{{ site.title | default: site.github.repository_name }} by {{ site.github.owner_name }}</title>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="stylesheet" href="{{ '/assets/css/style.css?v=' | append: site.github.build_revision | relative_url }}">
- <meta name="viewport" content="width=device-width">
+ {% seo %}
+ <link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">
+
+ <!--Begin favicon-->
+ <link rel="apple-touch-icon" sizes="180x180" href="{{ '/favicon/apple-touch-icon.png' | relative_url }}">
+ <link rel="icon" type="image/png" sizes="32x32" href="{{ '/favicon/favicon-32x32.png' | relative_url }}">
+ <link rel="icon" type="image/png" sizes="16x16" href="{{ '/favicon/favicon-16x16.png' | relative_url }}">
+ <link rel="manifest" href="{{ '/favicon/site.webmanifest' | relative_url }}">
+ <link rel="mask-icon" href="{{ '/favicon/safari-pinned-tab.svg' | relative_url }}" color="#3b5998">
+ <link rel="shortcut icon" href="{{ '/favicon/favicon.ico' | relative_url }}">
+ <meta name="msapplication-TileColor" content="#da532c">
+ <meta name="msapplication-config" content="{{ '/favicon/browserconfig.xml' | relative_url }}">
+ <meta name="theme-color" content="#ffffff">
+ <!--End favicon-->
<!--[if lt IE 9]>
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
<a href="{{ site.github.url }}"><img src="https://cdn.rawgit.com/AllanWang/KAU/master/files/images/logo.svg" alt="KAU" width="30%"/></a>
- <!--<h1><a href="{{ site.github.url }}">{{ site.title | default: site.github.repository_name }}</a></h1>-->
+
<p>{{ site.description | default: site.github.project_tagline }}</p>
{% if page.url == '/core/' or
@@ -60,18 +72,5 @@
</footer>
</div>
<script src="{{ '/assets/js/scale.fix.js' | relative_url }}"></script>
-
-
-{% if site.google_analytics %}
-<script>
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
- })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
-
- ga('create', '{{ site.google_analytics }}', 'auto');
- ga('send', 'pageview');
- </script>
-{% endif %}
</body>
</html> \ No newline at end of file
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
index f4ee4c5..79077c5 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt
@@ -1,13 +1,28 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
import android.graphics.drawable.Drawable
import android.os.Bundle
-import android.support.v4.view.PagerAdapter
-import android.support.v4.view.ViewPager
import android.transition.TransitionInflater
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
import ca.allanwang.kau.adapters.FastItemThemedAdapter
import ca.allanwang.kau.adapters.ThemableIItemColors
import ca.allanwang.kau.adapters.ThemableIItemColorsDelegate
@@ -32,7 +47,8 @@ import kotlinx.android.synthetic.main.kau_activity_about.*
* Note that for the auto detection to work, the R fields must be excluded from Proguard
* Manual lib listings and other extra modifications can be done so by overriding the open functions
*/
-abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilder: Configs.() -> Unit = {}) : KauBaseActivity(), ViewPager.OnPageChangeListener {
+abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilder: Configs.() -> Unit = {}) :
+ KauBaseActivity(), ViewPager.OnPageChangeListener {
val currentPage: Int
get() = about_pager.currentItem
@@ -73,7 +89,7 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde
about_draggable_frame.addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(this) {
override fun onDragDismissed() {
window.returnTransition = TransitionInflater.from(this@AboutActivityBase)
- .inflateTransition(if (about_draggable_frame.translationY > 0) R.transition.kau_exit_slide_bottom else R.transition.kau_exit_slide_top)
+ .inflateTransition(if (about_draggable_frame.translationY > 0) R.transition.kau_exit_slide_bottom else R.transition.kau_exit_slide_top)
panels[currentPage].recycler?.stopScroll()
finishAfterTransition()
}
@@ -113,7 +129,6 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde
* Feel free to add your own items to the adapter in here
*/
open fun postInflateMainPage(adapter: FastItemThemedAdapter<IItem<*, *>>) {
-
}
/**
@@ -123,7 +138,7 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde
* This is fetched asynchronously and you may override it to customize the list
*/
open fun getLibraries(libs: Libs): List<Library> =
- libs.prepareLibraries(this, null, null, true, true, true)!!
+ libs.prepareLibraries(this, null, null, true, true, true)!!
/*
* -------------------------------------------------------------------
@@ -156,7 +171,7 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde
*/
private fun getPage(position: Int, parent: ViewGroup): View {
if (views[position] == null) views[position] = panels[position]
- .inflatePage(this@AboutActivityBase, parent, position)
+ .inflatePage(this@AboutActivityBase, parent, position)
return views[position]!!
}
}
@@ -174,4 +189,4 @@ abstract class AboutActivityBase(val rClass: Class<*>?, private val configBuilde
AnimHolder.decelerateInterpolator.invalidate() //clear the reference to the interpolators we've used
super.onDestroy()
}
-} \ No newline at end of file
+}
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutBinder.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutBinder.kt
index c99f7c2..1183113 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/AboutBinder.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutBinder.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
import android.content.Context
@@ -12,6 +27,6 @@ import ca.allanwang.kau.utils.withSceneTransitionAnimation
* About activity launcher
*/
inline fun <reified T : AboutActivityBase> Context.kauLaunchAbout() =
- startActivity<T>(bundleBuilder = {
- withSceneTransitionAnimation(this@kauLaunchAbout)
- }) \ No newline at end of file
+ startActivity<T>(bundleBuilder = {
+ withSceneTransitionAnimation(this@kauLaunchAbout)
+ })
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt
index b6ea16b..924a771 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutPanelDelegate.kt
@@ -1,20 +1,43 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
-import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapters.FastItemThemedAdapter
import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
import ca.allanwang.kau.animators.KauAnimator
import ca.allanwang.kau.animators.NoAnimatorChange
import ca.allanwang.kau.iitems.HeaderIItem
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.AnimHolder
+import ca.allanwang.kau.utils.KAU_BOTTOM
+import ca.allanwang.kau.utils.colorToForeground
+import ca.allanwang.kau.utils.drawable
+import ca.allanwang.kau.utils.fullLinearRecycler
+import ca.allanwang.kau.utils.postDelayed
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.withMarginDecoration
import ca.allanwang.kau.xml.kauParseFaq
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.fastadapter.IItem
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Created by Allan Wang on 2017-08-02.
@@ -76,8 +99,8 @@ abstract class AboutPanelRecycler : AboutPanelContract {
override fun onInflatingPage(activity: AboutActivityBase, recycler: RecyclerView, position: Int) {
recycler.adapter = adapter
recycler.itemAnimator = KauAnimator(
- addAnimator = FadeScaleAnimatorAdd(scaleFactor = 0.7f, itemDelayFactor = 0.2f),
- changeAnimator = NoAnimatorChange()
+ addAnimator = FadeScaleAnimatorAdd(scaleFactor = 0.7f, itemDelayFactor = 0.2f),
+ changeAnimator = NoAnimatorChange()
).apply { addDuration = 300; interpolator = AnimHolder.decelerateInterpolator(recycler.context) }
}
@@ -136,7 +159,6 @@ open class AboutPanelMain : AboutPanelRecycler() {
}
override fun addItemsImpl(activity: AboutActivityBase, position: Int) {}
-
}
/**
@@ -153,12 +175,16 @@ open class AboutPanelLibs : AboutPanelRecycler() {
}
override fun loadItems(activity: AboutActivityBase, position: Int) {
- doAsync {
- with(activity) {
- items = getLibraries(if (rClass == null) Libs(activity) else Libs(this, Libs.toStringArray(rClass.fields)))
- .map(::LibraryIItem)
+ with(activity) {
+ launch {
+ items = withContext(Dispatchers.Default) {
+ getLibraries(
+ if (rClass == null) Libs(activity)
+ else Libs(activity, Libs.toStringArray(rClass.fields))
+ ).map(::LibraryIItem)
+ }
if (pageStatus[position] == 1)
- uiThread { addItems(activity, position) }
+ addItems(activity, position)
}
}
}
@@ -166,7 +192,7 @@ open class AboutPanelLibs : AboutPanelRecycler() {
override fun addItemsImpl(activity: AboutActivityBase, position: Int) {
with(activity.configs) {
adapter.add(HeaderIItem(text = libPageTitle, textRes = libPageTitleRes))
- .add(items)
+ .add(items)
}
}
}
@@ -180,8 +206,13 @@ open class AboutPanelFaqs : AboutPanelRecycler() {
override fun loadItems(activity: AboutActivityBase, position: Int) {
with(activity) {
- kauParseFaq(configs.faqXmlRes, configs.faqParseNewLine) {
- items = it.map(::FaqIItem)
+ launch {
+ items = withContext(Dispatchers.IO) {
+ kauParseFaq(
+ configs.faqXmlRes,
+ configs.faqParseNewLine
+ )
+ }.map(::FaqIItem)
if (pageStatus[position] == 1)
addItems(activity, position)
}
@@ -191,8 +222,7 @@ open class AboutPanelFaqs : AboutPanelRecycler() {
override fun addItemsImpl(activity: AboutActivityBase, position: Int) {
with(activity.configs) {
adapter.add(HeaderIItem(text = faqPageTitle, textRes = faqPageTitleRes))
- .add(items)
+ .add(items)
}
}
-
-} \ No newline at end of file
+}
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt b/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt
index f010321..c9b8b93 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/CollapsibleTextView.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
import android.content.Context
import android.content.res.Configuration
-import android.support.v7.widget.AppCompatTextView
import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
import ca.allanwang.kau.ui.views.CollapsibleView
import ca.allanwang.kau.ui.views.CollapsibleViewDelegate
@@ -12,7 +27,9 @@ import ca.allanwang.kau.ui.views.CollapsibleViewDelegate
*
*/
class CollapsibleTextView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr), CollapsibleView by CollapsibleViewDelegate() {
init {
@@ -29,4 +46,4 @@ class CollapsibleTextView @JvmOverloads constructor(
val result = getCollapsibleDimension()
setMeasuredDimension(result.first, result.second)
}
-} \ No newline at end of file
+}
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt
index 37c13d8..b51c9c8 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
-import android.support.v7.widget.RecyclerView
import android.view.View
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.iitems.KauIItem
@@ -13,7 +28,7 @@ import ca.allanwang.kau.ui.views.CutoutView
* Just a cutout item with some defaults in [R.layout.kau_iitem_cutout]
*/
class CutoutIItem(val config: CutoutView.() -> Unit = {}) : KauIItem<CutoutIItem, CutoutIItem.ViewHolder>(
- R.layout.kau_iitem_cutout, ::ViewHolder, R.id.kau_item_cutout
+ R.layout.kau_iitem_cutout, ::ViewHolder, R.id.kau_item_cutout
), ThemableIItem by ThemableIItemDelegate() {
override fun isSelectable(): Boolean = false
@@ -37,5 +52,4 @@ class CutoutIItem(val config: CutoutView.() -> Unit = {}) : KauIItem<CutoutIItem
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
val cutout: CutoutView = v.findViewById(R.id.kau_cutout)
}
-
-} \ No newline at end of file
+}
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt
index 5cf046e..755ac81 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/FaqIItem.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
import android.annotation.SuppressLint
-import android.support.v7.widget.RecyclerView
import android.text.method.LinkMovementMethod
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.iitems.KauIItem
@@ -22,23 +37,24 @@ import com.mikepenz.fastadapter.listeners.ClickEventHook
* Created by Allan Wang on 2017-08-02.
*/
class FaqIItem(val content: FaqItem) : KauIItem<LibraryIItem, FaqIItem.ViewHolder>(
- R.layout.kau_iitem_faq, ::ViewHolder, R.id.kau_item_faq
+ R.layout.kau_iitem_faq, ::ViewHolder, R.id.kau_item_faq
), ThemableIItem by ThemableIItemDelegate() {
companion object {
fun bindEvents(fastAdapter: FastAdapter<IItem<*, *>>) {
fastAdapter.withSelectable(false)
- .withEventHook(object : ClickEventHook<IItem<*, *>>() {
-
- override fun onBind(viewHolder: RecyclerView.ViewHolder): View? = (viewHolder as? ViewHolder)?.questionContainer
+ .withEventHook(object : ClickEventHook<IItem<*, *>>() {
- override fun onClick(v: View, position: Int, adapter: FastAdapter<IItem<*, *>>, item: IItem<*, *>) {
- if (item !is FaqIItem) return
- item.isExpanded = !item.isExpanded
- v.parentViewGroup.findViewById<CollapsibleTextView>(R.id.faq_item_answer).setExpanded(item.isExpanded)
- }
+ override fun onBind(viewHolder: RecyclerView.ViewHolder): View? =
+ (viewHolder as? ViewHolder)?.questionContainer
- })
+ override fun onClick(v: View, position: Int, adapter: FastAdapter<IItem<*, *>>, item: IItem<*, *>) {
+ if (item !is FaqIItem) return
+ item.isExpanded = !item.isExpanded
+ v.parentViewGroup.findViewById<CollapsibleTextView>(R.id.faq_item_answer)
+ .setExpanded(item.isExpanded)
+ }
+ })
}
}
@@ -83,5 +99,4 @@ class FaqIItem(val content: FaqItem) : KauIItem<LibraryIItem, FaqIItem.ViewHolde
answer.movementMethod = LinkMovementMethod.getInstance()
}
}
-
-} \ No newline at end of file
+}
diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt
index 2749c28..33aac09 100644
--- a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt
+++ b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.about
import android.os.Build
-import android.support.v7.widget.CardView
-import android.support.v7.widget.RecyclerView
import android.text.Html
import android.view.View
import android.widget.TextView
+import androidx.cardview.widget.CardView
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.iitems.KauIItem
@@ -20,21 +35,21 @@ import com.mikepenz.fastadapter.IItem
* Created by Allan Wang on 2017-06-27.
*/
class LibraryIItem(val lib: Library) : KauIItem<LibraryIItem, LibraryIItem.ViewHolder>(
- R.layout.kau_iitem_library, ::ViewHolder, R.id.kau_item_library
+ R.layout.kau_iitem_library, ::ViewHolder, R.id.kau_item_library
), ThemableIItem by ThemableIItemDelegate() {
companion object {
fun bindEvents(fastAdapter: FastAdapter<IItem<*, *>>) {
fastAdapter.withSelectable(false)
- .withOnClickListener { v, _, item, _ ->
- if (item !is LibraryIItem)
- false
- else
- with(item.lib) {
- v!!.context.startLink(libraryWebsite, repositoryLink, authorWebsite)
- true
- }
- }
+ .withOnClickListener { v, _, item, _ ->
+ if (item !is LibraryIItem)
+ false
+ else
+ with(item.lib) {
+ v!!.context.startLink(libraryWebsite, repositoryLink, authorWebsite)
+ true
+ }
+ }
}
}
@@ -48,7 +63,10 @@ class LibraryIItem(val lib: Library) : KauIItem<LibraryIItem, LibraryIItem.ViewH
@Suppress("DEPRECATION")
description.text = when {
lib.libraryDescription.isBlank() -> lib.libraryDescription
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> Html.fromHtml(lib.libraryDescription, Html.FROM_HTML_MODE_LEGACY)
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> Html.fromHtml(
+ lib.libraryDescription,
+ Html.FROM_HTML_MODE_LEGACY
+ )
else -> Html.fromHtml(lib.libraryDescription)
}
bottomDivider.gone()
@@ -90,5 +108,4 @@ class LibraryIItem(val lib: Library) : KauIItem<LibraryIItem, LibraryIItem.ViewH
val divider: View = v.findViewById(R.id.lib_item_top_divider)
val bottomDivider: View = v.findViewById(R.id.lib_item_bottom_divider)
}
-
-} \ No newline at end of file
+}
diff --git a/about/src/main/res/layout/kau_about_section_libraries.xml b/about/src/main/res/layout/kau_about_section_libraries.xml
index c14225e..60d1312 100644
--- a/about/src/main/res/layout/kau_about_section_libraries.xml
+++ b/about/src/main/res/layout/kau_about_section_libraries.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/about_library_container"
android:layout_width="match_parent"
@@ -15,7 +15,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/about_library_recycler"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -24,4 +24,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/about_library_title" />
-</android.support.constraint.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/about/src/main/res/layout/kau_about_section_main.xml b/about/src/main/res/layout/kau_about_section_main.xml
index e7b83a0..7ea0415 100644
--- a/about/src/main/res/layout/kau_about_section_main.xml
+++ b/about/src/main/res/layout/kau_about_section_main.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:showIn="@layout/kau_activity_about">
- <android.support.constraint.ConstraintLayout
+ <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/about_main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -41,6 +41,6 @@
</FrameLayout>
- </android.support.constraint.ConstraintLayout>
+ </androidx.constraintlayout.widget.ConstraintLayout>
-</android.support.v4.widget.NestedScrollView>
+</androidx.core.widget.NestedScrollView>
diff --git a/about/src/main/res/layout/kau_activity_about.xml b/about/src/main/res/layout/kau_activity_about.xml
index 3d1f9ab..626adda 100644
--- a/about/src/main/res/layout/kau_activity_about.xml
+++ b/about/src/main/res/layout/kau_activity_about.xml
@@ -9,7 +9,7 @@
app:dragDismissScale="0.95"
tools:context=".ui.about.AboutActivityBase">
- <android.support.v4.view.ViewPager
+ <androidx.viewpager.widget.ViewPager
android:id="@+id/about_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/about/src/main/res/layout/kau_iitem_library.xml b/about/src/main/res/layout/kau_iitem_library.xml
index 47b4e01..4dd5155 100644
--- a/about/src/main/res/layout/kau_iitem_library.xml
+++ b/about/src/main/res/layout/kau_iitem_library.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lib_item_card"
@@ -8,7 +8,7 @@
android:clickable="true"
android:focusable="true">
- <android.support.constraint.ConstraintLayout
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/kau_padding_normal"
@@ -112,6 +112,6 @@
app:layout_constraintTop_toBottomOf="@id/lib_item_bottom_divider"
tools:text="License" />
- </android.support.constraint.ConstraintLayout>
+ </androidx.constraintlayout.widget.ConstraintLayout>
-</android.support.v7.widget.CardView> \ No newline at end of file
+</androidx.cardview.widget.CardView> \ No newline at end of file
diff --git a/about/src/main/res/values-da-rDK/strings_about.xml b/about/src/main/res/values-da-rDK/strings_about.xml
index 837d419..87fc65b 100644
--- a/about/src/main/res/values-da-rDK/strings_about.xml
+++ b/about/src/main/res/values-da-rDK/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Denne app vil ikke være mulig uden de følgende fantastiske biblioteker.</string>
<string name="kau_about_faq_intro">Ofte stillede spørgsmål</string>
diff --git a/about/src/main/res/values-de-rDE/strings_about.xml b/about/src/main/res/values-de-rDE/strings_about.xml
index 5d7bc28..69df4d9 100644
--- a/about/src/main/res/values-de-rDE/strings_about.xml
+++ b/about/src/main/res/values-de-rDE/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Diese App wäre nicht möglich ohne die folgenden großartigen Bibliotheken.</string>
<string name="kau_about_faq_intro">Häufige Fragen / FAQ</string>
diff --git a/about/src/main/res/values-es-rES/strings_about.xml b/about/src/main/res/values-es-rES/strings_about.xml
index 3fb0bed..743bc4d 100644
--- a/about/src/main/res/values-es-rES/strings_about.xml
+++ b/about/src/main/res/values-es-rES/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Esta aplicación no sería posible sin las siguientes geniales librerías.</string>
<string name="kau_about_faq_intro">Preguntas Frecuentes</string>
diff --git a/about/src/main/res/values-fr-rFR/strings_about.xml b/about/src/main/res/values-fr-rFR/strings_about.xml
index 91db02c..0d50f86 100644
--- a/about/src/main/res/values-fr-rFR/strings_about.xml
+++ b/about/src/main/res/values-fr-rFR/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Ce soft ne serait pas possible sans ces super bibliothèques.</string>
<string name="kau_about_faq_intro">FAQ</string>
diff --git a/about/src/main/res/values-gl-rES/strings_about.xml b/about/src/main/res/values-gl-rES/strings_about.xml
index fe64f7f..f0da61f 100644
--- a/about/src/main/res/values-gl-rES/strings_about.xml
+++ b/about/src/main/res/values-gl-rES/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Esta aplicación non sería posible sen a existencia destas fantásticas librarías.</string>
<string name="kau_about_faq_intro">Preguntas frecuentes</string>
diff --git a/about/src/main/res/values-hu-rHU/strings_about.xml b/about/src/main/res/values-hu-rHU/strings_about.xml
index d57e13d..e4efded 100644
--- a/about/src/main/res/values-hu-rHU/strings_about.xml
+++ b/about/src/main/res/values-hu-rHU/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Ez az app nem jöhetett volna létre a következő könyvtárak nélkül.</string>
<string name="kau_about_faq_intro">GyIK</string>
diff --git a/about/src/main/res/values-in-rID/strings_about.xml b/about/src/main/res/values-in-rID/strings_about.xml
index e2e83a7..5bdee31 100644
--- a/about/src/main/res/values-in-rID/strings_about.xml
+++ b/about/src/main/res/values-in-rID/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Aplikasi ini tidak mungkin dilakukan tanpa perpustakaan besar berikut ini.</string>
<string name="kau_about_faq_intro">FAQ</string>
diff --git a/about/src/main/res/values-it-rIT/strings_about.xml b/about/src/main/res/values-it-rIT/strings_about.xml
index 170ff15..5867d94 100644
--- a/about/src/main/res/values-it-rIT/strings_about.xml
+++ b/about/src/main/res/values-it-rIT/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Questa applicazione non sarebbe possibile senza queste fantastiche librerie.</string>
<string name="kau_about_faq_intro">Domande frequenti</string>
diff --git a/about/src/main/res/values-ko-rKR/strings_about.xml b/about/src/main/res/values-ko-rKR/strings_about.xml
index f6b4413..00c80e3 100644
--- a/about/src/main/res/values-ko-rKR/strings_about.xml
+++ b/about/src/main/res/values-ko-rKR/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">이 앱은 아래의 라이브러리가 없었다면 만들 수 없었습니다.</string>
<string name="kau_about_faq_intro">FAQ</string>
diff --git a/about/src/main/res/values-nl-rNL/strings_about.xml b/about/src/main/res/values-nl-rNL/strings_about.xml
new file mode 100644
index 0000000..570984d
--- /dev/null
+++ b/about/src/main/res/values-nl-rNL/strings_about.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_about_libraries_intro">Deze app is mede mogelijk gemaakt door de volgende geweldige libraries.</string>
+ <string name="kau_about_faq_intro">Veelgestelde vragen</string>
+</resources>
diff --git a/about/src/main/res/values-no-rNO/strings_about.xml b/about/src/main/res/values-no-rNO/strings_about.xml
index 2cffcbc..328fda3 100644
--- a/about/src/main/res/values-no-rNO/strings_about.xml
+++ b/about/src/main/res/values-no-rNO/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Denne appens eksistens ville ikke vært mulig uten de flotte, følgende bibliotekene.</string>
<string name="kau_about_faq_intro">Spørsmål og svar</string>
diff --git a/about/src/main/res/values-pl-rPL/strings_about.xml b/about/src/main/res/values-pl-rPL/strings_about.xml
index cfdd1ef..a5daa6d 100644
--- a/about/src/main/res/values-pl-rPL/strings_about.xml
+++ b/about/src/main/res/values-pl-rPL/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Aplikacja nie byłaby możliwa bez następujących świetnych bibliotek.</string>
<string name="kau_about_faq_intro">FAQ</string>
diff --git a/about/src/main/res/values-pt-rBR/strings_about.xml b/about/src/main/res/values-pt-rBR/strings_about.xml
index e6feb8d..8e98238 100644
--- a/about/src/main/res/values-pt-rBR/strings_about.xml
+++ b/about/src/main/res/values-pt-rBR/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Este aplicativo não seria possível sem as seguintes excelentes bibliotecas.</string>
<string name="kau_about_faq_intro">Perguntas Frequentes</string>
diff --git a/about/src/main/res/values-pt-rPT/strings_about.xml b/about/src/main/res/values-pt-rPT/strings_about.xml
new file mode 100644
index 0000000..d092302
--- /dev/null
+++ b/about/src/main/res/values-pt-rPT/strings_about.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_about_libraries_intro">Esta aplicação não seria possível sem as seguintes bibliotecas.</string>
+ <string name="kau_about_faq_intro">FAQ</string>
+</resources>
diff --git a/about/src/main/res/values-sr-rSP/strings_about.xml b/about/src/main/res/values-sr-rSP/strings_about.xml
new file mode 100644
index 0000000..550aa9b
--- /dev/null
+++ b/about/src/main/res/values-sr-rSP/strings_about.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_about_libraries_intro">Ова апликација не бу била могућа без ових одличних библиотека.</string>
+ <string name="kau_about_faq_intro">ЧПП</string>
+</resources>
diff --git a/about/src/main/res/values-sv-rSE/strings_about.xml b/about/src/main/res/values-sv-rSE/strings_about.xml
index 02f5417..d8f888f 100644
--- a/about/src/main/res/values-sv-rSE/strings_about.xml
+++ b/about/src/main/res/values-sv-rSE/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Den här appen skulle inte varit möjlig utan följande bibliotek.</string>
<string name="kau_about_faq_intro">Vanliga frågor</string>
diff --git a/about/src/main/res/values-th-rTH/strings_about.xml b/about/src/main/res/values-th-rTH/strings_about.xml
index ab1863b..7a3a5ed 100644
--- a/about/src/main/res/values-th-rTH/strings_about.xml
+++ b/about/src/main/res/values-th-rTH/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">แอพนี้จะไม่สามารถเกิดขึ้นได้ถ้าไม่ได้ไลบาลี้เหล่านี้</string>
<string name="kau_about_faq_intro">ถามตอบ</string>
diff --git a/about/src/main/res/values-tr-rTR/strings_about.xml b/about/src/main/res/values-tr-rTR/strings_about.xml
index b54bb6e..857aec3 100644
--- a/about/src/main/res/values-tr-rTR/strings_about.xml
+++ b/about/src/main/res/values-tr-rTR/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Bu uygulama aşağıdaki büyük kütüphaneler olmadan mümkün olmayacaktır.</string>
<string name="kau_about_faq_intro">SSS</string>
diff --git a/about/src/main/res/values-uk-rUA/strings_about.xml b/about/src/main/res/values-uk-rUA/strings_about.xml
index 1ca3901..d4dca9b 100644
--- a/about/src/main/res/values-uk-rUA/strings_about.xml
+++ b/about/src/main/res/values-uk-rUA/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Цей додаток не був би можливим без використання великих бібліотек.</string>
<string name="kau_about_faq_intro">FAQ</string>
diff --git a/about/src/main/res/values-vi-rVN/strings_about.xml b/about/src/main/res/values-vi-rVN/strings_about.xml
index a71d127..4f84966 100644
--- a/about/src/main/res/values-vi-rVN/strings_about.xml
+++ b/about/src/main/res/values-vi-rVN/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">Ứng dụng này ra đời nhờ những thư viện tuyệt vời dưới đây.</string>
<string name="kau_about_faq_intro">CÂU HỎI THƯỜNG GẶP</string>
diff --git a/about/src/main/res/values-zh-rCN/strings_about.xml b/about/src/main/res/values-zh-rCN/strings_about.xml
index 8625ef7..cf63c9a 100644
--- a/about/src/main/res/values-zh-rCN/strings_about.xml
+++ b/about/src/main/res/values-zh-rCN/strings_about.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_about_libraries_intro">没有以下的大数据库,这个应用程序不会运行。</string>
<string name="kau_about_faq_intro">常见问题</string>
diff --git a/about/src/main/res/values-zh-rTW/strings_about.xml b/about/src/main/res/values-zh-rTW/strings_about.xml
new file mode 100644
index 0000000..a292a93
--- /dev/null
+++ b/about/src/main/res/values-zh-rTW/strings_about.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_about_libraries_intro">若無下述函式庫的幫忙, 本程式無法成真.</string>
+ <string name="kau_about_faq_intro">常見問題</string>
+</resources>
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt
index b754cb4..17fd09f 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/AdapterUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.adapters
import com.mikepenz.fastadapter.FastAdapter
@@ -14,10 +29,10 @@ import com.mikepenz.fastadapter.select.SelectExtension
* Add kotlin's generic syntax to better support out types
*/
fun <Item : IItem<*, *>> fastAdapter(vararg adapter: IAdapter<out Item>) =
- FastAdapter.with<Item, IAdapter<out Item>>(adapter.toList())!!
+ FastAdapter.with<Item, IAdapter<out Item>>(adapter.toList())!!
inline fun <reified T : IAdapterExtension<Item>, Item : IItem<*, *>> FastAdapter<Item>.getExtension(): T? =
- getExtension(T::class.java)
+ getExtension(T::class.java)
/**
* Returns selection size, or -1 if selection is disabled
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt
index 870861d..152982f 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/FastItemThemedAdapter.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.adapters
import android.content.res.ColorStateList
import android.os.Build
-import android.support.annotation.RequiresApi
import android.view.View
import android.widget.ImageView
import android.widget.TextView
+import androidx.annotation.RequiresApi
import ca.allanwang.kau.ui.createSimpleRippleDrawable
import ca.allanwang.kau.utils.adjustAlpha
import com.mikepenz.fastadapter.IItem
@@ -21,9 +36,9 @@ import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
* If that item extends [ThemableIItem], then the colors will be set
*/
class FastItemThemedAdapter<Item : IItem<*, *>>(
- textColor: Int? = null,
- backgroundColor: Int? = null,
- accentColor: Int? = null
+ textColor: Int? = null,
+ backgroundColor: Int? = null,
+ accentColor: Int? = null
) : FastItemAdapter<Item>() {
constructor(colors: ThemableIItemColors) : this(colors.textColor, colors.backgroundColor, colors.accentColor)
@@ -183,4 +198,4 @@ class ThemableIItemDelegate : ThemableIItem, ThemableIItemColors by ThemableIIte
val color = accentColor ?: textColor ?: return
views.forEach { it?.drawable?.setTintList(ColorStateList.valueOf(color)) }
}
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt
index aeee94c..40b4774 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/adapters/RepeatedClickListener.kt
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.adapters
-import android.support.annotation.IntRange
import android.view.View
+import androidx.annotation.IntRange
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.IAdapter
import com.mikepenz.fastadapter.IItem
@@ -10,10 +25,12 @@ import com.mikepenz.fastadapter.listeners.OnClickListener
/**
* Created by Allan Wang on 26/12/17.
*/
-fun <Item : IItem<*, *>> FastAdapter<Item>.withOnRepeatedClickListener(count: Int,
- duration: Long,
- event: OnClickListener<Item>) =
- withOnClickListener(RepeatedClickListener(count, duration, event))
+fun <Item : IItem<*, *>> FastAdapter<Item>.withOnRepeatedClickListener(
+ count: Int,
+ duration: Long,
+ event: OnClickListener<Item>
+) =
+ withOnClickListener(RepeatedClickListener(count, duration, event))
/**
* Registers and skips each click until the designated [count] clicks are triggered,
@@ -21,9 +38,10 @@ fun <Item : IItem<*, *>> FastAdapter<Item>.withOnRepeatedClickListener(count: In
* Only then will the [event] be fired, and everything will be reset.
*/
private class RepeatedClickListener<Item : IItem<*, *>>(
- @IntRange(from = 1) val count: Int,
- @IntRange(from = 1) val duration: Long,
- val event: OnClickListener<Item>) : OnClickListener<Item> {
+ @IntRange(from = 1) val count: Int,
+ @IntRange(from = 1) val duration: Long,
+ val event: OnClickListener<Item>
+) : OnClickListener<Item> {
init {
if (count <= 0)
@@ -49,4 +67,4 @@ private class RepeatedClickListener<Item : IItem<*, *>>(
}
return false
}
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt b/adapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt
index 3cf13df..b83a2d0 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/AnimatorInterfaces.kt
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.animators
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewPropertyAnimator
+import androidx.recyclerview.widget.RecyclerView
/**
* Created by Allan Wang on 2017-07-11.
@@ -25,7 +40,11 @@ interface KauAnimatorRemove {
}
interface KauAnimatorChange {
- fun changeOldAnimation(holder: RecyclerView.ViewHolder, changeInfo: BaseItemAnimator.ChangeInfo): ViewPropertyAnimator.() -> Unit
+ fun changeOldAnimation(
+ holder: RecyclerView.ViewHolder,
+ changeInfo: BaseItemAnimator.ChangeInfo
+ ): ViewPropertyAnimator.() -> Unit
+
fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit
fun changeAnimationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit
}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java b/adapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java
index 06b8df6..4ead735 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/BaseItemAnimator.java
@@ -26,10 +26,11 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.RecyclerView.ViewHolder;
-import android.support.v7.widget.SimpleItemAnimator;
+import androidx.annotation.NonNull;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import androidx.recyclerview.widget.SimpleItemAnimator;
+
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.Interpolator;
@@ -38,11 +39,11 @@ import java.util.ArrayList;
import java.util.List;
/**
- * This implementation of {@link android.support.v7.widget.RecyclerView.ItemAnimator} provides basic
+ * This implementation of {@link androidx.recyclerview.widget.RecyclerView.ItemAnimator} provides basic
* animations on remove, add, and move events that happen to the items in
* a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
*
- * @see android.support.v7.widget.RecyclerView#setItemAnimator(android.support.v7.widget.RecyclerView.ItemAnimator)
+ * @see androidx.recyclerview.widget.RecyclerView#setItemAnimator(androidx.recyclerview.widget.RecyclerView.ItemAnimator)
*/
public abstract class BaseItemAnimator extends SimpleItemAnimator {
private static final boolean DEBUG = false;
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt b/adapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt
index 9aeafde..4e342ab 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/DefaultAnimator.kt
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.animators
-import android.support.v7.widget.RecyclerView
import android.view.ViewPropertyAnimator
+import androidx.recyclerview.widget.RecyclerView
/**
* Created by Allan Wang on 2017-06-27.
@@ -59,5 +74,4 @@ open class DefaultAnimator : BaseItemAnimator() {
override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder) {
holder.itemView.alpha = 1f
}
-
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt b/adapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt
index bf38cac..9113b0e 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/FadeScaleAnimator.kt
@@ -1,14 +1,30 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.animators
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewPropertyAnimator
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.utils.scaleXY
/**
* Created by Allan Wang on 2017-07-11.
*/
-class FadeScaleAnimatorAdd(val scaleFactor: Float = 1.0f, override var itemDelayFactor: Float = 0.125f) : KauAnimatorAdd {
+class FadeScaleAnimatorAdd(val scaleFactor: Float = 1.0f, override var itemDelayFactor: Float = 0.125f) :
+ KauAnimatorAdd {
override fun animationPrepare(holder: RecyclerView.ViewHolder): View.() -> Unit = {
scaleXY = scaleFactor
@@ -26,10 +42,10 @@ class FadeScaleAnimatorAdd(val scaleFactor: Float = 1.0f, override var itemDelay
}
override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L
-
}
-class FadeScaleAnimatorRemove(val scaleFactor: Float = 1.0f, override var itemDelayFactor: Float = 0.125f) : KauAnimatorRemove {
+class FadeScaleAnimatorRemove(val scaleFactor: Float = 1.0f, override var itemDelayFactor: Float = 0.125f) :
+ KauAnimatorRemove {
override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = {
scaleXY(scaleFactor)
@@ -46,10 +62,12 @@ class FadeScaleAnimatorRemove(val scaleFactor: Float = 1.0f, override var itemDe
class FadeAnimatorChange : KauAnimatorChange {
- override fun changeOldAnimation(holder: RecyclerView.ViewHolder, changeInfo: BaseItemAnimator.ChangeInfo): ViewPropertyAnimator.() -> Unit = { alpha(0f) }
+ override fun changeOldAnimation(
+ holder: RecyclerView.ViewHolder,
+ changeInfo: BaseItemAnimator.ChangeInfo
+ ): ViewPropertyAnimator.() -> Unit = { alpha(0f) }
override fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { alpha(1f) }
override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { alpha = 1f }
-
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt b/adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt
index 7b9b732..b9df946 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.animators
-import android.support.v7.widget.RecyclerView
import android.view.ViewPropertyAnimator
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.utils.KAU_BOTTOM
import ca.allanwang.kau.utils.KAU_RIGHT
@@ -9,12 +24,13 @@ import ca.allanwang.kau.utils.KAU_RIGHT
* Created by Allan Wang on 2017-06-27.
*/
open class KauAnimator(
- val addAnimator: KauAnimatorAdd = SlideAnimatorAdd(KAU_BOTTOM),
- val removeAnimator: KauAnimatorRemove = SlideAnimatorRemove(KAU_RIGHT),
- val changeAnimator: KauAnimatorChange = FadeAnimatorChange()
+ val addAnimator: KauAnimatorAdd = SlideAnimatorAdd(KAU_BOTTOM),
+ val removeAnimator: KauAnimatorRemove = SlideAnimatorRemove(KAU_RIGHT),
+ val changeAnimator: KauAnimatorChange = FadeAnimatorChange()
) : BaseItemAnimator() {
- open fun startDelay(holder: RecyclerView.ViewHolder, duration: Long, factor: Float) = Math.max(0L, (holder.adapterPosition * duration * factor).toLong())
+ open fun startDelay(holder: RecyclerView.ViewHolder, duration: Long, factor: Float) =
+ Math.max(0L, (holder.adapterPosition * duration * factor).toLong())
override fun removeAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator {
return holder.itemView.animate().apply {
@@ -29,7 +45,8 @@ open class KauAnimator(
holder.itemView.apply { removeAnimator.animationCleanup(holder)() }
}
- override fun getRemoveDelay(remove: Long, move: Long, change: Long): Long = removeAnimator.getDelay(remove, move, change)
+ override fun getRemoveDelay(remove: Long, move: Long, change: Long): Long =
+ removeAnimator.getDelay(remove, move, change)
override fun addAnimationPrepare(holder: RecyclerView.ViewHolder) {
holder.itemView.apply { addAnimator.animationPrepare(holder)() }
@@ -69,5 +86,4 @@ open class KauAnimator(
override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder) {
holder.itemView.apply { changeAnimator.changeAnimationCleanup(holder)() }
}
-
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt b/adapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt
index 5ecc937..cca8a25 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/NoAnimator.kt
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.animators
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewPropertyAnimator
+import androidx.recyclerview.widget.RecyclerView
/**
* Created by Allan Wang on 2017-08-02.
@@ -16,7 +31,6 @@ class NoAnimatorAdd(override var itemDelayFactor: Float = 0f) : KauAnimatorAdd {
override fun animationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { }
override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L
-
}
class NoAnimatorRemove(override var itemDelayFactor: Float = 0f) : KauAnimatorRemove {
@@ -30,10 +44,12 @@ class NoAnimatorRemove(override var itemDelayFactor: Float = 0f) : KauAnimatorRe
class NoAnimatorChange : KauAnimatorChange {
- override fun changeOldAnimation(holder: RecyclerView.ViewHolder, changeInfo: BaseItemAnimator.ChangeInfo): ViewPropertyAnimator.() -> Unit = { }
+ override fun changeOldAnimation(
+ holder: RecyclerView.ViewHolder,
+ changeInfo: BaseItemAnimator.ChangeInfo
+ ): ViewPropertyAnimator.() -> Unit = { }
override fun changeNewAnimation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = { }
override fun changeAnimationCleanup(holder: RecyclerView.ViewHolder): View.() -> Unit = { alpha = 1f }
-
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt b/adapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt
index f8f71a5..55d5b2e 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/SlideAnimator.kt
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.animators
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewPropertyAnimator
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.utils.KAU_BOTTOM
import ca.allanwang.kau.utils.KAU_LEFT
import ca.allanwang.kau.utils.KAU_RIGHT
@@ -11,7 +26,8 @@ import ca.allanwang.kau.utils.KAU_TOP
/**
* Created by Allan Wang on 2017-07-11.
*/
-class SlideAnimatorAdd(val fromEdge: Int, val slideFactor: Float = 1f, override var itemDelayFactor: Float = 0.125f) : KauAnimatorAdd {
+class SlideAnimatorAdd(val fromEdge: Int, val slideFactor: Float = 1f, override var itemDelayFactor: Float = 0.125f) :
+ KauAnimatorAdd {
override fun animationPrepare(holder: RecyclerView.ViewHolder): View.() -> Unit = {
when (fromEdge) {
@@ -37,10 +53,13 @@ class SlideAnimatorAdd(val fromEdge: Int, val slideFactor: Float = 1f, override
}
override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L
-
}
-class SlideAnimatorRemove(val fromEdge: Int, val slideFactor: Float = 1f, override var itemDelayFactor: Float = 0.125f) : KauAnimatorRemove {
+class SlideAnimatorRemove(
+ val fromEdge: Int,
+ val slideFactor: Float = 1f,
+ override var itemDelayFactor: Float = 0.125f
+) : KauAnimatorRemove {
override fun animation(holder: RecyclerView.ViewHolder): ViewPropertyAnimator.() -> Unit = {
with(holder.itemView) {
when (fromEdge) {
@@ -61,4 +80,4 @@ class SlideAnimatorRemove(val fromEdge: Int, val slideFactor: Float = 1f, overri
}
override fun getDelay(remove: Long, move: Long, change: Long): Long = 0L
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt
index ba969a2..6e33833 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/CardIItem.kt
@@ -1,18 +1,38 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.iitems
import android.graphics.Color
import android.graphics.drawable.Drawable
-import android.support.v7.widget.CardView
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
+import androidx.cardview.widget.CardView
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapter.R
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.INVALID_ID
+import ca.allanwang.kau.utils.drawable
+import ca.allanwang.kau.utils.gone
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.toDrawable
+import ca.allanwang.kau.utils.visible
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter.listeners.ClickEventHook
@@ -25,9 +45,9 @@ import com.mikepenz.iconics.typeface.IIcon
* The icon and button are hidden by default unless values are given
*/
class CardIItem(
- val builder: Config.() -> Unit = {}
+ val builder: Config.() -> Unit = {}
) : KauIItem<CardIItem, CardIItem.ViewHolder>(
- R.layout.kau_iitem_card, ::ViewHolder, R.id.kau_item_card
+ R.layout.kau_iitem_card, ::ViewHolder, R.id.kau_item_card
), ThemableIItem by ThemableIItemDelegate() {
companion object {
@@ -83,7 +103,7 @@ class CardIItem(
}
val icon = drawable(imageRes) {
imageIIcon?.toDrawable(this@context, sizeDp = 24, color = imageIIconColor)
- ?: image
+ ?: image
}
if (icon != null) holder.icon.visible().setImageDrawable(icon)
}
@@ -117,5 +137,4 @@ class CardIItem(
val bottomRow: LinearLayout = v.findViewById(R.id.kau_card_bottom_row)
val button: Button = v.findViewById(R.id.kau_card_button)
}
-
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt
index 2116b34..2c488b1 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/HeaderIItem.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.iitems
-import android.support.v7.widget.CardView
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.TextView
+import androidx.cardview.widget.CardView
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapter.R
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
@@ -17,9 +32,10 @@ import ca.allanwang.kau.utils.string
* Contains only one text view
*/
class HeaderIItem(
- text: String? = null, var textRes: Int = INVALID_ID
+ text: String? = null,
+ var textRes: Int = INVALID_ID
) : KauIItem<HeaderIItem, HeaderIItem.ViewHolder>(
- R.layout.kau_iitem_header, { ViewHolder(it) }, R.id.kau_item_header_big_margin_top
+ R.layout.kau_iitem_header, { ViewHolder(it) }, R.id.kau_item_header_big_margin_top
), ThemableIItem by ThemableIItemDelegate() {
var text: String = text ?: "Header Placeholder"
@@ -40,5 +56,4 @@ class HeaderIItem(
val text: TextView = v.findViewById(R.id.kau_header_text)
val container: CardView = v.findViewById(R.id.kau_header_container)
}
-
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt
index 5174503..c66dc01 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/iitems/KauIItem.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.iitems
import android.annotation.SuppressLint
-import android.support.annotation.LayoutRes
-import android.support.v7.widget.RecyclerView
import android.view.View
+import androidx.annotation.LayoutRes
+import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.fastadapter.IClickable
import com.mikepenz.fastadapter.IItem
import com.mikepenz.fastadapter.items.AbstractItem
@@ -15,13 +30,13 @@ import com.mikepenz.fastadapter.items.AbstractItem
* If only one iitem type extends the given [layoutRes], you may use it as the type and not worry about another id
*/
open class KauIItem<Item, VH : RecyclerView.ViewHolder>(
- @param:LayoutRes private val layoutRes: Int,
- private val viewHolder: (v: View) -> VH,
- private val type: Int = layoutRes
+ @param:LayoutRes private val layoutRes: Int,
+ private val viewHolder: (v: View) -> VH,
+ private val type: Int = layoutRes
) : AbstractItem<Item, VH>() where Item : IItem<*, *>, Item : IClickable<*> {
@SuppressLint("ResourceType")
final override fun getType(): Int = type
final override fun getViewHolder(v: View): VH = viewHolder(v)
final override fun getLayoutRes(): Int = layoutRes
-} \ No newline at end of file
+}
diff --git a/adapter/src/main/res/layout/kau_iitem_card.xml b/adapter/src/main/res/layout/kau_iitem_card.xml
index 249f3b8..6bae0fe 100644
--- a/adapter/src/main/res/layout/kau_iitem_card.xml
+++ b/adapter/src/main/res/layout/kau_iitem_card.xml
@@ -3,7 +3,7 @@
<!--
Generic card with an imageview, title, description, and button
-->
-<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/kau_card_container"
android:layout_width="match_parent"
@@ -11,7 +11,7 @@
android:background="?android:selectableItemBackground"
android:minHeight="?android:listPreferredItemHeight">
- <android.support.constraint.ConstraintLayout
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/kau_padding_normal">
@@ -69,6 +69,6 @@
</LinearLayout>
- </android.support.constraint.ConstraintLayout>
+ </androidx.constraintlayout.widget.ConstraintLayout>
-</android.support.v7.widget.CardView>
+</androidx.cardview.widget.CardView>
diff --git a/adapter/src/main/res/layout/kau_iitem_header.xml b/adapter/src/main/res/layout/kau_iitem_header.xml
index db809eb..b0b2ec8 100644
--- a/adapter/src/main/res/layout/kau_iitem_header.xml
+++ b/adapter/src/main/res/layout/kau_iitem_header.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/kau_header_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -13,4 +13,4 @@
android:padding="@dimen/kau_padding_normal"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
-</android.support.v7.widget.CardView> \ No newline at end of file
+</androidx.cardview.widget.CardView> \ No newline at end of file
diff --git a/android-lib.gradle b/android-lib.gradle
index 7275347..e8a4c6d 100644
--- a/android-lib.gradle
+++ b/android-lib.gradle
@@ -31,7 +31,7 @@ android {
versionCode androidGitVersion.code()
consumerProguardFiles 'progress-proguard.txt'
multiDexEnabled true
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
@@ -87,5 +87,6 @@ dependencies {
androidTestImplementation kauDependency.kotlinTest
androidTestImplementation kauDependency.espresso
+ androidTestImplementation kauDependency.testRules
androidTestImplementation kauDependency.testRunner
} \ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 3ddfb9c..39aba6f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -15,6 +15,7 @@ buildscript {
classpath kauPlugin.playPublisher
classpath kauPlugin.dexCount
classpath kauPlugin.gitVersion
+ classpath kauPlugin.spotless
}
wrapper.setDistributionType(Wrapper.DistributionType.ALL)
@@ -27,7 +28,7 @@ task clean(type: Delete) {
}
task generateChangelogMd {
- kauChangelog.generate("$project.rootDir/sample/src/main/res/xml/kau_changelog.xml")
+ kauChangelog.generate("${project.rootDir}/sample/src/main/res/xml/kau_changelog.xml")
}
subprojects {
@@ -37,6 +38,8 @@ subprojects {
apply plugin: 'com.gladed.androidgitversion'
+ apply from: '../spotless.gradle'
+
repositories {
google()
jcenter()
diff --git a/buildSrc/README.md b/buildSrc/README.md
index 60d2dfc..91a60ac 100644
--- a/buildSrc/README.md
+++ b/buildSrc/README.md
@@ -48,7 +48,7 @@ You are free to use the values through `kau.[tagName]`.
As an example, AppCompat is imported in KAU using
```gradle
-api "com.android.support:appcompat-v7:${kau.supportLibs}"
+api "androidx.appcompat:appcompat:${kau.appcompat}"
```
# Plugins
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
deleted file mode 100644
index a51e9ae..0000000
--- a/buildSrc/build.gradle
+++ /dev/null
@@ -1,9 +0,0 @@
-apply plugin: 'groovy'
-apply plugin: 'maven'
-
-group = "ca.allanwang"
-
-dependencies {
- compile gradleApi()
- compile localGroovy()
-} \ No newline at end of file
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 0000000..83a3370
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,19 @@
+plugins {
+ `kotlin-dsl`
+ maven
+}
+
+group = "ca.allanwang"
+
+gradlePlugin {
+ plugins {
+ register("kau-plugin") {
+ id = "ca.allanwang.kau"
+ implementationClass = "ca.allanwang.kau.KauPlugin"
+ }
+ }
+}
+
+repositories {
+ mavenCentral()
+} \ No newline at end of file
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/buildSrc/settings.gradle.kts
diff --git a/buildSrc/src/main/groovy/ca/allanwang/kau/ChangelogGenerator.groovy b/buildSrc/src/main/groovy/ca/allanwang/kau/ChangelogGenerator.groovy
deleted file mode 100644
index bb56fa2..0000000
--- a/buildSrc/src/main/groovy/ca/allanwang/kau/ChangelogGenerator.groovy
+++ /dev/null
@@ -1,76 +0,0 @@
-package ca.allanwang.kau
-
-import org.gradle.api.GradleException
-import org.gradle.api.Project
-
-/**
- * Given an xml of the format
- *
- * <?xml version="1.0" encoding="utf-8"?>
- * <resources>
- * <version title="v0.1" />
- * <item text="Initial Changelog" />
- * <item text="Bullet point here" />
- * <item text="More points" />
- * <item text="" /> <!-- this one is empty and therefore ignored -->
- * </resources>
- *
- * Outputs a changelog in markdown format
- */
-class ChangelogGenerator {
-
- static class ChangelogException extends GradleException {
- ChangelogException(String message) {
- super(message)
- }
- }
-
- private Project project
-
- ChangelogGenerator(Project project) {
- this.project = project
- }
-
- private static void fail(String message) {
- throw new ChangelogException(message)
- }
-
- final void generate(String inputUri, String outputUri = "$project.rootDir/docs/Changelog.md") {
- def input = new File(inputUri)
- if (!input.exists())
- fail("Could not generate changelog from ${input.absolutePath}")
-
- def output = new File(outputUri)
-
- if (output.exists()) {
- if (output.isDirectory())
- fail("Cannot save changelog at directory ${output.absolutePath}")
-
-
- if (output.isFile() && !output.delete())
- fail("Could not delete changelog at ${output.absolutePath}")
- } else {
- output.parentFile.mkdirs()
- }
-
- if (!output.createNewFile())
- fail("Could not create changelog file at ${output.absolutePath}")
-
- def parsedProjectXml = (new XmlParser()).parse(inputUri)
- def sw = new StringWriter()
- sw.append("# Changelog\n")
- parsedProjectXml.depthFirst().each {
- switch (it.name()) {
- case "version":
- sw.append("\n## ${it.@title}\n")
- break
- case "item":
- if (it.@text?.trim())
- sw.append("* ${it.@text}\n")
- }
- }
- output.write(sw.toString())
- println("Generated changelog at ${output.absolutePath}")
- }
-
-} \ No newline at end of file
diff --git a/buildSrc/src/main/groovy/ca/allanwang/kau/Dependencies.groovy b/buildSrc/src/main/groovy/ca/allanwang/kau/Dependencies.groovy
deleted file mode 100644
index ec3d208..0000000
--- a/buildSrc/src/main/groovy/ca/allanwang/kau/Dependencies.groovy
+++ /dev/null
@@ -1,12 +0,0 @@
-package ca.allanwang.kau
-
-/**
- * Some common dependencies, backed by the supplied versions
- */
-class Dependencies {
- static def kotlin = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}"
- static def kotlinTest = "org.jetbrains.kotlin:kotlin-test-junit:${Versions.kotlin}"
- static def junit = "junit:junit:${Versions.junit}"
- static def espresso = "com.android.support.test.espresso:espresso-core:${Versions.espresso}"
- static def testRunner = "com.android.support.test:runner:${Versions.testRunner}"
-} \ No newline at end of file
diff --git a/buildSrc/src/main/groovy/ca/allanwang/kau/KauPlugin.groovy b/buildSrc/src/main/groovy/ca/allanwang/kau/KauPlugin.groovy
deleted file mode 100644
index e73564c..0000000
--- a/buildSrc/src/main/groovy/ca/allanwang/kau/KauPlugin.groovy
+++ /dev/null
@@ -1,16 +0,0 @@
-package ca.allanwang.kau
-
-import org.gradle.api.Plugin
-import org.gradle.api.Project
-
-class KauPlugin implements Plugin<Project> {
-
- @Override
- void apply(Project project) {
- project.extensions.create("kau", Versions)
- project.extensions.create("kauPlugin", Plugins)
- project.extensions.create("kauDependency", Dependencies)
- project.extensions.create("kauChangelog", ChangelogGenerator, project)
- }
-
-} \ No newline at end of file
diff --git a/buildSrc/src/main/groovy/ca/allanwang/kau/Plugins.groovy b/buildSrc/src/main/groovy/ca/allanwang/kau/Plugins.groovy
deleted file mode 100644
index c1ecba6..0000000
--- a/buildSrc/src/main/groovy/ca/allanwang/kau/Plugins.groovy
+++ /dev/null
@@ -1,17 +0,0 @@
-package ca.allanwang.kau
-
-/**
- * Some common buildscript plugins, backed by the supplied versions
- */
-class Plugins {
- static def android = "com.android.tools.build:gradle:${Versions.gradlePlugin}"
- static def kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}"
- static
- def androidMaven = "com.github.dcendents:android-maven-gradle-plugin:${Versions.mavenPlugin}"
- static
- def playPublisher = "com.github.triplet.gradle:play-publisher:${Versions.playPublishPlugin}"
- static
- def dexCount = "com.getkeepsafe.dexcount:dexcount-gradle-plugin:${Versions.dexCountPlugin}"
- static
- def gitVersion = "gradle.plugin.com.gladed.gradle.androidgitversion:gradle-android-git-version:${Versions.gitVersionPlugin}"
-} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/ca/allanwang/kau/ChangelogGenerator.kt b/buildSrc/src/main/kotlin/ca/allanwang/kau/ChangelogGenerator.kt
new file mode 100644
index 0000000..5e21b7e
--- /dev/null
+++ b/buildSrc/src/main/kotlin/ca/allanwang/kau/ChangelogGenerator.kt
@@ -0,0 +1,105 @@
+package ca.allanwang.kau
+
+import groovy.util.Node
+import groovy.util.XmlParser
+import org.gradle.api.GradleException
+import org.gradle.api.Project
+import java.io.File
+
+/**
+ * Given an xml of the format
+ *
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <resources>
+ * <version title="v0.1" />
+ * <item text="Initial Changelog" />
+ * <item text="Bullet point here" />
+ * <item text="More points" />
+ * <item text="" /> <!-- this one is empty and therefore ignored -->
+ * </resources>
+ *
+ * Outputs a changelog in markdown format
+ */
+open class ChangelogGenerator(private val project: Project) {
+
+ class ChangelogException(message: String) : GradleException(message)
+
+ private fun fail(message: String): Nothing =
+ throw ChangelogException(message)
+
+ class ChangelogEntry(val version: String, val items: Array<String>)
+
+ private fun Node.forEachNode(action: (Node) -> Unit) {
+ children().forEach {
+ action(it as Node)
+ }
+ }
+
+ fun read(inputUri: String): List<ChangelogEntry> {
+ val input = File(inputUri)
+ if (!input.exists()) {
+ fail("Could not generate changelog from ${input.absolutePath}")
+ }
+
+ val parser = XmlParser().parse(inputUri)
+
+ val entries: MutableList<ChangelogEntry> = mutableListOf()
+ var version: String? = null
+ val items: MutableList<String> = mutableListOf()
+
+ fun addEntry() {
+ version?.also { v ->
+ entries.add(ChangelogEntry(v, items.toTypedArray()))
+ items.clear()
+ }
+ }
+
+ parser.depthFirst().mapNotNull { it as? Node }.forEach { n ->
+ when (n.name()) {
+ "version" -> {
+ addEntry()
+ version = n.attribute("title")?.toString() ?: ""
+ }
+ "item" -> {
+ n.attribute("text")?.toString()?.takeIf(String::isNotBlank)?.let {
+ items.add(it)
+ }
+ }
+ }
+ }
+ addEntry()
+ return entries
+ }
+
+ @JvmOverloads
+ fun generate(inputUri: String, outputUri: String = "${project.rootDir}/docs/Changelog.md"): List<ChangelogEntry> {
+ val entries = read(inputUri)
+ val output = File(outputUri)
+ if (output.exists()) {
+ if (output.isDirectory) {
+ fail("Cannot save changelog at directory ${output.absolutePath}")
+ }
+ if (output.isFile && !output.delete()) {
+ fail("Could not delete changelog at ${output.absolutePath}")
+ }
+ } else {
+ output.parentFile.mkdirs()
+ }
+
+ if (!output.createNewFile()) {
+ fail("Could not create changelog file at ${output.absolutePath}")
+ }
+ val markdown = buildString {
+ append("# Changelog\n")
+ entries.forEach { e ->
+ append("\n## ${e.version}\n")
+ e.items.forEach {
+ append("* $it\n")
+ }
+ }
+ }
+ output.writeText(markdown)
+ println("Generated changelog at ${output.absolutePath}")
+ return entries
+ }
+} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/ca/allanwang/kau/Dependencies.kt b/buildSrc/src/main/kotlin/ca/allanwang/kau/Dependencies.kt
new file mode 100644
index 0000000..9e23ac4
--- /dev/null
+++ b/buildSrc/src/main/kotlin/ca/allanwang/kau/Dependencies.kt
@@ -0,0 +1,14 @@
+package ca.allanwang.kau
+
+/**
+ * Some common dependencies, backed by the supplied versions
+ */
+open class Dependencies {
+ private val v = Versions()
+ val kotlin = "org.jetbrains.kotlin:kotlin-stdlib:${v.kotlin}"
+ val kotlinTest = "org.jetbrains.kotlin:kotlin-test-junit:${v.kotlin}"
+ val junit = "junit:junit:${v.junit}"
+ val espresso = "androidx.test.espresso:espresso-core:${v.espresso}"
+ val testRunner = "androidx.test.ext:junit:${v.testRunner}"
+ val testRules = "androidx.test:rules:${v.testRules}"
+} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/ca/allanwang/kau/KauPlugin.kt b/buildSrc/src/main/kotlin/ca/allanwang/kau/KauPlugin.kt
new file mode 100644
index 0000000..6be15e5
--- /dev/null
+++ b/buildSrc/src/main/kotlin/ca/allanwang/kau/KauPlugin.kt
@@ -0,0 +1,17 @@
+package ca.allanwang.kau
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.create
+
+class KauPlugin : Plugin<Project> {
+
+ override fun apply(project: Project) {
+ project.extensions.run {
+ create<Versions>("kau")
+ create<Dependencies>("kauDependency")
+ create<Plugins>("kauPlugin")
+ create<ChangelogGenerator>("kauChangelog", project)
+ }
+ }
+} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/ca/allanwang/kau/Plugins.kt b/buildSrc/src/main/kotlin/ca/allanwang/kau/Plugins.kt
new file mode 100644
index 0000000..c8265ab
--- /dev/null
+++ b/buildSrc/src/main/kotlin/ca/allanwang/kau/Plugins.kt
@@ -0,0 +1,16 @@
+package ca.allanwang.kau
+
+/**
+ * Some common buildscript plugins, backed by the supplied versions
+ */
+open class Plugins {
+ private val v = Versions()
+ val android = "com.android.tools.build:gradle:${v.gradlePlugin}"
+ val kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${v.kotlin}"
+ val androidMaven = "com.github.dcendents:android-maven-gradle-plugin:${v.mavenPlugin}"
+ val playPublisher = "com.github.triplet.gradle:play-publisher:${v.playPublishPlugin}"
+ val dexCount = "com.getkeepsafe.dexcount:dexcount-gradle-plugin:${v.dexCountPlugin}"
+ val gitVersion =
+ "gradle.plugin.com.gladed.gradle.androidgitversion:gradle-android-git-version:${v.gitVersionPlugin}"
+ val spotless = "com.diffplug.spotless:spotless-plugin-gradle:${v.spotless}"
+} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/ca/allanwang/kau/Versions.kt b/buildSrc/src/main/kotlin/ca/allanwang/kau/Versions.kt
new file mode 100644
index 0000000..8c14a92
--- /dev/null
+++ b/buildSrc/src/main/kotlin/ca/allanwang/kau/Versions.kt
@@ -0,0 +1,80 @@
+package ca.allanwang.kau
+
+open class Versions {
+ val coreMinSdk = 19
+ val minSdk = 21
+ val targetSdk = 28
+
+ // https://developer.android.com/studio/releases/build-tools
+ val buildTools = "28.0.3"
+
+ // https://mvnrepository.com/artifact/androidx.appcompat/appcompat?repo=google
+ val appcompat = "1.0.2"
+
+ // https://mvnrepository.com/artifact/com.google.android.material/material
+ val googleMaterial = "1.0.0"
+
+ // https://mvnrepository.com/artifact/androidx.recyclerview/recyclerview
+ val recyclerView = "1.0.0"
+
+ // https://mvnrepository.com/artifact/androidx.cardview/cardview
+ val cardView = "1.0.0"
+
+ // https://mvnrepository.com/artifact/androidx.constraintlayout/constraintlayout
+ val constraintLayout = "1.1.3"
+
+ // https://kotlinlang.org/docs/reference/using-gradle.html
+ val kotlin = "1.3.31"
+
+ // https://github.com/Kotlin/kotlinx.coroutines/releases
+ val coroutines = "1.2.1"
+
+ // https://github.com/mikepenz/AboutLibraries/releases
+ val aboutLibraries = "6.2.3"
+
+ // https://github.com/wasabeef/Blurry/releases
+ val blurry = "3.0.0"
+
+ // https://github.com/mikepenz/FastAdapter#using-maven
+ val fastAdapter = "3.3.1"
+ val fastAdapterCommons = fastAdapter
+
+ // https://github.com/bumptech/glide/releases
+ val glide = "4.9.0"
+
+ // https://github.com/mikepenz/Android-Iconics#1-provide-the-gradle-dependency
+ val iconics = "3.2.5"
+ val iconicsGoogle = "3.0.1.3"
+ val iconicsMaterial = "2.2.0.5"
+ val iconicsCommunity = "3.5.95.1"
+
+ // https://github.com/afollestad/material-dialogs/releases
+ val materialDialog = "3.0.0-rc2"
+
+ // https://mvnrepository.com/artifact/androidx.test.espresso/espresso-core?repo=google
+ val espresso = "3.1.1"
+
+ // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
+ val junit = "4.12"
+
+ val testRunner = "1.1.0"
+
+ // https://mvnrepository.com/artifact/androidx.test/rules?repo=google
+ val testRules = "1.1.1"
+
+ // https://github.com/diffplug/spotless/blob/master/plugin-gradle/CHANGES.md
+ val spotless = "3.18.0"
+
+ // https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google
+ val gradlePlugin = "3.4.1"
+ // https://github.com/dcendents/android-maven-gradle-plugin/releases
+ val mavenPlugin = "2.1"
+ // https://github.com/Triple-T/gradle-play-publisher/releases
+ val playPublishPlugin = "2.1.0"
+
+ // https://github.com/KeepSafe/dexcount-gradle-plugin/releases
+ val dexCountPlugin = "0.8.6"
+
+ // https://github.com/gladed/gradle-android-git-version/releases
+ val gitVersionPlugin = "0.4.7"
+} \ No newline at end of file
diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/ca.allanwang.kau.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/ca.allanwang.kau.properties
deleted file mode 100644
index ba824cd..0000000
--- a/buildSrc/src/main/resources/META-INF/gradle-plugins/ca.allanwang.kau.properties
+++ /dev/null
@@ -1 +0,0 @@
-implementation-class=ca.allanwang.kau.KauPlugin \ No newline at end of file
diff --git a/colorpicker/README.md b/colorpicker/README.md
index c90809e..16977a9 100644
--- a/colorpicker/README.md
+++ b/colorpicker/README.md
@@ -1,10 +1,9 @@
# KAU :colorpicker
-Material Dialogs by default contains a color picker, but it requires an activity that also implements the color callback.
-KAU's colorpicker decouples the two, so it only needs a context and a separate callback.
-The color picker also animates the selection, and uses Kotlin's DSL to provide easy calling.
+As of Material Dialog 2.x, `:colorpicker` is effectively a very thin wrapper around [Material Dialog's color picker](https://github.com/afollestad/material-dialogs/blob/master/documentation/COLOR.md).
+The main difference is that it exposes an interface internal to KAU, which allows a greater level of consistency within other submodules.
+It also contains an extra palette for accent colors.
-To use it, call `Context.colorPickerDialog` and specify and configs as required through the builder.
+To use it, call `MaterialDialog.kauColorChooser` and specify the configs.
![Color Picker Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_color_picker.gif)
-![Color Picker Custom Gif](https://raw.githubusercontent.com/AllanWang/Storage-Hub/master/kau/kau_color_picker_custom.gif) \ No newline at end of file
diff --git a/colorpicker/build.gradle b/colorpicker/build.gradle
index 9b52cd4..4b89e10 100644
--- a/colorpicker/build.gradle
+++ b/colorpicker/build.gradle
@@ -7,7 +7,7 @@ apply from: '../android-lib.gradle'
dependencies {
implementation project(':core')
- implementation "com.afollestad.material-dialogs:commons:${kau.materialDialog}"
+ implementation "com.afollestad.material-dialogs:color:${kau.materialDialog}"
}
apply from: '../artifacts.gradle'
diff --git a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt
index 310fd53..e748677 100644
--- a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt
+++ b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/CircleView.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.colorpicker
import android.animation.ValueAnimator
@@ -13,15 +28,15 @@ import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.StateListDrawable
import android.graphics.drawable.shapes.OvalShape
import android.os.Build
-import android.support.annotation.ColorInt
-import android.support.annotation.ColorRes
-import android.support.annotation.FloatRange
-import android.support.v4.view.GravityCompat
-import android.support.v4.view.ViewCompat
import android.util.AttributeSet
import android.view.Gravity
import android.widget.FrameLayout
import android.widget.Toast
+import androidx.annotation.ColorInt
+import androidx.annotation.ColorRes
+import androidx.annotation.FloatRange
+import androidx.core.view.GravityCompat
+import androidx.core.view.ViewCompat
import ca.allanwang.kau.utils.getDip
import ca.allanwang.kau.utils.setBackgroundColorRes
import ca.allanwang.kau.utils.toColor
@@ -33,7 +48,8 @@ import ca.allanwang.kau.utils.toHSV
* An extension of MaterialDialog's CircleView with animation selection
* [https://github.com/afollestad/material-dialogs/blob/master/commons/src/main/java/com/afollestad/materialdialogs/color/CircleView.java]
*/
-class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr) {
+class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
+ FrameLayout(context, attrs, defStyleAttr) {
private val borderWidthMicro: Float = context.getDip(1f)
private val borderWidthSmall: Float = context.getDip(3f)
@@ -108,14 +124,14 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet
fun animateSelected(selected: Boolean) {
if (this.selected == selected) return
this.selected = selected // We need to draw the other bands
- val range = if (selected) Pair(-borderWidthSmall, borderWidthLarge) else Pair(borderWidthLarge, -borderWidthSmall)
+ val range =
+ if (selected) Pair(-borderWidthSmall, borderWidthLarge) else Pair(borderWidthLarge, -borderWidthSmall)
ValueAnimator.ofFloat(range.first, range.second).apply {
reverse()
duration = 150L
addUpdateListener { animation ->
whiteOuterBound = animation.animatedValue as Float
invalidate()
-
}
start()
}
@@ -137,12 +153,22 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet
if (whiteRadius >= centerWidth) {
canvas.drawCircle(centerWidth, centerHeight, centerWidth, whitePaint)
} else {
- canvas.drawCircle(centerWidth, centerHeight, if (withBorder) centerWidth - borderWidthMicro else centerWidth, outerPaint)
+ canvas.drawCircle(
+ centerWidth,
+ centerHeight,
+ if (withBorder) centerWidth - borderWidthMicro else centerWidth,
+ outerPaint
+ )
canvas.drawCircle(centerWidth, centerHeight, whiteRadius, whitePaint)
}
canvas.drawCircle(centerWidth, centerHeight, innerRadius, innerPaint)
} else {
- canvas.drawCircle(centerWidth, centerHeight, if (withBorder) centerWidth - borderWidthMicro else centerWidth, innerPaint)
+ canvas.drawCircle(
+ centerWidth,
+ centerHeight,
+ if (withBorder) centerWidth - borderWidthMicro else centerWidth,
+ innerPaint
+ )
}
}
@@ -169,11 +195,13 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet
referenceX = screenWidth - referenceX // mirror
}
val cheatSheet = Toast
- .makeText(context, String.format("#%06X", 0xFFFFFF and color), Toast.LENGTH_SHORT)
+ .makeText(context, String.format("#%06X", 0xFFFFFF and color), Toast.LENGTH_SHORT)
if (midy < displayFrame.height()) {
// Show along the top; follow action buttons
- cheatSheet.setGravity(Gravity.TOP or GravityCompat.END, referenceX,
- screenPos[1] + height - displayFrame.top)
+ cheatSheet.setGravity(
+ Gravity.TOP or GravityCompat.END, referenceX,
+ screenPos[1] + height - displayFrame.top
+ )
} else {
// Show along the bottom center
cheatSheet.setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, height)
@@ -194,8 +222,10 @@ class CircleView @JvmOverloads constructor(context: Context, attrs: AttributeSet
}
@ColorInt
- fun shiftColor(@ColorInt color: Int,
- @FloatRange(from = 0.0, to = 2.0) by: Float): Int {
+ fun shiftColor(
+ @ColorInt color: Int,
+ @FloatRange(from = 0.0, to = 2.0) by: Float
+ ): Int {
if (by == 1f) return color
val hsv = color.toHSV()
hsv[2] *= by // value component
diff --git a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPalette.kt b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPalette.kt
index 68e3461..113020c 100644
--- a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPalette.kt
+++ b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPalette.kt
@@ -1,37 +1,56 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.colorpicker
import android.graphics.Color
/**
* @author Aidan Follestad (afollestad)
+ *
+ * Modified by Allan Wang
*/
internal object ColorPalette {
val PRIMARY_COLORS: IntArray by lazy {
colorArrayOf(
- "#F44336",
- "#E91E63",
- "#9C27B0",
- "#673AB7",
- "#3F51B5",
- "#2196F3",
- "#03A9F4",
- "#00BCD4",
- "#009688",
- "#4CAF50",
- "#8BC34A",
- "#CDDC39",
- "#FFEB3B",
- "#FFC107",
- "#FF9800",
- "#FF5722",
- "#795548",
- "#9E9E9E",
- "#607D8B")
+ "#F44336",
+ "#E91E63",
+ "#9C27B0",
+ "#673AB7",
+ "#3F51B5",
+ "#2196F3",
+ "#03A9F4",
+ "#00BCD4",
+ "#009688",
+ "#4CAF50",
+ "#8BC34A",
+ "#CDDC39",
+ "#FFEB3B",
+ "#FFC107",
+ "#FF9800",
+ "#FF5722",
+ "#795548",
+ "#9E9E9E",
+ "#607D8B"
+ )
}
val PRIMARY_COLORS_SUB: Array<IntArray> by lazy {
- arrayOf(colorArrayOf(
+ arrayOf(
+ colorArrayOf(
"#FFEBEE",
"#FFCDD2",
"#EF9A9A",
@@ -42,7 +61,7 @@ internal object ColorPalette {
"#D32F2F",
"#C62828",
"#B71C1C"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FCE4EC",
"#F8BBD0",
"#F48FB1",
@@ -53,7 +72,7 @@ internal object ColorPalette {
"#C2185B",
"#AD1457",
"#880E4F"
- ), colorArrayOf(
+ ), colorArrayOf(
"#F3E5F5",
"#E1BEE7",
"#CE93D8",
@@ -64,7 +83,7 @@ internal object ColorPalette {
"#7B1FA2",
"#6A1B9A",
"#4A148C"
- ), colorArrayOf(
+ ), colorArrayOf(
"#EDE7F6",
"#D1C4E9",
"#B39DDB",
@@ -75,7 +94,7 @@ internal object ColorPalette {
"#512DA8",
"#4527A0",
"#311B92"
- ), colorArrayOf(
+ ), colorArrayOf(
"#E8EAF6",
"#C5CAE9",
"#9FA8DA",
@@ -86,7 +105,7 @@ internal object ColorPalette {
"#303F9F",
"#283593",
"#1A237E"
- ), colorArrayOf(
+ ), colorArrayOf(
"#E3F2FD",
"#BBDEFB",
"#90CAF9",
@@ -97,7 +116,7 @@ internal object ColorPalette {
"#1976D2",
"#1565C0",
"#0D47A1"
- ), colorArrayOf(
+ ), colorArrayOf(
"#E1F5FE",
"#B3E5FC",
"#81D4FA",
@@ -108,7 +127,7 @@ internal object ColorPalette {
"#0288D1",
"#0277BD",
"#01579B"
- ), colorArrayOf(
+ ), colorArrayOf(
"#E0F7FA",
"#B2EBF2",
"#80DEEA",
@@ -119,7 +138,7 @@ internal object ColorPalette {
"#0097A7",
"#00838F",
"#006064"
- ), colorArrayOf(
+ ), colorArrayOf(
"#E0F2F1",
"#B2DFDB",
"#80CBC4",
@@ -130,7 +149,7 @@ internal object ColorPalette {
"#00796B",
"#00695C",
"#004D40"
- ), colorArrayOf(
+ ), colorArrayOf(
"#E8F5E9",
"#C8E6C9",
"#A5D6A7",
@@ -141,7 +160,7 @@ internal object ColorPalette {
"#388E3C",
"#2E7D32",
"#1B5E20"
- ), colorArrayOf(
+ ), colorArrayOf(
"#F1F8E9",
"#DCEDC8",
"#C5E1A5",
@@ -152,7 +171,7 @@ internal object ColorPalette {
"#689F38",
"#558B2F",
"#33691E"
- ), colorArrayOf(
+ ), colorArrayOf(
"#F9FBE7",
"#F0F4C3",
"#E6EE9C",
@@ -163,7 +182,7 @@ internal object ColorPalette {
"#AFB42B",
"#9E9D24",
"#827717"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FFFDE7",
"#FFF9C4",
"#FFF59D",
@@ -174,7 +193,7 @@ internal object ColorPalette {
"#FBC02D",
"#F9A825",
"#F57F17"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FFF8E1",
"#FFECB3",
"#FFE082",
@@ -185,7 +204,7 @@ internal object ColorPalette {
"#FFA000",
"#FF8F00",
"#FF6F00"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FFF3E0",
"#FFE0B2",
"#FFCC80",
@@ -196,7 +215,7 @@ internal object ColorPalette {
"#F57C00",
"#EF6C00",
"#E65100"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FBE9E7",
"#FFCCBC",
"#FFAB91",
@@ -207,7 +226,7 @@ internal object ColorPalette {
"#E64A19",
"#D84315",
"#BF360C"
- ), colorArrayOf(
+ ), colorArrayOf(
"#EFEBE9",
"#D7CCC8",
"#BCAAA4",
@@ -218,7 +237,7 @@ internal object ColorPalette {
"#5D4037",
"#4E342E",
"#3E2723"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FAFAFA",
"#F5F5F5",
"#EEEEEE",
@@ -229,7 +248,7 @@ internal object ColorPalette {
"#616161",
"#424242",
"#212121"
- ), colorArrayOf(
+ ), colorArrayOf(
"#ECEFF1",
"#CFD8DC",
"#B0BEC5",
@@ -239,111 +258,117 @@ internal object ColorPalette {
"#546E7A",
"#455A64",
"#37474F",
- "#263238"))
+ "#263238"
+ )
+ )
}
val ACCENT_COLORS: IntArray by lazy {
colorArrayOf(
- "#FF1744",
- "#F50057",
- "#D500F9",
- "#651FFF",
- "#3D5AFE",
- "#2979FF",
- "#00B0FF",
- "#00E5FF",
- "#1DE9B6",
- "#00E676",
- "#76FF03",
- "#C6FF00",
- "#FFEA00",
- "#FFC400",
- "#FF9100",
- "#FF3D00")
+ "#FF1744",
+ "#F50057",
+ "#D500F9",
+ "#651FFF",
+ "#3D5AFE",
+ "#2979FF",
+ "#00B0FF",
+ "#00E5FF",
+ "#1DE9B6",
+ "#00E676",
+ "#76FF03",
+ "#C6FF00",
+ "#FFEA00",
+ "#FFC400",
+ "#FF9100",
+ "#FF3D00"
+ )
}
val ACCENT_COLORS_SUB: Array<IntArray> by lazy {
- arrayOf(colorArrayOf("#FF8A80",
+ arrayOf(
+ colorArrayOf(
+ "#FF8A80",
"#FF5252",
"#FF1744",
"#D50000"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FF80AB",
"#FF4081",
"#F50057",
"#C51162"
- ), colorArrayOf(
+ ), colorArrayOf(
"#EA80FC",
"#E040FB",
"#D500F9",
"#AA00FF"
- ), colorArrayOf(
+ ), colorArrayOf(
"#B388FF",
"#7C4DFF",
"#651FFF",
"#6200EA"
- ), colorArrayOf(
+ ), colorArrayOf(
"#8C9EFF",
"#536DFE",
"#3D5AFE",
"#304FFE"
- ), colorArrayOf(
+ ), colorArrayOf(
"#82B1FF",
"#448AFF",
"#2979FF",
"#2962FF"
- ), colorArrayOf(
+ ), colorArrayOf(
"#80D8FF",
"#40C4FF",
"#00B0FF",
"#0091EA"
- ), colorArrayOf(
+ ), colorArrayOf(
"#84FFFF",
"#18FFFF",
"#00E5FF",
"#00B8D4"
- ), colorArrayOf(
+ ), colorArrayOf(
"#A7FFEB",
"#64FFDA",
"#1DE9B6",
"#00BFA5"
- ), colorArrayOf(
+ ), colorArrayOf(
"#B9F6CA",
"#69F0AE",
"#00E676",
"#00C853"
- ), colorArrayOf(
+ ), colorArrayOf(
"#CCFF90",
"#B2FF59",
"#76FF03",
"#64DD17"
- ), colorArrayOf(
+ ), colorArrayOf(
"#F4FF81",
"#EEFF41",
"#C6FF00",
"#AEEA00"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FFFF8D",
"#FFFF00",
"#FFEA00",
"#FFD600"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FFE57F",
"#FFD740",
"#FFC400",
"#FFAB00"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FFD180",
"#FFAB40",
"#FF9100",
"#FF6D00"
- ), colorArrayOf(
+ ), colorArrayOf(
"#FF9E80",
"#FF6E40",
"#FF3D00",
- "#DD2C00"))
+ "#DD2C00"
+ )
+ )
}
private fun colorArrayOf(vararg colors: String) = colors.map { Color.parseColor(it) }.toIntArray()
}
-
diff --git a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt
index b264e58..02a1fff 100644
--- a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt
+++ b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerDialog.kt
@@ -1,89 +1,66 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.colorpicker
-import android.content.Context
+import android.annotation.SuppressLint
import android.graphics.Color
-import android.support.annotation.DimenRes
-import android.support.annotation.StringRes
-import ca.allanwang.kau.utils.INVALID_ID
-import ca.allanwang.kau.utils.string
+import androidx.annotation.ColorInt
import com.afollestad.materialdialogs.MaterialDialog
-import com.afollestad.materialdialogs.Theme
+import com.afollestad.materialdialogs.color.ColorCallback
+import com.afollestad.materialdialogs.color.colorChooser
+
+sealed class ColorOptions(val colors: IntArray, val subColors: Array<IntArray>?)
+
+object PrimaryColors : ColorOptions(ColorPalette.PRIMARY_COLORS, ColorPalette.PRIMARY_COLORS_SUB)
+object AccentColors : ColorOptions(ColorPalette.ACCENT_COLORS, ColorPalette.ACCENT_COLORS_SUB)
+class CustomColors(colors: IntArray, subColors: Array<IntArray>? = null) : ColorOptions(colors, subColors)
class ColorBuilder : ColorContract {
- override var title: String? = null
- override var titleRes: Int = INVALID_ID
+ override var colors: ColorOptions = PrimaryColors
override var allowCustom: Boolean = true
override var allowCustomAlpha: Boolean = false
- override var isAccent: Boolean = false
override var defaultColor: Int = Color.BLACK
- override var doneText: Int = R.string.kau_done
- override var backText: Int = R.string.kau_back
- override var cancelText: Int = R.string.kau_cancel
- override var presetText: Int = R.string.kau_md_presets
- override var customText: Int = R.string.kau_custom
- get() = if (allowCustom) field else 0
- override var dynamicButtonColors: Boolean = true
- override var circleSizeRes: Int = R.dimen.kau_color_circle_size
- override var colorCallback: ((selectedColor: Int) -> Unit)? = null
- override var colorsTop: IntArray? = null
- override var colorsSub: Array<IntArray>? = null
- override var theme: Theme? = null
+ override var callback: ColorCallback = null
}
interface ColorContract {
- var title: String?
- @setparam:StringRes
- var titleRes: Int
+ var colors: ColorOptions
var allowCustom: Boolean
var allowCustomAlpha: Boolean
- var isAccent: Boolean
- @setparam:StringRes
+ @setparam:ColorInt
var defaultColor: Int
- @setparam:StringRes
- var doneText: Int
- @setparam:StringRes
- var backText: Int
- @setparam:StringRes
- var cancelText: Int
- @setparam:StringRes
- var presetText: Int
- @setparam:StringRes
- var customText: Int
- var dynamicButtonColors: Boolean
- @setparam:DimenRes
- var circleSizeRes: Int
- var colorCallback: ((selectedColor: Int) -> Unit)?
- var colorsTop: IntArray?
- var colorsSub: Array<IntArray>?
- var theme: Theme?
+ var callback: ColorCallback
}
+@SuppressLint("CheckResult")
+fun MaterialDialog.kauColorChooser(action: ColorContract.() -> Unit) =
+ kauColorChooser(ColorBuilder().apply(action))
+
/**
- * This is the extension that allows us to initialize the dialog
- * Note that this returns just the dialog; you still need to call .show() to show it
+ * Thin wrapper that exposes color chooser options as [ColorContract]
*/
-fun Context.colorPickerDialog(action: ColorContract.() -> Unit): MaterialDialog {
- val b = ColorBuilder()
- b.action()
- return colorPickerDialog(b)
-}
-
-fun Context.colorPickerDialog(contract: ColorContract): MaterialDialog {
- val view = ColorPickerView(this)
- val dialog = with(MaterialDialog.Builder(this)) {
- title(string(contract.titleRes, contract.title) ?: string(R.string.kau_md_color_palette))
- customView(view, false)
- autoDismiss(false)
- positiveText(contract.doneText)
- negativeText(contract.cancelText)
- if (contract.allowCustom) neutralText(contract.presetText)
- onPositive { dialog, _ -> contract.colorCallback?.invoke(view.selectedColor); dialog.dismiss() }
- onNegative { _, _ -> view.backOrCancel() }
- if (contract.allowCustom) onNeutral { _, _ -> view.toggleCustom() }
- showListener { view.refreshColors() }
- if (contract.theme != null) theme(contract.theme!!)
- build()
- }
- view.bind(contract, dialog)
- return dialog
+@SuppressLint("CheckResult")
+fun MaterialDialog.kauColorChooser(c: ColorContract) {
+ colorChooser(
+ colors = c.colors.colors,
+ subColors = c.colors.subColors,
+ initialSelection = c.defaultColor,
+ allowCustomArgb = c.allowCustom,
+ showAlphaSelector = c.allowCustomAlpha,
+ selection = c.callback
+ )
+ positiveButton(R.string.kau_done)
} \ No newline at end of file
diff --git a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerView.kt b/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerView.kt
deleted file mode 100644
index b9cea99..0000000
--- a/colorpicker/src/main/kotlin/ca/allanwang/kau/colorpicker/ColorPickerView.kt
+++ /dev/null
@@ -1,319 +0,0 @@
-package ca.allanwang.kau.colorpicker
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.graphics.Color
-import android.support.annotation.ColorInt
-import android.support.v4.content.res.ResourcesCompat
-import android.text.Editable
-import android.text.InputFilter
-import android.text.TextWatcher
-import android.util.AttributeSet
-import android.view.View
-import android.view.ViewGroup
-import android.widget.*
-import ca.allanwang.kau.utils.*
-import com.afollestad.materialdialogs.DialogAction
-import com.afollestad.materialdialogs.MaterialDialog
-import com.afollestad.materialdialogs.color.FillGridView
-import java.util.*
-
-/**
- * Created by Allan Wang on 2017-06-08.
- *
- * ColorPicker component of the ColorPickerDialog
- */
-internal class ColorPickerView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
-) : ScrollView(context, attrs, defStyleAttr) {
- val selectedColor: Int
- get() = _selectedColor
- private var _selectedColor: Int = -1
- private var isInSub: Boolean = false
- private var isInCustom: Boolean = false
- private var circleSize: Int = context.dimen(R.dimen.kau_color_circle_size).toInt()
- @SuppressLint("PrivateResource")
- private val backgroundColor = context.resolveColor(R.attr.md_background_color,
- if (context.resolveColor(android.R.attr.textColorPrimary).isColorDark) Color.WHITE else 0xff424242.toInt())
- private val backgroundColorTint = backgroundColor.colorToForeground()
- private lateinit var dialog: MaterialDialog
- private lateinit var builder: ColorContract
- private lateinit var colorsTop: IntArray
- private var colorsSub: Array<IntArray>? = null
- private var topIndex: Int = -1
- private var subIndex: Int = -1
- private var colorIndex: Int
- get() = if (isInSub) subIndex else topIndex
- set(value) {
- if (isInSub) subIndex = value
- else {
- topIndex = value
- if (colorsSub != null && colorsSub!!.size > value) {
- dialog.setActionButton(DialogAction.NEGATIVE, builder.backText)
- isInSub = true
- invalidateGrid()
- }
- }
- }
-
- private val gridView: FillGridView
- private val customFrame: LinearLayout
- private val customColorIndicator: View
- private val hexInput: EditText
- private val alphaLabel: TextView
- private val alphaSeekbar: SeekBar
- private val alphaValue: TextView
- private val redSeekbar: SeekBar
- private val redValue: TextView
- private val greenSeekbar: SeekBar
- private val greenValue: TextView
- private val blueSeekbar: SeekBar
- private val blueValue: TextView
-
- private var customHexTextWatcher: TextWatcher? = null
- private var customRgbListener: SeekBar.OnSeekBarChangeListener? = null
-
- init {
- //noinspection PrivateResource
- View.inflate(context, R.layout.md_dialog_colorchooser, this)
- gridView = findViewById(R.id.md_grid)
- customFrame = findViewById(R.id.md_colorChooserCustomFrame)
- customColorIndicator = findViewById(R.id.md_colorIndicator)
- hexInput = findViewById(R.id.md_hexInput)
- alphaLabel = findViewById(R.id.md_colorALabel)
- alphaSeekbar = findViewById(R.id.md_colorA)
- alphaValue = findViewById(R.id.md_colorAValue)
- redSeekbar = findViewById(R.id.md_colorR)
- redValue = findViewById(R.id.md_colorRValue)
- greenSeekbar = findViewById(R.id.md_colorG)
- greenValue = findViewById(R.id.md_colorGValue)
- blueSeekbar = findViewById(R.id.md_colorB)
- blueValue = findViewById(R.id.md_colorBValue)
- }
-
- fun bind(builder: ColorContract, dialog: MaterialDialog) {
- this.builder = builder
- this.dialog = dialog
- this.colorsTop = with(builder) {
- when {
- colorsTop != null -> colorsTop!!
- isAccent -> ColorPalette.ACCENT_COLORS
- else -> ColorPalette.PRIMARY_COLORS
- }
- }
- this.colorsSub = with(builder) {
- when {
- colorsTop != null -> colorsSub
- isAccent -> ColorPalette.ACCENT_COLORS_SUB
- else -> ColorPalette.PRIMARY_COLORS_SUB
- }
- }
- this._selectedColor = builder.defaultColor
- if (builder.allowCustom) {
- if (!builder.allowCustomAlpha) {
- alphaLabel.gone()
- alphaSeekbar.gone()
- alphaValue.gone()
- hexInput.hint = String.format("%06X", _selectedColor)
- hexInput.filters = arrayOf(InputFilter.LengthFilter(6))
- } else {
- hexInput.hint = String.format("%08X", _selectedColor)
- hexInput.filters = arrayOf(InputFilter.LengthFilter(8))
- }
- }
- if (findColor(_selectedColor) || !builder.allowCustom) isInCustom = true // when toggled this will be false
- toggleCustom()
- }
-
- fun backOrCancel() {
- if (isInSub) {
- dialog.setActionButton(DialogAction.NEGATIVE, builder.cancelText)
- //to top
- isInSub = false
- subIndex = -1
- invalidateGrid()
- } else {
- dialog.cancel()
- }
- }
-
- fun toggleCustom() {
- isInCustom = !isInCustom
- if (isInCustom) {
- isInSub = false
- if (builder.allowCustom) dialog.setActionButton(DialogAction.NEUTRAL, builder.presetText)
- dialog.setActionButton(DialogAction.NEGATIVE, builder.cancelText)
- customHexTextWatcher = object : TextWatcher {
- override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
-
- override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
- _selectedColor = try {
- Color.parseColor("#$s")
- } catch (e: IllegalArgumentException) {
- Color.BLACK
- }
- customColorIndicator.setBackgroundColor(_selectedColor)
- if (alphaSeekbar.isVisible) {
- val alpha = Color.alpha(_selectedColor)
- alphaSeekbar.progress = alpha
- alphaValue.text = String.format(Locale.CANADA, "%d", alpha)
- }
- redSeekbar.progress = Color.red(_selectedColor)
- greenSeekbar.progress = Color.green(_selectedColor)
- blueSeekbar.progress = Color.blue(_selectedColor)
- isInSub = false
- topIndex = -1
- subIndex = -1
- refreshColors()
- }
-
- override fun afterTextChanged(s: Editable?) {}
- }
- hexInput.setText(_selectedColor.toHexString(builder.allowCustomAlpha, false))
- hexInput.addTextChangedListener(customHexTextWatcher)
- customRgbListener = object : SeekBar.OnSeekBarChangeListener {
- override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
- if (fromUser) {
- val color = if (builder.allowCustomAlpha)
- Color.argb(alphaSeekbar.progress,
- redSeekbar.progress,
- greenSeekbar.progress,
- blueSeekbar.progress)
- else Color.rgb(redSeekbar.progress,
- greenSeekbar.progress,
- blueSeekbar.progress)
-
- hexInput.setText(color.toHexString(builder.allowCustomAlpha, false))
- }
- if (builder.allowCustomAlpha) alphaValue.text = alphaSeekbar.progress.toString()
- redValue.text = redSeekbar.progress.toString()
- greenValue.text = greenSeekbar.progress.toString()
- blueValue.text = blueSeekbar.progress.toString()
- }
-
- override fun onStartTrackingTouch(seekBar: SeekBar) = Unit
-
- override fun onStopTrackingTouch(seekBar: SeekBar) = Unit
- }
- redSeekbar.setOnSeekBarChangeListener(customRgbListener)
- greenSeekbar.setOnSeekBarChangeListener(customRgbListener)
- blueSeekbar.setOnSeekBarChangeListener(customRgbListener)
- if (alphaSeekbar.isVisible)
- alphaSeekbar.setOnSeekBarChangeListener(customRgbListener)
- hexInput.setText(_selectedColor.toHexString(alphaSeekbar.isVisible, false))
- gridView.fadeOut(onFinish = { gridView.gone() })
- customFrame.fadeIn()
- } else {
- findColor(_selectedColor)
- if (builder.allowCustom) dialog.setActionButton(DialogAction.NEUTRAL, builder.customText)
- dialog.setActionButton(DialogAction.NEGATIVE, if (isInSub) builder.backText else builder.cancelText)
- gridView.fadeIn(onStart = this::invalidateGrid)
- customFrame.fadeOut(onFinish = { customFrame.gone() })
- hexInput.removeTextChangedListener(customHexTextWatcher)
- customHexTextWatcher = null
- alphaSeekbar.setOnSeekBarChangeListener(null)
- redSeekbar.setOnSeekBarChangeListener(null)
- greenSeekbar.setOnSeekBarChangeListener(null)
- blueSeekbar.setOnSeekBarChangeListener(null)
- customRgbListener = null
- }
- }
-
- fun refreshColors() {
- if (!isInCustom) findColor(_selectedColor)
- // Ensure that our tinted color is still visible against the background
- val visibleColor = if (_selectedColor.isColorVisibleOn(backgroundColor)) _selectedColor else backgroundColorTint
- if (builder.dynamicButtonColors) {
- dialog.getActionButton(DialogAction.POSITIVE).setTextColor(visibleColor)
- dialog.getActionButton(DialogAction.NEGATIVE).setTextColor(visibleColor)
- dialog.getActionButton(DialogAction.NEUTRAL).setTextColor(visibleColor)
- }
- if (!builder.allowCustom || !isInCustom) return
- if (builder.allowCustomAlpha)
- alphaSeekbar.visible().tint(visibleColor)
- redSeekbar.tint(visibleColor)
- greenSeekbar.tint(visibleColor)
- blueSeekbar.tint(visibleColor)
- hexInput.tint(visibleColor)
- }
-
- private fun findColor(@ColorInt color: Int): Boolean {
- topIndex = -1
- subIndex = -1
- colorsTop.forEachIndexed { index, topColor ->
- // First check for sub colors, then if the top color matches
- if (findSubColor(color, index) || topColor == color) {
- topIndex = index
- return true
- }
- }
- return false
- }
-
- private fun findSubColor(@ColorInt color: Int, topIndex: Int): Boolean {
- subIndex = colorsSub?.getOrNull(topIndex)?.indexOfFirst { color == it } ?: -1
- return subIndex != -1
- }
-
- private fun invalidateGrid() {
- if (gridView.adapter == null) {
- gridView.adapter = ColorGridAdapter()
- gridView.selector = ResourcesCompat.getDrawable(resources, R.drawable.kau_transparent, null)
- } else {
- (gridView.adapter as BaseAdapter).notifyDataSetChanged()
- }
- }
-
- inner class ColorGridAdapter : BaseAdapter(), OnClickListener, OnLongClickListener {
- override fun onClick(v: View) {
- val (pos, color) = v.tagData ?: return
- if (colorIndex == pos && isInSub)
- return
- circleAt(colorIndex)?.animateSelected(false)
- _selectedColor = color
- colorIndex = pos
- refreshColors()
- if (isInSub)
- circleAt(colorIndex)?.animateSelected(true)
- // Otherwise we are invalidating our grid, so there is no point in animating
- }
-
- private fun circleAt(index: Int): CircleView? =
- if (index == -1) null
- else gridView.getChildAt(index) as? CircleView
-
- private val View.tagData: Pair<Int, Int>?
- get() {
- val tags = (tag as? String)?.split(":") ?: return null
- val pos = tags[0].toIntOrNull() ?: return null
- val color = tags[1].toIntOrNull() ?: return null
- return pos to color
- }
-
- override fun onLongClick(v: View): Boolean {
- val (_, color) = v.tagData ?: return false
- (v as? CircleView)?.showHint(color) ?: return false
- return true
- }
-
- override fun getItem(position: Int): Int = if (isInSub) colorsSub!![topIndex][position] else colorsTop[position]
-
- override fun getCount(): Int = if (isInSub) colorsSub!![topIndex].size else colorsTop.size
-
- override fun getItemId(position: Int): Long = position.toLong()
-
- override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
- val view: CircleView = convertView as? CircleView ?: CircleView(context).apply {
- layoutParams = AbsListView.LayoutParams(circleSize, circleSize)
- setOnClickListener(this@ColorGridAdapter)
- setOnLongClickListener(this@ColorGridAdapter)
- }
- val color: Int = getItem(position)
- return view.apply {
- setBackgroundColor(color)
- isSelected = colorIndex == position
- tag = "$position:$color"
- }
- }
- }
-} \ No newline at end of file
diff --git a/colorpicker/src/main/res/values-da-rDK/strings_colorpicker.xml b/colorpicker/src/main/res/values-da-rDK/strings_colorpicker.xml
deleted file mode 100644
index a5f7487..0000000
--- a/colorpicker/src/main/res/values-da-rDK/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Farvepalette</string>
- <string name="kau_md_presets">Forhåndsvalg</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-de-rDE/strings_colorpicker.xml b/colorpicker/src/main/res/values-de-rDE/strings_colorpicker.xml
deleted file mode 100644
index 5dd7b38..0000000
--- a/colorpicker/src/main/res/values-de-rDE/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Farbpalette</string>
- <string name="kau_md_presets">Vorlagen</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-es-rES/strings_colorpicker.xml b/colorpicker/src/main/res/values-es-rES/strings_colorpicker.xml
deleted file mode 100644
index 56148fd..0000000
--- a/colorpicker/src/main/res/values-es-rES/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Paleta de colores</string>
- <string name="kau_md_presets">Ajustes preestablecidos</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-fr-rFR/strings_colorpicker.xml b/colorpicker/src/main/res/values-fr-rFR/strings_colorpicker.xml
deleted file mode 100644
index a044e6e..0000000
--- a/colorpicker/src/main/res/values-fr-rFR/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Palette de couleurs</string>
- <string name="kau_md_presets">Réglages prédéfinis</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-gl-rES/strings_colorpicker.xml b/colorpicker/src/main/res/values-gl-rES/strings_colorpicker.xml
deleted file mode 100644
index fbc1d90..0000000
--- a/colorpicker/src/main/res/values-gl-rES/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Paleta de cores</string>
- <string name="kau_md_presets">Axustes predefinidos</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-hu-rHU/strings_colorpicker.xml b/colorpicker/src/main/res/values-hu-rHU/strings_colorpicker.xml
deleted file mode 100644
index 42f3700..0000000
--- a/colorpicker/src/main/res/values-hu-rHU/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Színpaletta</string>
- <string name="kau_md_presets">Sablonok</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-in-rID/strings_colorpicker.xml b/colorpicker/src/main/res/values-in-rID/strings_colorpicker.xml
deleted file mode 100644
index 52e59bc..0000000
--- a/colorpicker/src/main/res/values-in-rID/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Palet warna</string>
- <string name="kau_md_presets">Preset</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-it-rIT/strings_colorpicker.xml b/colorpicker/src/main/res/values-it-rIT/strings_colorpicker.xml
deleted file mode 100644
index 4f3e282..0000000
--- a/colorpicker/src/main/res/values-it-rIT/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Tavolozza dei colori</string>
- <string name="kau_md_presets">Preimpostazioni</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-ko-rKR/strings_colorpicker.xml b/colorpicker/src/main/res/values-ko-rKR/strings_colorpicker.xml
deleted file mode 100644
index 7c65db1..0000000
--- a/colorpicker/src/main/res/values-ko-rKR/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">색상 팔레트</string>
- <string name="kau_md_presets">사전 설정</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-no-rNO/strings_colorpicker.xml b/colorpicker/src/main/res/values-no-rNO/strings_colorpicker.xml
deleted file mode 100644
index d79a6d8..0000000
--- a/colorpicker/src/main/res/values-no-rNO/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Fargepalett</string>
- <string name="kau_md_presets">Forhåndsinnstillinger</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-pl-rPL/strings_colorpicker.xml b/colorpicker/src/main/res/values-pl-rPL/strings_colorpicker.xml
deleted file mode 100644
index 42cb6e0..0000000
--- a/colorpicker/src/main/res/values-pl-rPL/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Paleta kolorów</string>
- <string name="kau_md_presets">Zdefiniowane</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-pt-rBR/strings_colorpicker.xml b/colorpicker/src/main/res/values-pt-rBR/strings_colorpicker.xml
deleted file mode 100644
index 0694ed4..0000000
--- a/colorpicker/src/main/res/values-pt-rBR/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Paleta de Cores</string>
- <string name="kau_md_presets">Predefinições</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-sv-rSE/strings_colorpicker.xml b/colorpicker/src/main/res/values-sv-rSE/strings_colorpicker.xml
deleted file mode 100644
index 6b06ba9..0000000
--- a/colorpicker/src/main/res/values-sv-rSE/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Färgpalett</string>
- <string name="kau_md_presets">Förval</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-th-rTH/strings_colorpicker.xml b/colorpicker/src/main/res/values-th-rTH/strings_colorpicker.xml
deleted file mode 100644
index 7fdf610..0000000
--- a/colorpicker/src/main/res/values-th-rTH/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">ชุดสี</string>
- <string name="kau_md_presets">ค่าที่ตั้งไว้</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-tr-rTR/strings_colorpicker.xml b/colorpicker/src/main/res/values-tr-rTR/strings_colorpicker.xml
deleted file mode 100644
index eddc8ad..0000000
--- a/colorpicker/src/main/res/values-tr-rTR/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Renk paleti</string>
- <string name="kau_md_presets">Hazır ayarlar</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-uk-rUA/strings_colorpicker.xml b/colorpicker/src/main/res/values-uk-rUA/strings_colorpicker.xml
deleted file mode 100644
index d114ba5..0000000
--- a/colorpicker/src/main/res/values-uk-rUA/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Кольорова палітра</string>
- <string name="kau_md_presets">Пресети</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-vi-rVN/strings_colorpicker.xml b/colorpicker/src/main/res/values-vi-rVN/strings_colorpicker.xml
deleted file mode 100644
index f14a044..0000000
--- a/colorpicker/src/main/res/values-vi-rVN/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Bảng màu</string>
- <string name="kau_md_presets">Cài đặt sẵn</string>
-</resources>
diff --git a/colorpicker/src/main/res/values-zh-rCN/strings_colorpicker.xml b/colorpicker/src/main/res/values-zh-rCN/strings_colorpicker.xml
deleted file mode 100644
index 9b117f5..0000000
--- a/colorpicker/src/main/res/values-zh-rCN/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com-->
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">调色板</string>
- <string name="kau_md_presets">预设</string>
-</resources>
diff --git a/colorpicker/src/main/res/values/dimens.xml b/colorpicker/src/main/res/values/dimens.xml
deleted file mode 100644
index 193940e..0000000
--- a/colorpicker/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<resources>
- <dimen name="kau_color_circle_size">56dp</dimen>
-</resources>
diff --git a/colorpicker/src/main/res/values/strings_colorpicker.xml b/colorpicker/src/main/res/values/strings_colorpicker.xml
deleted file mode 100644
index a470390..0000000
--- a/colorpicker/src/main/res/values/strings_colorpicker.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName">
- <string name="kau_md_color_palette">Color Palette</string>
- <string name="kau_md_presets">Presets</string>
-</resources>
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt
index 3951970..aff4d1c 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/activities/ElasticRecyclerActivity.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.activities
import android.os.Build
import android.os.Bundle
-import android.support.annotation.RequiresApi
-import android.support.v7.widget.RecyclerView
-import android.support.v7.widget.Toolbar
import android.transition.TransitionInflater
+import androidx.annotation.RequiresApi
+import androidx.appcompat.widget.Toolbar
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.ui.R
import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout
@@ -16,7 +31,7 @@ import kotlinx.android.synthetic.main.kau_elastic_recycler_activity.*
*
* A generic activity comprised of an ElasticDragDismissFrameLayout, CoordinatorLayout, Toolbar, RecyclerView, and Fab
* [ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout]
- * [android.support.v7.widget.RecyclerView]
+ * [androidx.recyclerview.widget.RecyclerView]
*
* The recyclerview defaults to a linearlayoutmanager, and the adapter is automatically bounded
*
@@ -39,10 +54,11 @@ abstract class ElasticRecyclerActivity : KauBaseActivity() {
setContentView(R.layout.kau_elastic_recycler_activity)
setSupportActionBar(kau_toolbar)
if (!onCreate(savedInstanceState, configs)) return
+
kau_draggable.addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(this) {
override fun onDragDismissed() {
window.returnTransition = TransitionInflater.from(this@ElasticRecyclerActivity)
- .inflateTransition(if (kau_draggable.translationY > 0) configs.exitTransitionBottom else configs.exitTransitionTop)
+ .inflateTransition(if (kau_draggable.translationY > 0) configs.exitTransitionBottom else configs.exitTransitionTop)
kau_recycler.stopScroll()
finishAfterTransition()
}
@@ -63,6 +79,4 @@ abstract class ElasticRecyclerActivity : KauBaseActivity() {
fun setOutsideTapListener(listener: () -> Unit) {
kau_draggable.setOnClickListener { listener() }
}
-
}
-
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/BoundedCardView.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/BoundedCardView.kt
index 5fc3e06..9433d17 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/BoundedCardView.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/BoundedCardView.kt
@@ -1,13 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.views
import android.content.Context
import android.graphics.Rect
-import android.support.v7.widget.CardView
import android.util.AttributeSet
+import androidx.cardview.widget.CardView
import ca.allanwang.kau.ui.R
import ca.allanwang.kau.utils.parentViewGroup
-
/**
* Created by Allan Wang on 2017-06-26.
*
@@ -16,7 +30,9 @@ import ca.allanwang.kau.utils.parentViewGroup
* Defaults to at most the parent's visible height
*/
class BoundedCardView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : CardView(context, attrs, defStyleAttr) {
/**
@@ -48,5 +64,4 @@ class BoundedCardView @JvmOverloads constructor(
val trueHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxMeasureHeight, MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, trueHeightMeasureSpec)
}
-
-} \ No newline at end of file
+}
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt
index f6f7864..474d40a 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt
@@ -1,11 +1,11 @@
/*
- * Copyright 2015 Google Inc.
+ * Copyright 2018 Allan Wang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,11 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package ca.allanwang.kau.ui.views
import android.content.Context
-import android.graphics.*
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffXfermode
+import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.text.TextPaint
import android.util.AttributeSet
@@ -32,9 +36,13 @@ import ca.allanwang.kau.utils.toBitmap
/**
* A view which punches out some text from an opaque color block, allowing you to see through it.
+ *
+ * Inspired by <a href="https://github.com/nickbutcher/plaid">Plaid</a>
*/
class CutoutView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
companion object {
@@ -107,8 +115,10 @@ class CutoutView @JvmOverloads constructor(
private fun calculateTextPosition() {
val targetWidth = width / PHI
- textSize = getSingleLineTextSize(text!!, paint, targetWidth, 0f, maxTextSize,
- 0.5f, resources.displayMetrics)
+ textSize = getSingleLineTextSize(
+ text!!, paint, targetWidth, 0f, maxTextSize,
+ 0.5f, resources.displayMetrics
+ )
paint.textSize = textSize
// measuring text is fun :] see: https://chris.banes.me/2014/03/27/measuring-text/
@@ -145,13 +155,15 @@ class CutoutView @JvmOverloads constructor(
* Adapted from https://github.com/grantland/android-autofittextview
*/
- fun getSingleLineTextSize(text: String,
- paint: TextPaint,
- targetWidth: Float,
- low: Float,
- high: Float,
- precision: Float,
- metrics: DisplayMetrics): Float {
+ fun getSingleLineTextSize(
+ text: String,
+ paint: TextPaint,
+ targetWidth: Float,
+ low: Float,
+ high: Float,
+ precision: Float,
+ metrics: DisplayMetrics
+ ): Float {
val mid = (low + high) / 2.0f
paint.textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, metrics)
@@ -180,7 +192,12 @@ class CutoutView @JvmOverloads constructor(
cutoutCanvas.drawText(text!!, cutoutX, cutoutY, paint)
}
TYPE_DRAWABLE -> {
- cutoutCanvas.drawBitmap(drawable!!.toBitmap(bitmapScaling, Bitmap.Config.ALPHA_8), cutoutX, cutoutY, paint)
+ cutoutCanvas.drawBitmap(
+ drawable!!.toBitmap(bitmapScaling, Bitmap.Config.ALPHA_8),
+ cutoutX,
+ cutoutY,
+ paint
+ )
}
TYPE_EMPTY -> {
// do nothing
@@ -193,5 +210,4 @@ class CutoutView @JvmOverloads constructor(
}
override fun hasOverlappingRendering(): Boolean = true
-
}
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/MeasuredImageView.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/MeasuredImageView.kt
index 5db5eaa..ef95ed3 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/MeasuredImageView.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/MeasuredImageView.kt
@@ -1,14 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.views
import android.content.Context
-import android.support.v7.widget.AppCompatImageView
import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatImageView
/**
* Created by Allan Wang on 2017-07-14.
*/
class MeasuredImageView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr), MeasureSpecContract by MeasureSpecDelegate() {
init {
@@ -19,5 +36,4 @@ class MeasuredImageView @JvmOverloads constructor(
val result = onMeasure(this, widthMeasureSpec, heightMeasureSpec)
super.onMeasure(result.first, result.second)
}
-
-} \ No newline at end of file
+}
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt
index f357f79..f4578f2 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt
@@ -1,11 +1,11 @@
/*
- * Copyright 2015 Google Inc.
+ * Copyright 2018 Allan Wang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,22 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package ca.allanwang.kau.ui.widgets
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.os.Build
-import android.support.annotation.RequiresApi
import android.transition.TransitionInflater
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.widget.FrameLayout
+import androidx.annotation.RequiresApi
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.ui.R
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.AnimHolder
+import ca.allanwang.kau.utils.dimen
+import ca.allanwang.kau.utils.dpToPx
+import ca.allanwang.kau.utils.isNavBarOnBottom
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.scaleXY
+import ca.allanwang.kau.utils.statusBarColor
+import ca.allanwang.kau.utils.withAlpha
/**
* A [FrameLayout] which responds to nested scrolls to create drag-dismissable layouts.
@@ -37,7 +43,10 @@ import ca.allanwang.kau.utils.*
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class ElasticDragDismissFrameLayout @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0,
+ defStyleRes: Int = 0
) : FrameLayout(context, attrs, defStyleAttr, defStyleRes) {
// configurable attribs
@@ -62,8 +71,11 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
init {
if (attrs != null) {
val a = getContext().obtainStyledAttributes(attrs, R.styleable.ElasticDragDismissFrameLayout, 0, 0)
- dragDismissDistance = a.getDimensionPixelSize(R.styleable.ElasticDragDismissFrameLayout_dragDismissDistance, Int.MAX_VALUE).toFloat()
- dragDismissFraction = a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragDismissFraction, dragDismissFraction)
+ dragDismissDistance =
+ a.getDimensionPixelSize(R.styleable.ElasticDragDismissFrameLayout_dragDismissDistance, Int.MAX_VALUE)
+ .toFloat()
+ dragDismissFraction =
+ a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragDismissFraction, dragDismissFraction)
dragDismissScale = a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragDismissScale, dragDismissScale)
dragElacticity = a.getFloat(R.styleable.ElasticDragDismissFrameLayout_dragElasticity, dragElacticity)
a.recycle()
@@ -74,27 +86,27 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
/**
* Called for each drag event.
-
- * @param elasticOffset Indicating the drag offset with elasticity applied i.e. may
- * * exceed 1.
- * *
+ * @param elasticOffset Indicating the drag offset with elasticity applied i.e. may exceed 1.
+ *
* @param elasticOffsetPixels The elastically scaled drag distance in pixels.
- * *
- * @param rawOffset Value from [0, 1] indicating the raw drag offset i.e.
- * * without elasticity applied. A value of 1 indicates that the
- * * dismiss distance has been reached.
- * *
- * @param rawOffsetPixels The raw distance the user has dragged
+ *
+ * @param rawOffset Value from [0, 1] indicating the raw drag offset i.e. without elasticity applied.
+ * A value of 1 indicates that the dismiss distance has been reached.
+ *
+ * @param rawOffsetPixels The raw distance the user has dragged
*/
- internal open fun onDrag(elasticOffset: Float, elasticOffsetPixels: Float,
- rawOffset: Float, rawOffsetPixels: Float) {
+ internal open fun onDrag(
+ elasticOffset: Float,
+ elasticOffsetPixels: Float,
+ rawOffset: Float,
+ rawOffsetPixels: Float
+ ) {
}
/**
* Called when dragging is released and has exceeded the threshold dismiss distance.
*/
internal open fun onDragDismissed() {}
-
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
@@ -114,8 +126,13 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
}
}
- override fun onNestedScroll(target: View, dxConsumed: Int, dyConsumed: Int,
- dxUnconsumed: Int, dyUnconsumed: Int) {
+ override fun onNestedScroll(
+ target: View,
+ dxConsumed: Int,
+ dyConsumed: Int,
+ dxUnconsumed: Int,
+ dyUnconsumed: Int
+ ) {
dragScale(dyUnconsumed)
}
@@ -129,12 +146,12 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
scaleXY = 1f
} else {
animate()
- .translationY(0f)
- .scaleXY(1f)
- .setDuration(200L)
- .setInterpolator(AnimHolder.fastOutSlowInInterpolator(context))
- .setListener(null)
- .start()
+ .translationY(0f)
+ .scaleXY(1f)
+ .setDuration(200L)
+ .setInterpolator(AnimHolder.fastOutSlowInInterpolator(context))
+ .setListener(null)
+ .start()
}
totalDrag = 0f
@@ -201,15 +218,23 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
translationY = 0f
scaleXY = 1f
}
- dispatchDragCallback(dragFraction, dragTo,
- Math.min(1f, Math.abs(totalDrag) / dragDismissDistance), totalDrag)
+ dispatchDragCallback(
+ dragFraction, dragTo,
+ Math.min(1f, Math.abs(totalDrag) / dragDismissDistance), totalDrag
+ )
}
- private fun dispatchDragCallback(elasticOffset: Float, elasticOffsetPixels: Float,
- rawOffset: Float, rawOffsetPixels: Float) {
+ private fun dispatchDragCallback(
+ elasticOffset: Float,
+ elasticOffsetPixels: Float,
+ rawOffset: Float,
+ rawOffsetPixels: Float
+ ) {
callbacks.forEach {
- it.onDrag(elasticOffset, elasticOffsetPixels,
- rawOffset, rawOffsetPixels)
+ it.onDrag(
+ elasticOffset, elasticOffsetPixels,
+ rawOffset, rawOffsetPixels
+ )
}
}
@@ -227,8 +252,12 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
private val navBarAlpha: Int = Color.alpha(activity.navigationBarColor)
private val fadeNavBar: Boolean = activity.isNavBarOnBottom
- public override fun onDrag(elasticOffset: Float, elasticOffsetPixels: Float,
- rawOffset: Float, rawOffsetPixels: Float) {
+ public override fun onDrag(
+ elasticOffset: Float,
+ elasticOffsetPixels: Float,
+ rawOffset: Float,
+ rawOffsetPixels: Float
+ ) {
if (elasticOffsetPixels > 0) {
// dragging downward, fade the status bar in proportion
activity.statusBarColor = activity.statusBarColor.withAlpha(((1f - rawOffset) * statusBarAlpha).toInt())
@@ -238,7 +267,8 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
activity.navigationBarColor = activity.navigationBarColor.withAlpha(navBarAlpha)
} else if (fadeNavBar) {
// dragging upward, fade the navigation bar in proportion
- activity.navigationBarColor = activity.navigationBarColor.withAlpha(((1f - rawOffset) * navBarAlpha).toInt())
+ activity.navigationBarColor =
+ activity.navigationBarColor.withAlpha(((1f - rawOffset) * navBarAlpha).toInt())
}
}
@@ -247,15 +277,18 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
}
}
- fun addExitListener(activity: Activity, transitionBottom: Int = R.transition.kau_exit_slide_bottom, transitionTop: Int = R.transition.kau_exit_slide_top) {
+ fun addExitListener(
+ activity: Activity,
+ transitionBottom: Int = R.transition.kau_exit_slide_bottom,
+ transitionTop: Int = R.transition.kau_exit_slide_top
+ ) {
addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(activity) {
override fun onDragDismissed() {
KL.v { "New transition" }
activity.window.returnTransition = TransitionInflater.from(activity)
- .inflateTransition(if (translationY > 0) transitionBottom else transitionTop)
+ .inflateTransition(if (translationY > 0) transitionBottom else transitionTop)
activity.finishAfterTransition()
}
})
}
-
}
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/InkPageIndicator.java b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/InkPageIndicator.java
index a963556..13381aa 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/InkPageIndicator.java
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/InkPageIndicator.java
@@ -27,14 +27,14 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
-import android.support.annotation.ColorInt;
-import android.support.v4.view.ViewPager;
+import androidx.annotation.ColorInt;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Interpolator;
import java.util.Arrays;
+import androidx.viewpager.widget.ViewPager;
import ca.allanwang.kau.ui.R;
import ca.allanwang.kau.utils.AnimHolder;
import ca.allanwang.kau.utils.ColorUtilsKt;
diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/TextSlider.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/TextSlider.kt
index bcd930f..51f7ab9 100644
--- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/TextSlider.kt
+++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/TextSlider.kt
@@ -1,8 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.widgets
import android.content.Context
import android.graphics.Color
-import android.support.v4.widget.TextViewCompat
import android.text.TextUtils
import android.util.AttributeSet
import android.view.Gravity
@@ -10,8 +24,10 @@ import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.TextSwitcher
import android.widget.TextView
+import androidx.core.widget.TextViewCompat
import ca.allanwang.kau.ui.R
-import java.util.*
+import java.util.EmptyStackException
+import java.util.Stack
/**
* Created by Allan Wang on 2017-06-21.
@@ -19,7 +35,9 @@ import java.util.*
* Text switcher with global text color and embedded sliding animations
* Also has a stack to keep track of title changes
*/
-class TextSlider @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null
+class TextSlider @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null
) : TextSwitcher(context, attrs) {
val titleStack: Stack<CharSequence?> = Stack()
@@ -28,20 +46,26 @@ class TextSlider @JvmOverloads constructor(context: Context, attrs: AttributeSet
* Holds a mapping of animation types to their respective animations
*/
val animationMap = mapOf(
- ANIMATION_NONE to null,
- ANIMATION_SLIDE_HORIZONTAL to AnimationBundle(
- R.anim.kau_slide_in_right, R.anim.kau_slide_out_left,
- R.anim.kau_slide_in_left, R.anim.kau_slide_out_right),
- ANIMATION_SLIDE_VERTICAL to AnimationBundle(
- R.anim.kau_slide_in_bottom, R.anim.kau_slide_out_top,
- R.anim.kau_slide_in_top, R.anim.kau_slide_out_bottom
- )
+ ANIMATION_NONE to null,
+ ANIMATION_SLIDE_HORIZONTAL to AnimationBundle(
+ R.anim.kau_slide_in_right, R.anim.kau_slide_out_left,
+ R.anim.kau_slide_in_left, R.anim.kau_slide_out_right
+ ),
+ ANIMATION_SLIDE_VERTICAL to AnimationBundle(
+ R.anim.kau_slide_in_bottom, R.anim.kau_slide_out_top,
+ R.anim.kau_slide_in_top, R.anim.kau_slide_out_bottom
+ )
)
/**
* Holds lazy instances of the animations
*/
- inner class AnimationBundle(private val nextIn: Int, private val nextOut: Int, private val prevIn: Int, private val prevOut: Int) {
+ inner class AnimationBundle(
+ private val nextIn: Int,
+ private val nextOut: Int,
+ private val prevIn: Int,
+ private val prevOut: Int
+ ) {
val NEXT_IN: Animation by lazy { AnimationUtils.loadAnimation(context, nextIn) }
val NEXT_OUT: Animation by lazy { AnimationUtils.loadAnimation(context, nextOut) }
val PREV_IN: Animation by lazy { AnimationUtils.loadAnimation(context, prevIn) }
@@ -122,4 +146,4 @@ class TextSlider @JvmOverloads constructor(context: Context, attrs: AttributeSet
}
}
}
-} \ No newline at end of file
+}
diff --git a/core-ui/src/main/res-public/layout/kau_elastic_recycler_activity.xml b/core-ui/src/main/res-public/layout/kau_elastic_recycler_activity.xml
index 9fbe447..5fc151c 100644
--- a/core-ui/src/main/res-public/layout/kau_elastic_recycler_activity.xml
+++ b/core-ui/src/main/res-public/layout/kau_elastic_recycler_activity.xml
@@ -7,7 +7,7 @@
app:dragDismissDistance="@dimen/kau_drag_dismiss_distance_large"
app:dragDismissScale="0.95">
- <android.support.design.widget.CoordinatorLayout
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/kau_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -15,27 +15,27 @@
android:background="?android:colorBackground"
android:orientation="vertical">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/kau_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/kau_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/kau_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:layoutManager="android.support.v7.widget.LinearLayoutManager"
+ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/kau_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -47,6 +47,6 @@
app:layout_anchor="@id/kau_recycler"
app:layout_anchorGravity="bottom|right|end" />
- </android.support.design.widget.CoordinatorLayout>
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
</ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout> \ No newline at end of file
diff --git a/core-ui/src/main/res-public/layout/kau_recycler_detached_background.xml b/core-ui/src/main/res-public/layout/kau_recycler_detached_background.xml
index 7295d66..2273a20 100644
--- a/core-ui/src/main/res-public/layout/kau_recycler_detached_background.xml
+++ b/core-ui/src/main/res-public/layout/kau_recycler_detached_background.xml
@@ -15,13 +15,13 @@
<!--defaults to a LinearLayoutManager-->
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/kau_recycler_detached"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingBottom="@dimen/kau_spacing_normal"
android:scrollbars="vertical"
- app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
+ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</FrameLayout>
diff --git a/core-ui/src/main/res-public/layout/kau_recycler_textslider.xml b/core-ui/src/main/res-public/layout/kau_recycler_textslider.xml
index eacd5be..d048627 100644
--- a/core-ui/src/main/res-public/layout/kau_recycler_textslider.xml
+++ b/core-ui/src/main/res-public/layout/kau_recycler_textslider.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/kau_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/kau_toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
@@ -20,9 +20,9 @@
android:gravity="center"
app:animation_type="slide_vertical" />
- </android.support.v7.widget.Toolbar>
+ </androidx.appcompat.widget.Toolbar>
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/kau_recycler"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -31,4 +31,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/kau_toolbar" />
-</android.support.constraint.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/core/README.md b/core/README.md
index 39899dd..b9a10f5 100644
--- a/core/README.md
+++ b/core/README.md
@@ -131,6 +131,9 @@ These variants are weakly held in the private `KotterknifeRegistry` object, and
values through the `Kotterknife.reset` method. This is typically useful for Fragments, as they do not follow
the same lifecycle as Activities and Views.
+Note that this is useful for views that have ids in multiple layout files or in `id.xml` files.
+Kotlin has another solution, [`kotlin-android-extensions`](https://kotlinlang.org/docs/tutorials/android-plugin.html), which is more convenient.
+
## Ripple Canvas
Ripple canvas provides a way to create simultaneous ripples against a background color.
@@ -210,7 +213,6 @@ Include your email and subject, along with other optional configurations such as
## Extension Functions
> "[Extensions](https://kotlinlang.org/docs/reference/extensions.html) provide the ability to extend a class with new functionality without having to inherit from the class"
-<br/>Note that since KAU depends on [ANKO](https://github.com/Kotlin/anko), all of the extensions in its core package is also in KAU.
KAU's vast collection of extensions is one of its strongest features.
There are too many to explain here, but you may check out the [utils package](https://github.com/AllanWang/KAU/tree/master/core/src/main/kotlin/ca/allanwang/kau/utils)
diff --git a/core/build.gradle b/core/build.gradle
index 046a734..3ac4f36 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -5,20 +5,18 @@ apply from: '../android-lib.gradle'
dependencies {
api kauDependency.kotlin
- api "com.android.support:support-annotations:${kau.supportLibs}"
- api "com.android.support:appcompat-v7:${kau.supportLibs}"
- api "com.android.support:support-v13:${kau.supportLibs}"
- api "com.android.support:design:${kau.supportLibs}"
- api "com.android.support:recyclerview-v7:${kau.supportLibs}"
- api "com.android.support:cardview-v7:${kau.supportLibs}"
- api "com.android.support.constraint:constraint-layout:${kau.constraintLayout}"
+ api "androidx.appcompat:appcompat:${kau.appcompat}"
+ api "androidx.recyclerview:recyclerview:${kau.recyclerView}"
+ api "androidx.cardview:cardview:${kau.cardView}"
+ api "androidx.constraintlayout:constraintlayout:${kau.constraintLayout}"
+ api "com.google.android.material:material:${kau.googleMaterial}"
+
+ api "org.jetbrains.kotlinx:kotlinx-coroutines-android:${kau.coroutines}"
api "com.mikepenz:iconics-core:${kau.iconics}@aar"
api "com.mikepenz:google-material-typeface:${kau.iconicsGoogle}.original@aar"
api "com.afollestad.material-dialogs:core:${kau.materialDialog}"
-
- api "org.jetbrains.anko:anko-commons:${kau.anko}"
}
apply from: '../artifacts.gradle'
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt
index 2a9263a..29f5af1 100644
--- a/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/kpref/KPrefTest.kt
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref
import android.annotation.SuppressLint
-import android.support.test.InstrumentationRegistry
-import android.support.test.filters.MediumTest
-import android.support.test.runner.AndroidJUnit4
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -23,7 +39,7 @@ class KPrefTest {
class TestPref : KPref() {
init {
- initialize(InstrumentationRegistry.getTargetContext(), "kpref_test_${System.currentTimeMillis()}")
+ initialize(ApplicationProvider.getApplicationContext<Context>(), "kpref_test_${System.currentTimeMillis()}")
}
var one by kpref("one", 1)
@@ -83,11 +99,9 @@ class KPrefTest {
assertEquals(-1, pref.one, "Kpref did not refetch from shared prefs upon reset")
}
-
@Test
fun single() {
assertTrue(pref.oneShot)
assertFalse(pref.oneShot)
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt
index 1dac92f..96ebd3a 100644
--- a/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/KotterknifeTest.kt
@@ -1,12 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.Context
-import android.support.test.InstrumentationRegistry
-import android.support.test.filters.MediumTest
-import android.support.test.runner.AndroidJUnit4
import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -25,7 +40,7 @@ class KotterknifeTest {
@Before
fun init() {
- context = InstrumentationRegistry.getContext()
+ context = InstrumentationRegistry.getInstrumentation().context
}
@Test
@@ -197,4 +212,4 @@ class KotterknifeTest {
view.id = id
return view
}
-} \ No newline at end of file
+}
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt
new file mode 100644
index 0000000..665e0b2
--- /dev/null
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ca.allanwang.kau.utils
+
+import android.graphics.Color
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.test.assertEquals
+
+/**
+ * Created by Allan Wang on 2018-12-24.
+ *
+ * Misc test code that are dependent on android
+ */
+@RunWith(AndroidJUnit4::class)
+class UtilsAndroidTest {
+
+ @Test
+ fun colorBlend() {
+ assertEquals(0x22446688, 0x11335577.blendWith(0x33557799, 0.5f), "Failed to blend with 50% ratio")
+ assertEquals(0x11335577, 0x11335577.blendWith(0x33557799, 0.0f), "Failed to blend with 0% ratio")
+ assertEquals(0x33557799, 0x22446688.blendWith(0x33557799, 1.0f), "Failed to blend with 100% ratio")
+ }
+
+ @Test
+ fun lighten() {
+ assertEquals(Color.WHITE, Color.WHITE.lighten(0.35f), "Should not be able to further lighten white")
+ assertEquals(0xFFEEAAEA.toInt(), 0xFFDD55D5.toInt().lighten(0.5f), "Failed to lighten color by 50%")
+ }
+
+ @Test
+ fun darken() {
+ assertEquals(Color.BLACK, Color.BLACK.darken(0.35f), "Should not be able to further darken black")
+ assertEquals(0xFF224424.toInt(), 0xFF448848.toInt().darken(0.5f), "Failed to darken color by 50%")
+ }
+}
diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt
index f9ce24b..7ec2a41 100644
--- a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt
+++ b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt
@@ -1,8 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.xml
-import android.support.test.InstrumentationRegistry
-import android.support.test.filters.MediumTest
-import android.support.test.runner.AndroidJUnit4
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import ca.allanwang.kau.test.R
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
@@ -14,26 +31,16 @@ import kotlin.test.assertEquals
@MediumTest
class FaqTest {
- @Test
- fun simpleTest() {
- InstrumentationRegistry.getTargetContext().kauParseFaq(R.xml.test_faq) { data ->
- assertEquals(2, data.size, "FAQ size is incorrect")
- assertEquals("1. This is a question", data.first().question.toString(), "First question does not match")
- assertEquals("This is an answer", data.first().answer.toString(), "First answer does not match")
- assertEquals("2. This is another question", data.last().question.toString(), "Second question does not match")
- assertEquals("This is another answer", data.last().answer.toString(), "Second answer does not match")
- }
- }
+ val context: Context
+ get() = ApplicationProvider.getApplicationContext<Context>()
@Test
- fun withoutNumbering() {
- InstrumentationRegistry.getTargetContext().kauParseFaq(R.xml.test_faq, false) { data ->
- assertEquals(2, data.size, "FAQ size is incorrect")
- assertEquals("This is a question", data.first().question.toString(), "First question does not match")
- assertEquals("This is an answer", data.first().answer.toString(), "First answer does not match")
- assertEquals("This is another question", data.last().question.toString(), "Second question does not match")
- assertEquals("This is another answer", data.last().answer.toString(), "Second answer does not match")
- }
+ fun simpleTest() {
+ val data = context.kauParseFaq(R.xml.test_faq, false)
+ assertEquals(2, data.size, "FAQ size is incorrect")
+ assertEquals("This is a question", data.first().question.toString(), "First question does not match")
+ assertEquals("This is an answer", data.first().answer.toString(), "First answer does not match")
+ assertEquals("This is another question", data.last().question.toString(), "Second question does not match")
+ assertEquals("This is another answer", data.last().answer.toString(), "Second answer does not match")
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt
index 2b9d91c..78661b1 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/email/EmailBuilder.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.email
import android.app.Activity
@@ -6,12 +21,15 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
-import android.support.annotation.StringRes
import android.util.DisplayMetrics
+import androidx.annotation.StringRes
import ca.allanwang.kau.R
import ca.allanwang.kau.logging.KL
-import ca.allanwang.kau.utils.*
-
+import ca.allanwang.kau.utils.boolean
+import ca.allanwang.kau.utils.installerPackageName
+import ca.allanwang.kau.utils.isAppInstalled
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.toast
/**
* Created by Allan Wang on 2017-06-20.
@@ -28,7 +46,7 @@ class EmailBuilder(val email: String, val subject: String) {
private var attachment: Uri? = null
fun checkPackage(packageName: String, appName: String) =
- packages.add(Package(packageName, appName))
+ packages.add(Package(packageName, appName))
fun addItem(key: String, value: String) = pairs.put(key, value)
@@ -45,24 +63,24 @@ class EmailBuilder(val email: String, val subject: String) {
fun getIntent(context: Context): Intent {
val intent = Intent(Intent.ACTION_SEND)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
- .putExtra(Intent.EXTRA_SUBJECT, subject)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
+ .putExtra(Intent.EXTRA_SUBJECT, subject)
val emailBuilder = StringBuilder()
emailBuilder.append(message).append("\n\n")
if (deviceDetails) {
- val deviceItems = linkedMapOf(
- "OS Version" to "${System.getProperty("os.version")} (${Build.VERSION.INCREMENTAL})",
- "OS SDK" to Build.VERSION.SDK_INT,
- "Device (Manufacturer)" to "${Build.DEVICE} (${Build.MANUFACTURER})",
- "Model (Product)" to "${Build.MODEL} (${Build.PRODUCT})",
- "Package Installer" to (context.installerPackageName ?: "None"),
- "Tablet" to context.boolean(R.bool.kau_is_tablet)
+ val deviceItems = mutableListOf(
+ "OS Version" to "${System.getProperty("os.version")} (${Build.VERSION.INCREMENTAL})",
+ "OS SDK" to Build.VERSION.SDK_INT,
+ "Device (Manufacturer)" to "${Build.DEVICE} (${Build.MANUFACTURER})",
+ "Model (Product)" to "${Build.MODEL} (${Build.PRODUCT})",
+ "Package Installer" to (context.installerPackageName ?: "None"),
+ "Tablet" to context.boolean(R.bool.kau_is_tablet)
)
if (context is Activity) {
val metric = DisplayMetrics()
context.windowManager.defaultDisplay.getMetrics(metric)
- deviceItems["Screen Dimensions"] = "${metric.widthPixels} x ${metric.heightPixels}"
+ deviceItems.add("Screen Dimensions" to "${metric.widthPixels} x ${metric.heightPixels}")
}
deviceItems.forEach { (k, v) -> emailBuilder.append("$k: $v\n") }
}
@@ -76,8 +94,8 @@ class EmailBuilder(val email: String, val subject: String) {
appInfo.versionCode.toString()
}
emailBuilder.append("\nApp: ").append(context.packageName)
- .append("\nApp Version Name: ").append(appInfo.versionName)
- .append("\nApp Version Code: ").append(versionCode).append("\n")
+ .append("\nApp Version Name: ").append(appInfo.versionName)
+ .append("\nApp Version Code: ").append(versionCode).append("\n")
} catch (e: PackageManager.NameNotFoundException) {
KL.e { "EmailBuilder packageInfo not found" }
}
@@ -112,7 +130,7 @@ class EmailBuilder(val email: String, val subject: String) {
val intent = getIntent(context)
intent.extras()
val packageName = intent.resolveActivity(context.packageManager)?.packageName
- ?: return context.toast(R.string.kau_error_no_email, log = true)
+ ?: return context.toast(R.string.kau_error_no_email, log = true)
val attachment = this.attachment
if (attachment != null) {
@@ -124,12 +142,12 @@ class EmailBuilder(val email: String, val subject: String) {
}
}
-fun Context.sendEmail(@StringRes emailId: Int, @StringRes subjectId: Int, builder: EmailBuilder.() -> Unit = {}) = sendEmail(string(emailId), string(subjectId), builder)
-
+fun Context.sendEmail(@StringRes emailId: Int, @StringRes subjectId: Int, builder: EmailBuilder.() -> Unit = {}) =
+ sendEmail(string(emailId), string(subjectId), builder)
fun Context.sendEmail(email: String, subject: String, builder: EmailBuilder.() -> Unit = {}) {
EmailBuilder(email, subject).apply {
builder()
execute(this@sendEmail)
}
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt b/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt
index 87d94ce..cb8f4bf 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/internal/KauBaseActivity.kt
@@ -1,7 +1,28 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.internal
-import android.support.v7.app.AppCompatActivity
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
+import ca.allanwang.kau.utils.ContextHelper
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.SupervisorJob
+import kotlin.coroutines.CoroutineContext
/**
* Created by Allan Wang on 2017-08-01.
@@ -11,11 +32,31 @@ import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
* Ensures that some singleton methods are called.
* This is simply a convenience class;
* you can always copy and paste this to your own class.
+ *
+ * This also implements [CoroutineScope] that adheres to the activity lifecycle.
+ * Note that by default, [SupervisorJob] is used, to avoid exceptions in one child from affecting that of another.
+ * The default job can be overridden within [defaultJob]
*/
-abstract class KauBaseActivity : AppCompatActivity() {
+abstract class KauBaseActivity : AppCompatActivity(), CoroutineScope {
+
+ open lateinit var job: Job
+ override val coroutineContext: CoroutineContext
+ get() = ContextHelper.dispatcher + job
+
+ open fun defaultJob(): Job = SupervisorJob()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ job = defaultJob()
+ }
+
+ override fun onDestroy() {
+ job.cancel()
+ super.onDestroy()
+ }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
kauOnRequestPermissionsResult(permissions, grantResults)
}
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt
index de5d148..ea13f73 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Debouncer.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
import ca.allanwang.kau.logging.KL
@@ -56,7 +71,6 @@ open class Debouncer(var interval: Long) {
task = null
}
}
-
}
/*
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/FlyWeight.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/FlyWeight.kt
deleted file mode 100644
index 03e98d2..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/FlyWeight.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package ca.allanwang.kau.kotlin
-
-/**
- * Created by Allan Wang on 26/12/17.
- *
- * Kotlin implementation of a flyweight design pattern
- * Values inside the map will be returned directly
- * Otherwise, it will be created with the supplier, saved, and returned
- * In the event a default is provided, the default takes precedence
- */
-fun <K : Any, V : Any> flyweight(creator: (K) -> V) = FlyWeight(creator)
-
-class FlyWeight<K : Any, V : Any>(private val creator: (key: K) -> V) : Map<K, V> {
-
- private val map = mutableMapOf<K, V>()
-
- override val entries: Set<Map.Entry<K, V>>
- get() = map.entries
- override val keys: Set<K>
- get() = map.keys
- override val size: Int
- get() = map.size
- override val values: Collection<V>
- get() = map.values
-
- override fun containsKey(key: K) = map.containsKey(key)
-
- override fun containsValue(value: V) = map.containsValue(value)
-
- override fun getOrDefault(key: K, defaultValue: V) = map.getOrDefault(key, defaultValue)
-
- override fun isEmpty() = map.isEmpty()
-
- override fun get(key: K): V {
- if (!map.containsKey(key))
- map.put(key, creator(key))
- return map[key]!!
- }
-
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyContext.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyContext.kt
index 0a45b65..e2a59d7 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyContext.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyContext.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
import android.content.Context
-import android.support.annotation.AnimRes
-import android.support.annotation.InterpolatorRes
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.animation.Interpolator
+import androidx.annotation.AnimRes
+import androidx.annotation.InterpolatorRes
/**
* Created by Allan Wang on 2017-05-30.
@@ -47,5 +62,4 @@ class LazyContext<out T>(private val initializer: (context: Context) -> T, lock:
}
}
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt
index 979f7a7..ee38d48 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyResettable.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
import java.io.Serializable
@@ -80,4 +95,4 @@ class LazyResettableRegistry : ILazyResettableRegistry {
override fun invalidateAll() = lazyRegistry.forEach { it.invalidate() }
override fun clear() = lazyRegistry.clear()
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Streams.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Streams.kt
index 303153f..65d15a7 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Streams.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Streams.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
/**
@@ -9,7 +24,6 @@ package ca.allanwang.kau.kotlin
* Since we don't have access to the internals of our extended class,
* We will simply iterate and remove when the filter returns {@code false}
*/
-@Synchronized
inline fun <T, C : MutableIterable<T>> C.kauRemoveIf(filter: (item: T) -> Boolean): C {
val iter = iterator()
while (iter.hasNext())
@@ -27,4 +41,4 @@ inline fun <T : Any> Iterator<T>.firstOrNull(predicate: (T) -> Boolean): T? {
if (predicate(data)) return data
}
return null
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt
index 1ba1de6..1e35ecf 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Utils.kt
@@ -1,6 +1,21 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
/**
* Created by Allan Wang on 07/04/18.
*/
-inline fun <reified T : Any> javaClass(): Class<T> = T::class.java \ No newline at end of file
+inline fun <reified T : Any> javaClass(): Class<T> = T::class.java
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Zip.kt b/core/src/main/kotlin/ca/allanwang/kau/kotlin/Zip.kt
deleted file mode 100644
index 17ae5e5..0000000
--- a/core/src/main/kotlin/ca/allanwang/kau/kotlin/Zip.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package ca.allanwang.kau.kotlin
-
-import org.jetbrains.anko.doAsync
-import java.util.concurrent.atomic.AtomicInteger
-
-/**
- * Created by Allan Wang on 2017-08-06.
- *
- * Collection of zip methods that aim to replicate
- * <a href="http://reactivex.io/documentation/operators/zip.html">Reactive Zips</a>
- * For unit returning functions
- *
- * Typically, the functions will execute asynchronously and call their given callbacks when finished.
- * Once all callbacks are called, the final onFinish callback will be executed.
- *
- * There is also a helper zipper to wrap synchronous functions with Anko's doAsync to achieve the same results
- *
- * Note that not wrapping synchronous functions will render these methods useless,
- * as you can simply define an inline callback after all functions are finished
- */
-
-/**
- * Callback which will only execute the first time
- */
-open class ZipCallbackBase {
- var completed: Boolean = false
-
- inline operator fun invoke(callback: () -> Unit) {
- if (completed) return
- completed = true
- callback()
- }
-}
-
-class ZipCallback<T>(val onReceived: (T) -> Unit) : ZipCallbackBase() {
- operator fun invoke(result: T) = invoke { onReceived(result) }
-}
-
-class ZipEmptyCallback(val onReceived: () -> Unit) : ZipCallbackBase() {
- operator fun invoke() = invoke(onReceived)
-}
-
-/**
- * Given a default result, a series of tasks, and a finished callback,
- * this method will run all tasks and wait until all tasks emit a response
- * The response will then be sent back to the callback
- *
- * ALl tasks must invoke the task callback for [onFinished] to execute
- */
-inline fun <reified T> Collection<(ZipCallback<T>) -> Unit>.zip(
- defaultResult: T, crossinline onFinished: (results: Array<T>) -> Unit
-) {
- val result = Array(size) { defaultResult }
- val countDown = AtomicInteger(size)
- forEachIndexed { index, asyncFun ->
- asyncFun(ZipCallback {
- result[index] = it
- if (countDown.decrementAndGet() <= 0)
- onFinished(result)
- })
- }
-}
-
-/**
- * Simplified zip method with no finished callback arguments
- */
-inline fun Collection<(ZipEmptyCallback) -> Unit>.zip(crossinline onFinished: () -> Unit) {
- val countDown = AtomicInteger(size)
- forEach { asyncFun ->
- asyncFun(ZipEmptyCallback {
- if (countDown.decrementAndGet() <= 0)
- onFinished()
- })
- }
-}
-
-/**
- * Converts a collection of synchronous tasks to asynchronous tasks with a common callback
- */
-inline fun Collection<() -> Unit>.zipAsync(crossinline onFinished: () -> Unit) {
- map { synchronousFun ->
- { callback: ZipEmptyCallback ->
- doAsync {
- synchronousFun()
- callback()
- }; Unit
- }
- }.zip(onFinished)
-}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
index 12f9606..7a6330f 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPref.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref
import android.content.Context
@@ -47,5 +62,4 @@ open class KPref {
operator fun get(key: String): ILazyResettable<*>? = prefMap[key]
open fun deleteKeys(): Array<String> = arrayOf()
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt
index b80479e..9813f24 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefDelegate.kt
@@ -1,31 +1,47 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref
import ca.allanwang.kau.kotlin.ILazyResettable
-
fun KPref.kpref(key: String, fallback: Boolean, postSetter: (value: Boolean) -> Unit = {}) =
- KPrefDelegate(key, fallback, this, KPrefBooleanTransaction, postSetter)
+ KPrefDelegate(key, fallback, this, KPrefBooleanTransaction, postSetter)
fun KPref.kpref(key: String, fallback: Float, postSetter: (value: Float) -> Unit = {}) =
- KPrefDelegate(key, fallback, this, KPrefFloatTransaction, postSetter)
+ KPrefDelegate(key, fallback, this, KPrefFloatTransaction, postSetter)
-@Deprecated("Double is not supported in SharedPreferences; cast to float yourself",
- ReplaceWith("kpref(key, fallback.toFloat(), postSetter)"),
- DeprecationLevel.WARNING)
+@Deprecated(
+ "Double is not supported in SharedPreferences; cast to float yourself",
+ ReplaceWith("kpref(key, fallback.toFloat(), postSetter)"),
+ DeprecationLevel.WARNING
+)
fun KPref.kpref(key: String, fallback: Double, postSetter: (value: Float) -> Unit = {}) =
- kpref(key, fallback.toFloat(), postSetter)
+ kpref(key, fallback.toFloat(), postSetter)
fun KPref.kpref(key: String, fallback: Int, postSetter: (value: Int) -> Unit = {}) =
- KPrefDelegate(key, fallback, this, KPrefIntTransaction, postSetter)
+ KPrefDelegate(key, fallback, this, KPrefIntTransaction, postSetter)
fun KPref.kpref(key: String, fallback: Long, postSetter: (value: Long) -> Unit = {}) =
- KPrefDelegate(key, fallback, this, KPrefLongTransaction, postSetter)
+ KPrefDelegate(key, fallback, this, KPrefLongTransaction, postSetter)
fun KPref.kpref(key: String, fallback: Set<String>, postSetter: (value: Set<String>) -> Unit = {}) =
- KPrefDelegate(key, fallback, this, KPrefSetTransaction, postSetter)
+ KPrefDelegate(key, fallback, this, KPrefSetTransaction, postSetter)
fun KPref.kpref(key: String, fallback: String, postSetter: (value: String) -> Unit = {}) =
- KPrefDelegate(key, fallback, this, KPrefStringTransaction, postSetter)
+ KPrefDelegate(key, fallback, this, KPrefStringTransaction, postSetter)
/**
* Created by Allan Wang on 2017-06-07.
@@ -35,11 +51,11 @@ fun KPref.kpref(key: String, fallback: String, postSetter: (value: String) -> Un
* Also contains an optional mutable postSetter that will be called every time a new value is given
*/
class KPrefDelegate<T> internal constructor(
- private val key: String,
- private val fallback: T,
- private val pref: KPref,
- private val transaction: KPrefTransaction<T>,
- private var postSetter: (value: T) -> Unit = {}
+ private val key: String,
+ private val fallback: T,
+ private val pref: KPref,
+ private val transaction: KPrefTransaction<T>,
+ private var postSetter: (value: T) -> Unit = {}
) : ILazyResettable<T> {
private object UNINITIALIZED
@@ -91,4 +107,4 @@ class KPrefDelegate<T> internal constructor(
}
}
-class KPrefException(message: String) : IllegalAccessException(message) \ No newline at end of file
+class KPrefException(message: String) : IllegalAccessException(message)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt
index ed30a44..204e07e 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefSingleDelegate.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref
import ca.allanwang.kau.kotlin.ILazyResettable
@@ -12,7 +27,8 @@ fun KPref.kprefSingle(key: String) = KPrefSingleDelegate(key, this)
* All subsequent retrievals will be [false]
* This is useful for one time toggles such as showcasing items
*/
-class KPrefSingleDelegate internal constructor(private val key: String, private val pref: KPref, lock: Any? = null) : ILazyResettable<Boolean> {
+class KPrefSingleDelegate internal constructor(private val key: String, private val pref: KPref, lock: Any? = null) :
+ ILazyResettable<Boolean> {
@Volatile
private var _value: Boolean? = null
@@ -52,5 +68,4 @@ class KPrefSingleDelegate internal constructor(private val key: String, private
override fun isInitialized(): Boolean = _value != null
override fun toString(): String = if (isInitialized()) value.toString() else "Lazy kPref $key not initialized yet."
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefTransaction.kt b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefTransaction.kt
index 773d208..1070e11 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefTransaction.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/kpref/KPrefTransaction.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref
import android.content.SharedPreferences
@@ -9,7 +24,7 @@ internal interface KPrefTransaction<T> {
internal object KPrefBooleanTransaction : KPrefTransaction<Boolean> {
override fun get(prefs: SharedPreferences, key: String, fallback: Boolean) =
- prefs.getBoolean(key, fallback)
+ prefs.getBoolean(key, fallback)
override fun set(editor: SharedPreferences.Editor, key: String, data: Boolean) {
editor.putBoolean(key, data)
@@ -18,7 +33,7 @@ internal object KPrefBooleanTransaction : KPrefTransaction<Boolean> {
internal object KPrefIntTransaction : KPrefTransaction<Int> {
override fun get(prefs: SharedPreferences, key: String, fallback: Int) =
- prefs.getInt(key, fallback)
+ prefs.getInt(key, fallback)
override fun set(editor: SharedPreferences.Editor, key: String, data: Int) {
editor.putInt(key, data)
@@ -27,7 +42,7 @@ internal object KPrefIntTransaction : KPrefTransaction<Int> {
internal object KPrefLongTransaction : KPrefTransaction<Long> {
override fun get(prefs: SharedPreferences, key: String, fallback: Long) =
- prefs.getLong(key, fallback)
+ prefs.getLong(key, fallback)
override fun set(editor: SharedPreferences.Editor, key: String, data: Long) {
editor.putLong(key, data)
@@ -36,7 +51,7 @@ internal object KPrefLongTransaction : KPrefTransaction<Long> {
internal object KPrefFloatTransaction : KPrefTransaction<Float> {
override fun get(prefs: SharedPreferences, key: String, fallback: Float) =
- prefs.getFloat(key, fallback)
+ prefs.getFloat(key, fallback)
override fun set(editor: SharedPreferences.Editor, key: String, data: Float) {
editor.putFloat(key, data)
@@ -45,7 +60,7 @@ internal object KPrefFloatTransaction : KPrefTransaction<Float> {
internal object KPrefStringTransaction : KPrefTransaction<String> {
override fun get(prefs: SharedPreferences, key: String, fallback: String) =
- prefs.getString(key, fallback)
+ prefs.getString(key, fallback)
override fun set(editor: SharedPreferences.Editor, key: String, data: String) {
editor.putString(key, data)
@@ -54,11 +69,9 @@ internal object KPrefStringTransaction : KPrefTransaction<String> {
internal object KPrefSetTransaction : KPrefTransaction<Set<String>> {
override fun get(prefs: SharedPreferences, key: String, fallback: Set<String>) =
- prefs.getStringSet(key, fallback)!!
+ prefs.getStringSet(key, fallback)!!
override fun set(editor: SharedPreferences.Editor, key: String, data: Set<String>) {
editor.putStringSet(key, data)
}
}
-
-
diff --git a/core/src/main/kotlin/ca/allanwang/kau/logging/KL.kt b/core/src/main/kotlin/ca/allanwang/kau/logging/KL.kt
index 9f48ab5..9fbc070 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/logging/KL.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/logging/KL.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.logging
import ca.allanwang.kau.BuildConfig
@@ -7,4 +22,13 @@ import ca.allanwang.kau.BuildConfig
*
* Internal KAU logger
*/
-object KL : KauLogger("KAU", { BuildConfig.DEBUG }) \ No newline at end of file
+object KL : KauLogger("KAU", { BuildConfig.DEBUG }) {
+
+ /**
+ * Logger with searchable tag and thread info
+ */
+ inline fun test(message: () -> Any?) {
+ if (BuildConfig.DEBUG)
+ d { "Test1234 ${Thread.currentThread().name} ${message()}" }
+ }
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt b/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt
index 799d32f..4562b00 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/logging/KauLogger.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
@file:Suppress("NOTHING_TO_INLINE")
package ca.allanwang.kau.logging
-import android.os.Looper
import android.util.Log
+import ca.allanwang.kau.utils.kauIsMainThread
/**
* Created by Allan Wang on 2017-05-28.
@@ -25,15 +40,15 @@ import android.util.Log
* for production builds
*/
open class KauLogger(
- /**
- * Tag to be used for each log
- */
- val tag: String,
- /**
- * Toggle to dictate whether a message should be logged
- */
- var shouldLog: (priority: Int) -> Boolean = { true }) {
-
+ /**
+ * Tag to be used for each log
+ */
+ val tag: String,
+ /**
+ * Toggle to dictate whether a message should be logged
+ */
+ var shouldLog: (priority: Int) -> Boolean = { true }
+) {
inline fun v(message: () -> Any?) = log(Log.VERBOSE, message)
@@ -67,7 +82,7 @@ open class KauLogger(
inline fun checkThread(id: Int) {
d {
val name = Thread.currentThread().name
- val status = if (Looper.myLooper() == Looper.getMainLooper()) "is" else "is not"
+ val status = if (kauIsMainThread) "is" else "is not"
"$id $status in the main thread - thread name: $name"
}
}
@@ -96,16 +111,16 @@ class KauLoggerExtension(val tag: String, val logger: KauLogger) {
}
inline fun log(priority: Int, message: () -> Any?, t: Throwable? = null) =
- logger.log(priority, {
- val msg = message()?.toString()
- if (msg == null) null
- else "$tag: $msg"
- }, t)
+ logger.log(priority, {
+ val msg = message()?.toString()
+ if (msg == null) null
+ else "$tag: $msg"
+ }, t)
inline fun checkThread(id: Int) {
d {
val name = Thread.currentThread().name
- val status = if (Looper.myLooper() == Looper.getMainLooper()) "is" else "is not"
+ val status = if (kauIsMainThread) "is" else "is not"
"$id $status in the main thread - thread name: $name"
}
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
index 36456ec..96adfa3 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionManager.kt
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.permissions
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
-import android.support.v4.app.ActivityCompat
+import androidx.core.app.ActivityCompat
+import ca.allanwang.kau.kotlin.kauRemoveIf
import ca.allanwang.kau.kotlin.lazyContext
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.utils.KauException
@@ -12,43 +28,55 @@ import ca.allanwang.kau.utils.hasPermission
import ca.allanwang.kau.utils.toast
import java.lang.ref.WeakReference
-
/**
* Created by Allan Wang on 2017-07-03.
*
- * Permission manager that is decoupled from activities
- * Keeps track of pending requests, and warns about invalid requests
+ * Permission manager that is decoupled from activities.
+ * Keeps track of pending requests, and warns about invalid requests.
*/
internal object PermissionManager {
- private var requestInProgress = false
- private val pendingResults: MutableList<WeakReference<PermissionResult>> by lazy { mutableListOf<WeakReference<PermissionResult>>() }
+ private val pendingResults = mutableListOf<WeakReference<PermissionResult>>()
/**
* Retrieve permissions requested in our manifest
*/
- private val manifestPermission = lazyContext<Array<String>> {
+ private val manifestPermission = lazyContext<Set<String>> {
try {
- it.packageManager.getPackageInfo(it.packageName, PackageManager.GET_PERMISSIONS)?.requestedPermissions
- ?: emptyArray()
+ it.packageManager.getPackageInfo(
+ it.packageName,
+ PackageManager.GET_PERMISSIONS
+ )?.requestedPermissions?.toSet()
+ ?: emptySet()
} catch (e: Exception) {
- emptyArray()
+ emptySet()
}
}
- operator fun invoke(context: Context, permissions: Array<out String>, callback: (granted: Boolean, deniedPerm: String?) -> Unit) {
+ /**
+ * Registers a new permission request.
+ * It is expected that the callback will be called eventually, unless the parent activity is destroyed.
+ */
+ operator fun invoke(
+ context: Context,
+ permissions: Array<out String>,
+ callback: (granted: Boolean, deniedPerm: String?) -> Unit
+ ) {
KL.d { "Permission manager for: ${permissions.contentToString()}" }
if (!buildIsMarshmallowAndUp) return callback(true, null)
val missingPermissions = permissions.filter { !context.hasPermission(it) }
if (missingPermissions.isEmpty()) return callback(true, null)
pendingResults.add(WeakReference(PermissionResult(permissions, callback = callback)))
- if (!requestInProgress) {
- requestInProgress = true
+ if (pendingResults.size == 1) {
requestPermissions(context, missingPermissions.toTypedArray())
- } else KL.d { "Request is postponed since another one is still in progress; did you remember to override onRequestPermissionsResult?" }
+ } else {
+ KL.d { "Request is postponed since another one is still in progress; did you remember to override onRequestPermissionsResult?" }
+ }
}
- @Synchronized
+ /**
+ * Checks that the listed permissions can be requested, and submits the request to the provided activity
+ */
private fun requestPermissions(context: Context, permissions: Array<out String>) {
permissions.forEach {
if (!manifestPermission(context).contains(it)) {
@@ -58,36 +86,27 @@ internal object PermissionManager {
}
}
val activity = (context as? Activity)
- ?: throw KauException("Context is not an instance of an activity; cannot request permissions")
+ ?: throw KauException("Context is not an instance of an activity; cannot request permissions")
KL.i { "Requesting permissions ${permissions.contentToString()}" }
ActivityCompat.requestPermissions(activity, permissions, 1)
}
/**
- * Handles permission result by allowing accepted permissions for all pending requests
- * Also cleans up destroyed or completed pending requests
+ * Handles permission result by allowing accepted permissions for all pending requests.
+ * Also cleans up destroyed or completed pending requests.
*/
fun onRequestPermissionsResult(context: Context, permissions: Array<out String>, grantResults: IntArray) {
KL.i { "On permission result: pending ${pendingResults.size}" }
val count = Math.min(permissions.size, grantResults.size)
- val iter = pendingResults.iterator()
- while (iter.hasNext()) {
- val action = iter.next().get()
- if ((0 until count).any { action?.onResult(permissions[it], grantResults[it]) != false })
- iter.remove()
+ pendingResults.kauRemoveIf {
+ val action = it.get()
+ action == null || (0 until count).any { i -> action.onResult(permissions[i], grantResults[i]) }
}
- if (pendingResults.isEmpty())
- requestInProgress = false
- else {
- val action = pendingResults.map { it.get() }.firstOrNull { it != null }
- if (action == null) { //actions have been unlinked from their weak references
- pendingResults.clear()
- requestInProgress = false
- return
- }
- requestPermissions(context, action.permissions.toTypedArray())
+ val action = pendingResults.asSequence().map { it.get() }.firstOrNull { it != null }
+ if (action == null) { // actions have been unlinked from their weak references
+ pendingResults.clear()
+ return
}
- KL.i { "Post on permission result: pending ${pendingResults.size}" }
+ requestPermissions(context, action.permissions.toTypedArray())
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionResult.kt b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionResult.kt
index ba3e6dd..599f6e8 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionResult.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/permissions/PermissionResult.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.permissions
import android.content.pm.PackageManager
@@ -21,8 +36,10 @@ class PermissionResult(permissions: Array<out String>, val callback: (granted: B
return true
}
permissions.remove(permission)
- if (permissions.isNotEmpty()) return false
+ if (permissions.isNotEmpty()) {
+ return false
+ }
callback(true, null)
return true
}
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/permissions/Permissions.kt b/core/src/main/kotlin/ca/allanwang/kau/permissions/Permissions.kt
index 248e484..3c90b05 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/permissions/Permissions.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/permissions/Permissions.kt
@@ -1,11 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.permissions
import android.Manifest
import android.app.Activity
import android.content.Context
import android.os.Build
-import android.support.annotation.RequiresApi
-
+import androidx.annotation.RequiresApi
/**
* Created by Allan Wang on 2017-07-02.
@@ -22,7 +36,8 @@ import android.support.annotation.RequiresApi
/**
* Hook that should be added inside all [Activity.onRequestPermissionsResult] so that the Permission manager can handle the responses
*/
-fun Activity.kauOnRequestPermissionsResult(permissions: Array<out String>, grantResults: IntArray) = PermissionManager.onRequestPermissionsResult(this, permissions, grantResults)
+fun Activity.kauOnRequestPermissionsResult(permissions: Array<out String>, grantResults: IntArray) =
+ PermissionManager.onRequestPermissionsResult(this, permissions, grantResults)
/**
* Request a permission with a callback
@@ -31,7 +46,10 @@ fun Activity.kauOnRequestPermissionsResult(permissions: Array<out String>, grant
* The [callback] returns [granted], which is true if all permissions are granted
* [deniedPerm] is the first denied permission, if granted is false
*/
-fun Context.kauRequestPermissions(vararg permissions: String, callback: (granted: Boolean, deniedPerm: String?) -> Unit) = PermissionManager(this, permissions, callback)
+fun Context.kauRequestPermissions(
+ vararg permissions: String,
+ callback: (granted: Boolean, deniedPerm: String?) -> Unit
+) = PermissionManager(this, permissions, callback)
/**
* See http://developer.android.com/guide/topics/security/permissions.html#normal-dangerous for a
@@ -72,4 +90,4 @@ const val PERMISSION_RECEIVE_MMS = Manifest.permission.RECEIVE_MMS
const val PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE
const val PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE
-const val PERMISSION_SYSTEM_ALERT_WINDOW = Manifest.permission.SYSTEM_ALERT_WINDOW \ No newline at end of file
+const val PERMISSION_SYSTEM_ALERT_WINDOW = Manifest.permission.SYSTEM_ALERT_WINDOW
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt
index f14f5cf..0b1dd88 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/RelativeSlider.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.swipe
/**
@@ -30,10 +45,14 @@ internal class RelativeSlider(var curPage: SwipeBackPage) : SwipeListener {
return
}
when (edgeFlag) {
- SWIPE_EDGE_LEFT -> page.swipeBackLayout.x = Math.min(-offset * Math.max(1 - percent, 0f) + DEFAULT_OFFSET, 0f)
- SWIPE_EDGE_RIGHT -> page.swipeBackLayout.x = Math.min(offset * Math.max(1 - percent, 0f) - DEFAULT_OFFSET, 0f)
- SWIPE_EDGE_TOP -> page.swipeBackLayout.y = Math.min(-offset * Math.max(1 - percent, 0f) + DEFAULT_OFFSET, 0f)
- SWIPE_EDGE_BOTTOM -> page.swipeBackLayout.y = Math.min(offset * Math.max(1 - percent, 0f) - DEFAULT_OFFSET, 0f)
+ SWIPE_EDGE_LEFT -> page.swipeBackLayout.x =
+ Math.min(-offset * Math.max(1 - percent, 0f) + DEFAULT_OFFSET, 0f)
+ SWIPE_EDGE_RIGHT -> page.swipeBackLayout.x =
+ Math.min(offset * Math.max(1 - percent, 0f) - DEFAULT_OFFSET, 0f)
+ SWIPE_EDGE_TOP -> page.swipeBackLayout.y =
+ Math.min(-offset * Math.max(1 - percent, 0f) + DEFAULT_OFFSET, 0f)
+ SWIPE_EDGE_BOTTOM -> page.swipeBackLayout.y =
+ Math.min(offset * Math.max(1 - percent, 0f) - DEFAULT_OFFSET, 0f)
}
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
index 018d7c7..1c6de12 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackHelper.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.swipe
import android.app.Activity
@@ -5,7 +20,7 @@ import ca.allanwang.kau.R
import ca.allanwang.kau.kotlin.kauRemoveIf
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.swipe.SwipeBackHelper.onDestroy
-import java.util.*
+import java.util.Stack
/**
* Singleton to hold our swipe stack
@@ -16,7 +31,8 @@ internal object SwipeBackHelper {
private val pageStack = Stack<SwipeBackPage>()
- private operator fun get(activity: Activity): SwipeBackPage? = pageStack.firstOrNull { it.activityRef.get() === activity }
+ private operator fun get(activity: Activity): SwipeBackPage? =
+ pageStack.firstOrNull { it.activityRef.get() === activity }
fun onCreate(activity: Activity, builder: SwipeBackContract.() -> Unit = {}) {
val page = this[activity] ?: pageStack.push(SwipeBackPage(activity).apply { builder() })
@@ -93,4 +109,4 @@ const val SWIPE_EDGE_RIGHT = ViewDragHelper.EDGE_RIGHT
const val SWIPE_EDGE_TOP = ViewDragHelper.EDGE_TOP
-const val SWIPE_EDGE_BOTTOM = ViewDragHelper.EDGE_BOTTOM \ No newline at end of file
+const val SWIPE_EDGE_BOTTOM = ViewDragHelper.EDGE_BOTTOM
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
index a323e6c..1f564ce 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackLayout.kt
@@ -1,15 +1,30 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.swipe
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Canvas
-import android.support.v4.view.ViewCompat
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import androidx.core.view.ViewCompat
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.utils.adjustAlpha
import ca.allanwang.kau.utils.navigationBarColor
@@ -23,7 +38,10 @@ import java.lang.ref.WeakReference
* If an edge detection occurs, this layout consumes all the touch events
* Use the [swipeEnabled] toggle if you need the scroll events on the same axis
*/
-internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0
+internal class SwipeBackLayout @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyle: Int = 0
) : FrameLayout(context, attrs, defStyle), SwipeBackContract, SwipeBackContractInternal {
override val swipeBackLayout: SwipeBackLayout
@@ -96,11 +114,9 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
override fun onEdgeTouch() {}
override fun onScrollToClose(edgeFlag: Int) {}
-
}
}
-
private var inLayout: Boolean = false
override var edgeSize: Int
@@ -158,7 +174,8 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
}
override fun setEdgeSizePercent(swipeEdgePercent: Float) {
- edgeSize = ((if (horizontal) resources.displayMetrics.widthPixels else resources.displayMetrics.heightPixels) * swipeEdgePercent).toInt()
+ edgeSize =
+ ((if (horizontal) resources.displayMetrics.widthPixels else resources.displayMetrics.heightPixels) * swipeEdgePercent).toInt()
}
/**
@@ -206,7 +223,7 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
*/
override fun scrollToFinishActivity() {
val contentView = contentViewRef.get()
- ?: return KL.e { "KauSwipe cannot scroll to finish as contentView is null. Is onPostCreate called?" }
+ ?: return KL.e { "KauSwipe cannot scroll to finish as contentView is null. Is onPostCreate called?" }
val swipeWidth = contentView.width + OVERSCROLL_DISTANCE
val swipeHeight = contentView.height + OVERSCROLL_DISTANCE
var top = 0
@@ -243,7 +260,7 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
val contentView = contentViewRef.get()
- ?: return KL.e { "KauSwipe cannot change layout as contentView is null. Is onPostCreate called?" }
+ ?: return KL.e { "KauSwipe cannot change layout as contentView is null. Is onPostCreate called?" }
inLayout = true
val xOffset: Int
val yOffset: Int
@@ -346,11 +363,12 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) {
super.onViewPositionChanged(changedView, left, top, dx, dy)
val contentView = contentViewRef.get()
- ?: return KL.e { "KauSwipe cannot change view position as contentView is null; is onPostCreate called?" }
+ ?: return KL.e { "KauSwipe cannot change view position as contentView is null; is onPostCreate called?" }
//make sure that we are using the proper axis
scrollPercent = Math.abs(
- if (horizontal) left.toFloat() / contentView.width
- else (top.toFloat() / contentView.height))
+ if (horizontal) left.toFloat() / contentView.width
+ else (top.toFloat() / contentView.height)
+ )
contentOffset = if (horizontal) left else top
invalidate()
if (scrollPercent < scrollThreshold && !isScrollOverValid)
@@ -375,10 +393,11 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
var result = Pair(0, 0)
if (scrollPercent <= scrollThreshold) {
//threshold not met; check velocities
- if ((edgeFlag == SWIPE_EDGE_LEFT && xvel > MIN_FLING_VELOCITY)
- || (edgeFlag == SWIPE_EDGE_RIGHT && xvel < -MIN_FLING_VELOCITY)
- || (edgeFlag == SWIPE_EDGE_TOP && yvel > MIN_FLING_VELOCITY)
- || (edgeFlag == SWIPE_EDGE_BOTTOM && yvel < -MIN_FLING_VELOCITY))
+ if ((edgeFlag == SWIPE_EDGE_LEFT && xvel > MIN_FLING_VELOCITY) ||
+ (edgeFlag == SWIPE_EDGE_RIGHT && xvel < -MIN_FLING_VELOCITY) ||
+ (edgeFlag == SWIPE_EDGE_TOP && yvel > MIN_FLING_VELOCITY) ||
+ (edgeFlag == SWIPE_EDGE_BOTTOM && yvel < -MIN_FLING_VELOCITY)
+ )
result = exitCaptureOffsets(edgeFlag, releasedChild)
} else {
//threshold met; fling to designated side
@@ -431,6 +450,5 @@ internal class SwipeBackLayout @JvmOverloads constructor(context: Context, attrs
const val DEFAULT_SCROLL_THRESHOLD = 0.3f
const val OVERSCROLL_DISTANCE = 10
-
}
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
index 4dba622..bc5b459 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeBackPage.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.swipe
import android.app.Activity
@@ -24,7 +39,8 @@ internal class SwipeBackPage(activity: Activity) : SwipeBackContractInternal by
init {
activity.window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
activity.window.decorView.setBackgroundColor(Color.TRANSPARENT)
- swipeBackLayout.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ swipeBackLayout.layoutParams =
+ ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
slider = RelativeSlider(this)
}
@@ -41,7 +57,7 @@ internal class SwipeBackPage(activity: Activity) : SwipeBackContractInternal by
private fun handleLayout() {
val activity = activityRef.get()
- ?: return KL.v { "KauSwipe activity ref gone during handleLayout" }
+ ?: return KL.v { "KauSwipe activity ref gone during handleLayout" }
if (swipeEnabled) swipeBackLayout.attachToActivity(activity)
else swipeBackLayout.removeFromActivity(activity)
}
@@ -50,7 +66,6 @@ internal class SwipeBackPage(activity: Activity) : SwipeBackContractInternal by
swipeBackLayout.scrollThreshold = percent
return this
}
-
}
internal interface SwipeBackContractInternal : SwipeBackContract {
@@ -104,4 +119,4 @@ interface SwipeBackContract {
fun removeListener(listener: SwipeListener)
fun hasListener(listener: SwipeListener): Boolean
fun scrollToFinishActivity()
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt
index 3ea62b5..07f8eb8 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/SwipeListener.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.swipe
interface SwipeListener {
@@ -16,4 +31,4 @@ interface SwipeListener {
* Invoked when scroll percent over the threshold for the first time
*/
fun onScrollToClose(edgeFlag: Int)
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java b/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java
index 566e9e5..ac7fb7e 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java
+++ b/core/src/main/kotlin/ca/allanwang/kau/swipe/ViewDragHelper.java
@@ -1,7 +1,7 @@
package ca.allanwang.kau.swipe;
import android.content.Context;
-import android.support.v4.view.ViewCompat;
+import androidx.core.view.ViewCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -25,7 +25,7 @@ import static ca.allanwang.kau.swipe.SwipeBackHelperKt.SWIPE_EDGE_TOP;
* of useful operations and state tracking for allowing a user to drag and reposition
* views within their parent ViewGroup.
* <p>
- * This is an extension of {@link android.support.v4.widget.ViewDragHelper}
+ * This is an extension of {@link androidx.core.widget.ViewDragHelper}
* Along with additional methods defined in {@link ViewDragHelperExtras}
*/
class ViewDragHelper implements ViewDragHelperExtras {
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt
index b98a47e..a46e6c5 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
-import android.support.annotation.VisibleForTesting
+import androidx.annotation.VisibleForTesting
import ca.allanwang.kau.kotlin.kauRemoveIf
/**
@@ -37,8 +52,7 @@ class ProgressAnimator private constructor() : ValueAnimator() {
isCancelled = false
}
})
- apply(builder)
- }
+ }.apply(builder)
/**
* Gets output of a linear function starting at [start] when [progress] is 0 and [end] when [progress] is 1 at point [progress].
@@ -54,7 +68,6 @@ class ProgressAnimator private constructor() : ValueAnimator() {
start + (end - start) * trueProgress
}
}
-
}
private val animators: MutableList<ProgressDisposableAction> = mutableListOf()
@@ -69,7 +82,6 @@ class ProgressAnimator private constructor() : ValueAnimator() {
val animatorCount get() = animators.size
-
/**
* Converts an action to a disposable action
*/
@@ -95,13 +107,13 @@ class ProgressAnimator private constructor() : ValueAnimator() {
}
fun withAnimator(action: ProgressAction) =
- withDisposableAnimator(action.asDisposable())
+ withDisposableAnimator(action.asDisposable())
/**
* Range animator. Multiples the range by the current float progress before emission
*/
fun withAnimator(from: Float, to: Float, action: ProgressAction) =
- withDisposableAnimator(from, to, action.asDisposable())
+ withDisposableAnimator(from, to, action.asDisposable())
fun withDisposableAnimator(action: ProgressDisposableAction) = animators.add(action)
@@ -170,4 +182,4 @@ class ProgressAnimator private constructor() : ValueAnimator() {
private typealias ProgressAction = (Float) -> Unit
private typealias ProgressDisposableAction = (Float) -> Boolean
private typealias ProgressRunnable = () -> Unit
-private typealias ProgressDisposableRunnable = () -> Boolean \ No newline at end of file
+private typealias ProgressDisposableRunnable = () -> Boolean
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt
index b92b222..684a11c 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/ui/SimpleRippleDrawable.kt
@@ -1,11 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui
import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.RippleDrawable
import android.os.Build
-import android.support.annotation.ColorInt
-import android.support.annotation.RequiresApi
+import androidx.annotation.ColorInt
+import androidx.annotation.RequiresApi
import ca.allanwang.kau.utils.adjustAlpha
/**
@@ -19,4 +34,4 @@ fun createSimpleRippleDrawable(@ColorInt foregroundColor: Int, @ColorInt backgro
val content = ColorDrawable(backgroundColor)
val mask = ColorDrawable(foregroundColor.adjustAlpha(0.16f))
return RippleDrawable(states, content, mask)
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/views/CollapsibleViewDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/views/CollapsibleViewDelegate.kt
index 8923775..b2a0d27 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/ui/views/CollapsibleViewDelegate.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/ui/views/CollapsibleViewDelegate.kt
@@ -1,8 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.views
import android.animation.ValueAnimator
import android.view.View
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.KAU_COLLAPSED
+import ca.allanwang.kau.utils.KAU_COLLAPSING
+import ca.allanwang.kau.utils.KAU_EXPANDED
+import ca.allanwang.kau.utils.KAU_EXPANDING
+import ca.allanwang.kau.utils.goneIf
import java.lang.ref.WeakReference
/**
@@ -48,10 +67,10 @@ class CollapsibleViewDelegate : CollapsibleView {
if (v > 1) v = 1f
else if (v < 0) v = 0f
stateHolder =
- if (v == 0f) KAU_COLLAPSED
- else if (v == 1f) KAU_EXPANDED
- else if (v - field < 0) KAU_COLLAPSING
- else KAU_EXPANDING
+ if (v == 0f) KAU_COLLAPSED
+ else if (v == 1f) KAU_EXPANDED
+ else if (v - field < 0) KAU_COLLAPSING
+ else KAU_EXPANDING
field = v
view?.goneIf(state == KAU_COLLAPSED)
view?.requestLayout()
@@ -101,5 +120,4 @@ class CollapsibleViewDelegate : CollapsibleView {
val target = if (expand) 1f else 0f
if (animate) animateSize(target) else expansion = target
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt
index 716fd71..6481306 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/ui/views/MeasureSpecDelegate.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.views
import android.content.Context
@@ -84,10 +99,13 @@ class MeasureSpecDelegate : MeasureSpecContract {
val styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MeasureSpecDelegate)
relativeWidth = styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_relativeWidth, relativeWidth)
relativeHeight = styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_relativeHeight, relativeHeight)
- relativeWidthToParent = styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_relativeWidthToParent, relativeWidthToParent)
- relativeHeightToParent = styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_relativeHeightToParent, relativeHeightToParent)
+ relativeWidthToParent =
+ styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_relativeWidthToParent, relativeWidthToParent)
+ relativeHeightToParent =
+ styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_relativeHeightToParent, relativeHeightToParent)
postRelativeWidth = styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_postRelativeWidth, postRelativeWidth)
- postRelativeHeight = styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_postRelativeHeight, postRelativeHeight)
+ postRelativeHeight =
+ styledAttrs.getFloat(R.styleable.MeasureSpecDelegate_postRelativeHeight, postRelativeHeight)
styledAttrs.recycle()
}
@@ -115,5 +133,4 @@ class MeasureSpecDelegate : MeasureSpecContract {
private val Float.measureSpec: Int
get() = View.MeasureSpec.makeMeasureSpec(this.toInt(), View.MeasureSpec.EXACTLY)
-
}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/views/RippleCanvas.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/views/RippleCanvas.kt
index 3d86419..176b9ea 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/ui/views/RippleCanvas.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/ui/views/RippleCanvas.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.ui.views
import android.animation.Animator
@@ -5,7 +20,11 @@ import android.animation.AnimatorListenerAdapter
import android.animation.ArgbEvaluator
import android.animation.ValueAnimator
import android.content.Context
-import android.graphics.*
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffXfermode
import android.util.AttributeSet
import android.view.View
@@ -17,7 +36,9 @@ import android.view.View
* Supports multiple ripples from varying locations
*/
class RippleCanvas @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val paint: Paint = Paint().apply {
isAntiAlias = true
@@ -53,11 +74,13 @@ class RippleCanvas @JvmOverloads constructor(
/**
* Creates a ripple effect from the given starting values
*/
- fun ripple(color: Int,
- startX: Float = 0f,
- startY: Float = 0f,
- duration: Long = 600L,
- callback: (() -> Unit)? = null) {
+ fun ripple(
+ color: Int,
+ startX: Float = 0f,
+ startY: Float = 0f,
+ duration: Long = 600L,
+ callback: (() -> Unit)? = null
+ ) {
val w = width.toFloat()
val h = height.toFloat()
val x = when (startX) {
@@ -112,11 +135,13 @@ class RippleCanvas @JvmOverloads constructor(
animator.start()
}
- internal class Ripple(val color: Int,
- val x: Float,
- val y: Float,
- var radius: Float,
- val maxRadius: Float)
+ internal class Ripple(
+ val color: Int,
+ val x: Float,
+ val y: Float,
+ var radius: Float,
+ val maxRadius: Float
+ )
companion object {
const val MIDDLE = -1.0f
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt
index ab0e59f..21141f1 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
@file:Suppress("NOTHING_TO_INLINE")
package ca.allanwang.kau.utils
@@ -11,15 +26,15 @@ import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
-import android.support.annotation.ColorInt
-import android.support.annotation.RequiresApi
-import android.support.annotation.StringRes
-import android.support.design.widget.Snackbar
import android.view.Menu
import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.ColorInt
+import androidx.annotation.RequiresApi
+import androidx.annotation.StringRes
import ca.allanwang.kau.R
+import com.google.android.material.snackbar.Snackbar
import com.mikepenz.iconics.typeface.IIcon
-import org.jetbrains.anko.contentView
/**
* Created by Allan Wang on 2017-06-21.
@@ -36,19 +51,22 @@ annotation class KauActivity
*/
@Suppress("DEPRECATION")
inline fun <reified T : Activity> Activity.startActivityForResult(
- requestCode: Int,
- bundleBuilder: Bundle.() -> Unit = {},
- intentBuilder: Intent.() -> Unit = {}
+ requestCode: Int,
+ bundleBuilder: Bundle.() -> Unit = {},
+ intentBuilder: Intent.() -> Unit = {}
) = startActivityForResult(T::class.java, requestCode, bundleBuilder, intentBuilder)
-@Deprecated("Use reified generic instead of passing class",
- ReplaceWith("startActivityForResult<T>(requestCode, bundleBuilder, intentBuilder)"),
- DeprecationLevel.WARNING)
+@Deprecated(
+ "Use reified generic instead of passing class",
+ ReplaceWith("startActivityForResult<T>(requestCode, bundleBuilder, intentBuilder)"),
+ DeprecationLevel.WARNING
+)
inline fun <T : Activity> Activity.startActivityForResult(
- clazz: Class<T>,
- requestCode: Int,
- bundleBuilder: Bundle.() -> Unit = {},
- intentBuilder: Intent.() -> Unit = {}) {
+ clazz: Class<T>,
+ requestCode: Int,
+ bundleBuilder: Bundle.() -> Unit = {},
+ intentBuilder: Intent.() -> Unit = {}
+) {
val intent = Intent(this, clazz)
intent.intentBuilder()
val bundle = Bundle()
@@ -72,13 +90,12 @@ inline fun Activity.restart(intentBuilder: Intent.() -> Unit = {}) {
overridePendingTransition(R.anim.kau_fade_in, R.anim.kau_fade_out)
}
-
/**
* Force restart an entire application
*/
@RequiresApi(Build.VERSION_CODES.M)
inline fun Activity.restartApplication() {
- val intent = packageManager.getLaunchIntentForPackage(packageName)
+ val intent = packageManager.getLaunchIntentForPackage(packageName)!!
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
val pending = PendingIntent.getActivity(this, 666, intent, PendingIntent.FLAG_CANCEL_CURRENT)
val alarm = getSystemService(Context.ALARM_SERVICE) as AlarmManager
@@ -119,8 +136,8 @@ inline var Activity.statusBarLight: Boolean
if (buildIsMarshmallowAndUp) {
val flags = window.decorView.systemUiVisibility
window.decorView.systemUiVisibility =
- if (value) flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
- else flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
+ if (value) flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+ else flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}
}
@@ -135,10 +152,33 @@ fun Context.setMenuIcons(menu: Menu, @ColorInt color: Int = Color.WHITE, vararg
}
}
-inline fun Activity.hideKeyboard() = currentFocus.hideKeyboard()
-
-inline fun Activity.showKeyboard() = currentFocus.showKeyboard()
+inline fun Activity.hideKeyboard() {
+ currentFocus?.hideKeyboard()
+}
-inline fun Activity.snackbar(text: String, duration: Int = Snackbar.LENGTH_LONG, noinline builder: Snackbar.() -> Unit = {}) = contentView!!.snackbar(text, duration, builder)
+inline fun Activity.showKeyboard() {
+ currentFocus?.showKeyboard()
+}
-inline fun Activity.snackbar(@StringRes textId: Int, duration: Int = Snackbar.LENGTH_LONG, noinline builder: Snackbar.() -> Unit = {}) = contentView!!.snackbar(textId, duration, builder) \ No newline at end of file
+/**
+ * Gets the view set by [Activity.setContentView] if it exists.
+ *
+ * Taken courtesy of <a href="https://github.com/Kotlin/anko">Anko</a>
+ *
+ * Previously, Anko was a dependency in KAU, but has been removed on 12/24/2018
+ * as most of the methods weren't used
+ */
+inline val Activity.contentView: View?
+ get() = (findViewById(android.R.id.content) as? ViewGroup)?.getChildAt(0)
+
+inline fun Activity.snackbar(
+ text: String,
+ duration: Int = Snackbar.LENGTH_LONG,
+ noinline builder: Snackbar.() -> Unit = {}
+) = contentView!!.snackbar(text, duration, builder)
+
+inline fun Activity.snackbar(
+ @StringRes textId: Int,
+ duration: Int = Snackbar.LENGTH_LONG,
+ noinline builder: Snackbar.() -> Unit = {}
+) = contentView!!.snackbar(textId, duration, builder)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt
index 2767f04..0062361 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimHolder.kt
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.os.Build
-import android.support.annotation.RequiresApi
+import androidx.annotation.RequiresApi
import ca.allanwang.kau.kotlin.lazyInterpolator
/**
@@ -14,5 +29,4 @@ object AnimHolder {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
val fastOutSlowInInterpolator = lazyInterpolator(android.R.interpolator.fast_out_linear_in)
val decelerateInterpolator = lazyInterpolator(android.R.interpolator.decelerate_cubic)
-
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt
index a287cf2..0a548ce 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/AnimUtils.kt
@@ -1,15 +1,30 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint
-import android.support.annotation.StringRes
import android.view.View
import android.view.ViewAnimationUtils
import android.view.ViewPropertyAnimator
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.TextView
+import androidx.annotation.StringRes
/**
* Created by Allan Wang on 2017-06-01.
@@ -19,7 +34,15 @@ import android.widget.TextView
@SuppressLint("NewApi")
@KauUtils
-fun View.circularReveal(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float = -1.0f, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
+fun View.circularReveal(
+ x: Int = 0,
+ y: Int = 0,
+ offset: Long = 0L,
+ radius: Float = -1.0f,
+ duration: Long = 500L,
+ onStart: (() -> Unit)? = null,
+ onFinish: (() -> Unit)? = null
+) {
if (!isAttachedToWindow) {
onStart?.invoke()
visible()
@@ -29,7 +52,10 @@ fun View.circularReveal(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float
if (!buildIsLollipopAndUp) return fadeIn(offset, duration, onStart, onFinish)
val r = if (radius >= 0) radius
- else Math.max(Math.hypot(x.toDouble(), y.toDouble()), Math.hypot((width - x.toDouble()), (height - y.toDouble()))).toFloat()
+ else Math.max(
+ Math.hypot(x.toDouble(), y.toDouble()),
+ Math.hypot((width - x.toDouble()), (height - y.toDouble()))
+ ).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(this, x, y, 0f, r).setDuration(duration)
anim.startDelay = offset
@@ -47,7 +73,15 @@ fun View.circularReveal(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float
@SuppressLint("NewApi")
@KauUtils
-fun View.circularHide(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float = -1.0f, duration: Long = 500L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
+fun View.circularHide(
+ x: Int = 0,
+ y: Int = 0,
+ offset: Long = 0L,
+ radius: Float = -1.0f,
+ duration: Long = 500L,
+ onStart: (() -> Unit)? = null,
+ onFinish: (() -> Unit)? = null
+) {
if (!isAttachedToWindow) {
onStart?.invoke()
invisible()
@@ -57,7 +91,10 @@ fun View.circularHide(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float =
if (!buildIsLollipopAndUp) return fadeOut(offset, duration, onStart, onFinish)
val r = if (radius >= 0) radius
- else Math.max(Math.hypot(x.toDouble(), y.toDouble()), Math.hypot((width - x.toDouble()), (height - y.toDouble()))).toFloat()
+ else Math.max(
+ Math.hypot(x.toDouble(), y.toDouble()),
+ Math.hypot((width - x.toDouble()), (height - y.toDouble()))
+ ).toFloat()
val anim = ViewAnimationUtils.createCircularReveal(this, x, y, r, 0f).setDuration(duration)
anim.startDelay = offset
@@ -75,7 +112,12 @@ fun View.circularHide(x: Int = 0, y: Int = 0, offset: Long = 0L, radius: Float =
}
@KauUtils
-fun View.fadeIn(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
+fun View.fadeIn(
+ offset: Long = 0L,
+ duration: Long = 200L,
+ onStart: (() -> Unit)? = null,
+ onFinish: (() -> Unit)? = null
+) {
if (!isAttachedToWindow) {
onStart?.invoke()
visible()
@@ -97,7 +139,12 @@ fun View.fadeIn(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)?
}
@KauUtils
-fun View.fadeOut(offset: Long = 0L, duration: Long = 200L, onStart: (() -> Unit)? = null, onFinish: (() -> Unit)? = null) {
+fun View.fadeOut(
+ offset: Long = 0L,
+ duration: Long = 200L,
+ onStart: (() -> Unit)? = null,
+ onFinish: (() -> Unit)? = null
+) {
if (!isAttachedToWindow) {
onStart?.invoke()
invisible()
@@ -130,7 +177,8 @@ fun TextView.setTextWithFade(text: String, duration: Long = 200, onFinish: (() -
}
@KauUtils
-fun TextView.setTextWithFade(@StringRes textId: Int, duration: Long = 200, onFinish: (() -> Unit)? = null) = setTextWithFade(context.getString(textId), duration, onFinish)
+fun TextView.setTextWithFade(@StringRes textId: Int, duration: Long = 200, onFinish: (() -> Unit)? = null) =
+ setTextWithFade(context.getString(textId), duration, onFinish)
@KauUtils
-fun ViewPropertyAnimator.scaleXY(value: Float) = scaleX(value).scaleY(value) \ No newline at end of file
+fun ViewPropertyAnimator.scaleXY(value: Float) = scaleX(value).scaleY(value)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/BundleUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/BundleUtils.kt
index 82cd577..40c1c72 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/BundleUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/BundleUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.annotation.SuppressLint
@@ -5,10 +20,12 @@ import android.app.Activity
import android.app.ActivityOptions
import android.content.Context
import android.os.Bundle
-import android.support.annotation.AnimRes
+import android.os.Parcelable
import android.util.Pair
import android.view.View
+import androidx.annotation.AnimRes
import ca.allanwang.kau.R
+import java.io.Serializable
/**
* Created by Allan Wang on 10/12/17.
@@ -22,6 +39,56 @@ infix fun Bundle.with(bundle: Bundle?): Bundle {
}
/**
+ * Saves all bundle args based on their respective types.
+ *
+ * Taken courtesy of <a href="https://github.com/Kotlin/anko">Anko</a>
+ *
+ * Previously, Anko was a dependency in KAU, but has been removed on 12/24/2018
+ * as most of the methods weren't used
+ */
+fun bundleOf(vararg params: kotlin.Pair<String, Any?>): Bundle {
+ val b = Bundle()
+ for (p in params) {
+ val (k, v) = p
+ when (v) {
+ null -> b.putSerializable(k, null)
+ is Boolean -> b.putBoolean(k, v)
+ is Byte -> b.putByte(k, v)
+ is Char -> b.putChar(k, v)
+ is Short -> b.putShort(k, v)
+ is Int -> b.putInt(k, v)
+ is Long -> b.putLong(k, v)
+ is Float -> b.putFloat(k, v)
+ is Double -> b.putDouble(k, v)
+ is String -> b.putString(k, v)
+ is CharSequence -> b.putCharSequence(k, v)
+ is Parcelable -> b.putParcelable(k, v)
+ is Serializable -> b.putSerializable(k, v)
+ is BooleanArray -> b.putBooleanArray(k, v)
+ is ByteArray -> b.putByteArray(k, v)
+ is CharArray -> b.putCharArray(k, v)
+ is DoubleArray -> b.putDoubleArray(k, v)
+ is FloatArray -> b.putFloatArray(k, v)
+ is IntArray -> b.putIntArray(k, v)
+ is LongArray -> b.putLongArray(k, v)
+ is Array<*> -> {
+ @Suppress("UNCHECKED_CAST")
+ when {
+ v.isArrayOf<Parcelable>() -> b.putParcelableArray(k, v as Array<out Parcelable>)
+ v.isArrayOf<CharSequence>() -> b.putCharSequenceArray(k, v as Array<out CharSequence>)
+ v.isArrayOf<String>() -> b.putStringArray(k, v as Array<out String>)
+ else -> throw KauException("Unsupported bundle component (${v.javaClass})")
+ }
+ }
+ is ShortArray -> b.putShortArray(k, v)
+ is Bundle -> b.putBundle(k, v)
+ else -> throw KauException("Unsupported bundle component (${v.javaClass})")
+ }
+ }
+ return b
+}
+
+/**
* Adds transition bundle if context is activity and build is lollipop+
*/
@SuppressLint("NewApi")
@@ -36,34 +103,46 @@ fun Bundle.withSceneTransitionAnimation(context: Context) {
* create a scene transition animation
*/
fun Bundle.withSceneTransitionAnimation(parent: View, data: Map<Int, String>) =
- withSceneTransitionAnimation(parent.context, data.mapKeys { (id, _) ->
- parent.findViewById<View>(id)
- })
+ withSceneTransitionAnimation(parent.context, data.mapKeys { (id, _) ->
+ parent.findViewById<View>(id)
+ })
/**
* Given a mapping of views to tags,
* create a scene transition animation
*/
@SuppressLint("NewApi")
-fun Bundle.withSceneTransitionAnimation(context: Context, data: Map<View, String>) {
+fun Bundle.withSceneTransitionAnimation(context: Context, data: Map<out View, String>) {
if (context !is Activity || !buildIsLollipopAndUp) return
- val options = ActivityOptions.makeSceneTransitionAnimation(context,
- *data.map { (view, tag) -> Pair(view, tag) }.toTypedArray())
+ val options = ActivityOptions.makeSceneTransitionAnimation(
+ context,
+ *data.map { (view, tag) -> Pair(view, tag) }.toTypedArray()
+ )
putAll(options.toBundle())
}
-fun Bundle.withCustomAnimation(context: Context,
- @AnimRes enterResId: Int,
- @AnimRes exitResId: Int) {
- this with ActivityOptions.makeCustomAnimation(context,
- enterResId, exitResId).toBundle()
+fun Bundle.withCustomAnimation(
+ context: Context,
+ @AnimRes enterResId: Int,
+ @AnimRes exitResId: Int
+) {
+ this with ActivityOptions.makeCustomAnimation(
+ context,
+ enterResId, exitResId
+ ).toBundle()
}
-fun Bundle.withSlideIn(context: Context) = withCustomAnimation(context,
- R.anim.kau_slide_in_right, R.anim.kau_fade_out)
+fun Bundle.withSlideIn(context: Context) = withCustomAnimation(
+ context,
+ R.anim.kau_slide_in_right, R.anim.kau_fade_out
+)
-fun Bundle.withSlideOut(context: Context) = withCustomAnimation(context,
- R.anim.kau_fade_in, R.anim.kau_slide_out_right_top)
+fun Bundle.withSlideOut(context: Context) = withCustomAnimation(
+ context,
+ R.anim.kau_fade_in, R.anim.kau_slide_out_right_top
+)
-fun Bundle.withFade(context: Context) = withCustomAnimation(context,
- android.R.anim.fade_in, android.R.anim.fade_out) \ No newline at end of file
+fun Bundle.withFade(context: Context) = withCustomAnimation(
+ context,
+ android.R.anim.fade_in, android.R.anim.fade_out
+)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt
index 236f2ca..bbb8953 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.annotation.SuppressLint
@@ -7,15 +22,21 @@ import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.os.Build
-import android.support.annotation.ColorInt
-import android.support.annotation.FloatRange
-import android.support.annotation.IntRange
-import android.support.v4.graphics.drawable.DrawableCompat
-import android.support.v7.widget.AppCompatEditText
-import android.support.v7.widget.Toolbar
-import android.widget.*
+import android.widget.CheckBox
+import android.widget.EditText
+import android.widget.ImageButton
+import android.widget.ProgressBar
+import android.widget.RadioButton
+import android.widget.SeekBar
+import android.widget.TextView
+import androidx.annotation.ColorInt
+import androidx.annotation.FloatRange
+import androidx.annotation.IntRange
+import androidx.appcompat.widget.AppCompatEditText
+import androidx.appcompat.widget.Toolbar
+import androidx.core.graphics.drawable.DrawableCompat
import com.afollestad.materialdialogs.R
-import java.util.*
+import java.util.Random
/**
* Created by Allan Wang on 2017-06-08.
@@ -38,7 +59,7 @@ inline val Int.isColorDark: Boolean
get() = isColorDark(0.5f)
fun Int.isColorDark(minDarkness: Float): Boolean =
- ((0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255.0) < minDarkness
+ ((0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255.0) < minDarkness
fun Int.toHexString(withAlpha: Boolean = false, withHexPrefix: Boolean = true): String {
val hex = if (withAlpha) String.format("#%08X", this)
@@ -46,7 +67,8 @@ fun Int.toHexString(withAlpha: Boolean = false, withHexPrefix: Boolean = true):
return if (withHexPrefix) hex else hex.substring(1)
}
-fun Int.toRgbaString(): String = "rgba(${Color.red(this)}, ${Color.green(this)}, ${Color.blue(this)}, ${(Color.alpha(this) / 255f).round(3)})"
+fun Int.toRgbaString(): String =
+ "rgba(${Color.red(this)}, ${Color.green(this)}, ${Color.blue(this)}, ${(Color.alpha(this) / 255f).round(3)})"
fun Int.toHSV(): FloatArray {
val hsv = FloatArray(3)
@@ -59,13 +81,15 @@ inline val Int.isColorOpaque: Boolean
fun FloatArray.toColor(): Int = Color.HSVToColor(this)
-fun Int.isColorVisibleOn(@ColorInt color: Int, @IntRange(from = 0L, to = 255L) delta: Int = 25,
- @IntRange(from = 0L, to = 255L) minAlpha: Int = 50): Boolean =
- if (Color.alpha(this) < minAlpha) false
- else !(Math.abs(Color.red(this) - Color.red(color)) < delta
- && Math.abs(Color.green(this) - Color.green(color)) < delta
- && Math.abs(Color.blue(this) - Color.blue(color)) < delta)
-
+fun Int.isColorVisibleOn(
+ @ColorInt color: Int,
+ @IntRange(from = 0L, to = 255L) delta: Int = 25,
+ @IntRange(from = 0L, to = 255L) minAlpha: Int = 50
+): Boolean =
+ if (Color.alpha(this) < minAlpha) false
+ else !(Math.abs(Color.red(this) - Color.red(color)) < delta &&
+ Math.abs(Color.green(this) - Color.green(color)) < delta &&
+ Math.abs(Color.blue(this) - Color.blue(color)) < delta)
@ColorInt
fun Context.getDisabledColor(): Int {
@@ -94,49 +118,58 @@ fun Int.blendWith(@ColorInt color: Int, @FloatRange(from = 0.0, to = 1.0) ratio:
}
@ColorInt
-fun Int.withAlpha(@IntRange(from = 0L, to = 255L) alpha: Int): Int = Color.argb(alpha, Color.red(this), Color.green(this), Color.blue(this))
+fun Int.withAlpha(@IntRange(from = 0, to = 0xFF) alpha: Int): Int =
+ this and 0x00FFFFFF or (alpha shl 24)
@ColorInt
-fun Int.withMinAlpha(@IntRange(from = 0L, to = 255L) alpha: Int): Int = Color.argb(Math.max(alpha, Color.alpha(this)), Color.red(this), Color.green(this), Color.blue(this))
+fun Int.withMinAlpha(@IntRange(from = 0, to = 0xFF) alpha: Int): Int =
+ withAlpha(Math.max(alpha, this ushr 24))
@ColorInt
-fun Int.lighten(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int {
+private inline fun Int.colorFactor(rgbFactor: (Int) -> Float): Int {
val (red, green, blue) = intArrayOf(Color.red(this), Color.green(this), Color.blue(this))
- .map { (it * (1f - factor) + 255f * factor).toInt() }
+ .map { rgbFactor(it).toInt() }
return Color.argb(Color.alpha(this), red, green, blue)
}
@ColorInt
-fun Int.darken(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int {
- val (red, green, blue) = intArrayOf(Color.red(this), Color.green(this), Color.blue(this))
- .map { (it * (1f - factor)).toInt() }
- return Color.argb(Color.alpha(this), red, green, blue)
+fun Int.lighten(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = colorFactor {
+ (it * (1f - factor) + 255f * factor)
}
@ColorInt
-fun Int.colorToBackground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = if (isColorDark) darken(factor) else lighten(factor)
+fun Int.darken(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = colorFactor {
+ it * (1f - factor)
+}
+
+@ColorInt
+fun Int.colorToBackground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int =
+ if (isColorDark) darken(factor) else lighten(factor)
@ColorInt
-fun Int.colorToForeground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = if (isColorDark) lighten(factor) else darken(factor)
+fun Int.colorToForeground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int =
+ if (isColorDark) lighten(factor) else darken(factor)
-@Throws(IllegalArgumentException::class)
fun String.toColor(): Int {
- val toParse: String
- if (startsWith("#") && length == 4)
- toParse = "#${this[1]}${this[1]}${this[2]}${this[2]}${this[3]}${this[3]}"
+ val toParse: String = if (startsWith("#") && length == 4)
+ "#${this[1]}${this[1]}${this[2]}${this[2]}${this[3]}${this[3]}"
else
- toParse = this
+ this
return Color.parseColor(toParse)
}
//Get ColorStateList
fun Context.colorStateList(@ColorInt color: Int): ColorStateList {
val disabledColor = color.adjustAlpha(0.3f)
- return ColorStateList(arrayOf(intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
+ return ColorStateList(
+ arrayOf(
+ intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_enabled, -android.R.attr.state_checked),
- intArrayOf(-android.R.attr.state_enabled, android.R.attr.state_checked)),
- intArrayOf(color.adjustAlpha(0.8f), color, disabledColor, disabledColor))
+ intArrayOf(-android.R.attr.state_enabled, android.R.attr.state_checked)
+ ),
+ intArrayOf(color.adjustAlpha(0.8f), color, disabledColor, disabledColor)
+ )
}
/*
@@ -203,14 +236,14 @@ fun ProgressBar.tint(@ColorInt color: Int, skipIndeterminate: Boolean = false) {
fun Context.textColorStateList(@ColorInt color: Int): ColorStateList {
val states = arrayOf(
- intArrayOf(-android.R.attr.state_enabled),
- intArrayOf(-android.R.attr.state_pressed, -android.R.attr.state_focused),
- intArrayOf()
+ intArrayOf(-android.R.attr.state_enabled),
+ intArrayOf(-android.R.attr.state_pressed, -android.R.attr.state_focused),
+ intArrayOf()
)
val colors = intArrayOf(
- resolveColor(R.attr.colorControlNormal),
- resolveColor(R.attr.colorControlNormal),
- color
+ resolveColor(R.attr.colorControlNormal),
+ resolveColor(R.attr.colorControlNormal),
+ color
)
return ColorStateList(states, colors)
}
@@ -254,4 +287,4 @@ fun Toolbar.tint(@ColorInt color: Int, tintTitle: Boolean = true) {
setSubtitleTextColor(color)
}
(0 until childCount).asSequence().forEach { (getChildAt(it) as? ImageButton)?.setColorFilter(color) }
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt
index 1eeac1a..9dca16c 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Const.kt
@@ -1,6 +1,21 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
-import android.support.v4.widget.ViewDragHelper
+import androidx.customview.widget.ViewDragHelper
/**
* Created by Allan Wang on 2017-06-08.
@@ -20,4 +35,4 @@ const val KAU_COLLAPSING = 1
const val KAU_EXPANDING = 2
const val KAU_EXPANDED = 3
-const val KAU_ELLIPSIS = '\u2026' \ No newline at end of file
+const val KAU_ELLIPSIS = '\u2026'
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
index 6568bf2..82d5608 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2017 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
@file:Suppress("NOTHING_TO_INLINE")
package ca.allanwang.kau.utils
@@ -11,20 +26,35 @@ import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
-import android.support.annotation.*
-import android.support.v4.content.ContextCompat
+import android.os.Looper
import android.util.TypedValue
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.Toast
+import androidx.annotation.AnimRes
+import androidx.annotation.AttrRes
+import androidx.annotation.BoolRes
+import androidx.annotation.ColorInt
+import androidx.annotation.ColorRes
+import androidx.annotation.DimenRes
+import androidx.annotation.DrawableRes
+import androidx.annotation.IntegerRes
+import androidx.annotation.InterpolatorRes
+import androidx.annotation.PluralsRes
+import androidx.annotation.StringRes
+import androidx.core.content.ContextCompat
import ca.allanwang.kau.R
import ca.allanwang.kau.logging.KL
+import com.afollestad.materialdialogs.DialogBehavior
import com.afollestad.materialdialogs.MaterialDialog
-
+import com.afollestad.materialdialogs.ModalDialog
/**
* Created by Allan Wang on 2017-06-03.
*/
+fun Context.runOnUiThread(f: Context.() -> Unit) {
+ if (ContextHelper.looper === Looper.myLooper()) f() else ContextHelper.handler.post { f() }
+}
/**
* Helper class to launch an activity from a context
@@ -33,19 +63,22 @@ import com.afollestad.materialdialogs.MaterialDialog
*/
@Suppress("DEPRECATION")
inline fun <reified T : Activity> Context.startActivity(
- clearStack: Boolean = false,
- bundleBuilder: Bundle.() -> Unit = {},
- intentBuilder: Intent.() -> Unit = {}
+ clearStack: Boolean = false,
+ bundleBuilder: Bundle.() -> Unit = {},
+ intentBuilder: Intent.() -> Unit = {}
) = startActivity(T::class.java, clearStack, bundleBuilder, intentBuilder)
-@Deprecated("Use reified generic instead of passing class",
- ReplaceWith("startActivity<T>(clearStack, bundleBuilder, intentBuilder)"),
- DeprecationLevel.WARNING)
+@Deprecated(
+ "Use reified generic instead of passing class",
+ ReplaceWith("startActivity<T>(clearStack, bundleBuilder, intentBuilder)"),
+ DeprecationLevel.WARNING
+)
inline fun <T : Activity> Context.startActivity(
- clazz: Class<T>,
- clearStack: Boolean = false,
- bundleBuilder: Bundle.() -> Unit = {},
- intentBuilder: Intent.() -> Unit = {}) {
+ clazz: Class<T>,
+ clearStack: Boolean = false,
+ bundleBuilder: Bundle.() -> Unit = {},
+ intentBuilder: Intent.() -> Unit = {}
+) {
val intent = Intent(this, clazz)
if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
intent.intentBuilder()
@@ -55,7 +88,6 @@ inline fun <T : Activity> Context.startActivity(
if (clearStack && this is Activity) finish()
}
-
fun Context.startPlayStoreLink(@StringRes packageIdRes: Int) = startPlayStoreLink(string(packageIdRes))
fun Context.startPlayStoreLink(packageId: String) {
@@ -82,11 +114,14 @@ fun Context.startLink(vararg url: String?) {
fun Context.startLink(@StringRes url: Int) = startLink(string(url))
//Toast helpers
-inline fun View.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = context.toast(id, duration, log)
+inline fun View.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) =
+ context.toast(id, duration, log)
-inline fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = toast(this.string(id), duration, log)
+inline fun Context.toast(@StringRes id: Int, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) =
+ toast(this.string(id), duration, log)
-inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) = context.toast(text, duration, log)
+inline fun View.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) =
+ context.toast(text, duration, log)
inline fun Context.toast(text: String, duration: Int = Toast.LENGTH_LONG, log: Boolean = false) {
Toast.makeText(this, text, duration).show()
@@ -98,24 +133,33 @@ const val INVALID_ID = 0
//Resource retrievers
inline fun Context.string(@StringRes id: Int): String = getString(id)
-inline fun Context.string(@StringRes id: Int, fallback: String?): String? = if (id != INVALID_ID) string(id) else fallback
-inline fun Context.string(@StringRes id: Int, fallback: () -> String?): String? = if (id != INVALID_ID) string(id) else fallback()
+inline fun Context.string(@StringRes id: Int, fallback: String?): String? =
+ if (id != INVALID_ID) string(id) else fallback
+
+inline fun Context.string(@StringRes id: Int, fallback: () -> String?): String? =
+ if (id != INVALID_ID) string(id) else fallback()
+
inline fun Context.color(@ColorRes id: Int): Int = ContextCompat.getColor(this, id)
inline fun Context.boolean(@BoolRes id: Int): Boolean = resources.getBoolean(id)
inline fun Context.integer(@IntegerRes id: Int): Int = resources.getInteger(id)
inline fun Context.dimen(@DimenRes id: Int): Float = resources.getDimension(id)
inline fun Context.dimenPixelSize(@DimenRes id: Int): Int = resources.getDimensionPixelSize(id)
inline fun Context.drawable(@DrawableRes id: Int): Drawable = ContextCompat.getDrawable(this, id)
- ?: throw KauException("Drawable with id $id not found")
+ ?: throw KauException("Drawable with id $id not found")
+
+inline fun Context.drawable(@DrawableRes id: Int, fallback: Drawable?): Drawable? =
+ if (id != INVALID_ID) drawable(id) else fallback
+
+inline fun Context.drawable(@DrawableRes id: Int, fallback: () -> Drawable?): Drawable? =
+ if (id != INVALID_ID) drawable(id) else fallback()
-inline fun Context.drawable(@DrawableRes id: Int, fallback: Drawable?): Drawable? = if (id != INVALID_ID) drawable(id) else fallback
-inline fun Context.drawable(@DrawableRes id: Int, fallback: () -> Drawable?): Drawable? = if (id != INVALID_ID) drawable(id) else fallback()
inline fun Context.interpolator(@InterpolatorRes id: Int) = AnimationUtils.loadInterpolator(this, id)!!
inline fun Context.animation(@AnimRes id: Int) = AnimationUtils.loadAnimation(this, id)!!
/**
* Returns plural form of res. The quantity is also passed to the formatter as an int
*/
-inline fun Context.plural(@PluralsRes id: Int, quantity: Number) = resources.getQuantityString(id, quantity.toInt(), quantity.toInt())!!
+inline fun Context.plural(@PluralsRes id: Int, quantity: Number) =
+ resources.getQuantityString(id, quantity.toInt(), quantity.toInt())
//Attr retrievers
fun Context.resolveColor(@AttrRes attr: Int, @ColorInt fallback: Int = 0): Int {
@@ -151,20 +195,24 @@ fun Context.resolveString(@AttrRes attr: Int, fallback: String = ""): String {
}
/**
- * Wrapper function for the MaterialDialog adapterBuilder
- * There is no need to call build() or show() as those are done by default
+ * Wrapper function for MaterialDialog
+ *
+ * Mainly handles invalid creations, such as showing a dialog when an activity is finishing
+ * See https://github.com/afollestad/material-dialogs/issues/1778
*/
-inline fun Context.materialDialog(action: MaterialDialog.Builder.() -> Unit): MaterialDialog {
- val builder = MaterialDialog.Builder(this)
- builder.action()
+inline fun Context.materialDialog(
+ dialogBehavior: DialogBehavior = ModalDialog,
+ action: MaterialDialog.() -> Unit
+) {
+ val dialog = MaterialDialog(this, dialogBehavior)
if (isFinishing) {
- KL.d { "Material Dialog triggered from finishing context; did not show" }
- return builder.build()
+ return KL.d { "Material Dialog triggered from finishing context; did not show" }
}
- return builder.show()
+ dialog.show(action)
}
-fun Context.getDip(value: Float): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, resources.displayMetrics)
+fun Context.getDip(value: Float): Float =
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, resources.displayMetrics)
inline val Context.isRtl: Boolean
get() = resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
@@ -181,7 +229,10 @@ inline val Context.isNavBarOnBottom: Boolean
return !canMove || dm.widthPixels < dm.heightPixels
}
-fun Context.hasPermission(permissions: String) = !buildIsMarshmallowAndUp || ContextCompat.checkSelfPermission(this, permissions) == PackageManager.PERMISSION_GRANTED
+fun Context.hasPermission(permissions: String) = !buildIsMarshmallowAndUp || ContextCompat.checkSelfPermission(
+ this,
+ permissions
+) == PackageManager.PERMISSION_GRANTED
fun Context.copyToClipboard(text: String?, label: String = "Copied Text", showToast: Boolean = true) {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
@@ -207,4 +258,4 @@ fun Context.shareText(text: String?) {
* As of now, it is only checked when tied to an activity
*/
inline val Context.isFinishing: Boolean
- get() = (this as? Activity)?.isFinishing ?: false \ No newline at end of file
+ get() = (this as? Activity)?.isFinishing ?: false
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/CoroutineUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/CoroutineUtils.kt
new file mode 100644
index 0000000..57a9921
--- /dev/null
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/CoroutineUtils.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2019 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ca.allanwang.kau.utils
+
+import android.content.Context
+import android.os.Handler
+import android.os.Looper
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.android.asCoroutineDispatcher
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+
+object ContextHelper : CoroutineScope {
+
+ val looper = Looper.getMainLooper()
+
+ val handler = Handler(looper)
+
+ /**
+ * Creating dispatcher from main handler to avoid IO
+ * See https://github.com/Kotlin/kotlinx.coroutines/issues/878
+ */
+ val dispatcher = handler.asCoroutineDispatcher("kau-main")
+
+ override val coroutineContext: CoroutineContext get() = dispatcher
+}
+
+/**
+ * Most context items implement [CoroutineScope] by default.
+ * We will add a fallback just in case.
+ * It is expected that the scope returned always has the Android main dispatcher as part of the context.
+ */
+internal inline val Context.ctxCoroutine: CoroutineScope
+ get() = this as? CoroutineScope ?: ContextHelper
+
+/**
+ * Calls [launch] with an explicit dispatcher for Android's main thread
+ */
+fun CoroutineScope.launchMain(
+ context: CoroutineContext = EmptyCoroutineContext,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ block: suspend CoroutineScope.() -> Unit
+) = launch(ContextHelper.dispatcher + context, start, block)
+
+/**
+ * Calls [async] with an explicit dispatcher for Android's main thread
+ */
+fun CoroutineScope.asyncMain(
+ context: CoroutineContext = EmptyCoroutineContext,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ block: suspend CoroutineScope.() -> Unit
+) = async(ContextHelper.dispatcher + context, start, block)
+
+/**
+ * Calls [withContext] with an explicit dispatcher for Android's main thread
+ */
+suspend fun <T> withMainContext(block: suspend CoroutineScope.() -> T) =
+ withContext(ContextHelper.dispatcher, block)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/DrawableUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/DrawableUtils.kt
index dae3bff..6950f2f 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/DrawableUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/DrawableUtils.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
-import android.support.annotation.ColorInt
-import android.support.v4.graphics.drawable.DrawableCompat
+import androidx.annotation.ColorInt
+import androidx.core.graphics.drawable.DrawableCompat
/**
* Wrap the color into a state and tint the drawable
@@ -17,4 +32,4 @@ fun Drawable.tint(state: ColorStateList): Drawable {
val drawable = DrawableCompat.wrap(mutate())
DrawableCompat.setTintList(drawable, state)
return drawable
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/FileUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/FileUtils.kt
index bfbc009..1d27bfc 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/FileUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/FileUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import java.io.File
@@ -6,4 +21,5 @@ import java.io.InputStream
/**
* Created by Allan Wang on 2017-08-04.
*/
-fun File.copyFromInputStream(inputStream: InputStream) = inputStream.use { input -> outputStream().use { output -> input.copyTo(output) } } \ No newline at end of file
+fun File.copyFromInputStream(inputStream: InputStream) =
+ inputStream.use { input -> outputStream().use { output -> input.copyTo(output) } }
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/FontUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/FontUtils.kt
index 1db7694..064d70b 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/FontUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/FontUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.Context
@@ -14,17 +29,17 @@ object FontUtils {
synchronized(sTypefaceCache) {
if (!sTypefaceCache.containsKey(font)) {
val tf = Typeface.createFromAsset(
- context.applicationContext.assets, "fonts/$font.ttf")
+ context.applicationContext.assets, "fonts/$font.ttf"
+ )
sTypefaceCache.put(font, tf)
}
return sTypefaceCache.get(font)
- ?: throw IllegalArgumentException("Font error; typeface does not exist at assets/fonts$font.ttf")
+ ?: throw IllegalArgumentException("Font error; typeface does not exist at assets/fonts$font.ttf")
}
}
fun getName(typeface: Typeface): String? = sTypefaceCache.entries.firstOrNull { it.value == typeface }?.key
-
}
fun Context.getFont(font: String) = FontUtils.get(this, font)
-fun Context.getFontName(typeface: Typeface) = FontUtils.getName(typeface) \ No newline at end of file
+fun Context.getFontName(typeface: Typeface) = FontUtils.getName(typeface)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/FragmentUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/FragmentUtils.kt
index acc71f2..75dc1c1 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/FragmentUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/FragmentUtils.kt
@@ -1,12 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
-import android.support.v4.app.Fragment
-import org.jetbrains.anko.bundleOf
+import androidx.fragment.app.Fragment
/**
* Created by Allan Wang on 2017-07-02.
*/
-fun <T : Fragment> T.withArguments(vararg params: Pair<String, Any>): T {
+fun <T : Fragment> T.withArguments(vararg params: Pair<String, Any?>): T {
arguments = bundleOf(*params)
return this
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt
index 51691af..8b40352 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/IIconUtils.kt
@@ -1,10 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.Drawable
-import android.support.annotation.ColorInt
+import androidx.annotation.ColorInt
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.IIcon
@@ -12,10 +27,15 @@ import com.mikepenz.iconics.typeface.IIcon
* Created by Allan Wang on 2017-05-29.
*/
@KauUtils
-fun IIcon.toDrawable(c: Context, sizeDp: Int = 24, @ColorInt color: Int = Color.WHITE, builder: IconicsDrawable.() -> Unit = {}): Drawable {
+fun IIcon.toDrawable(
+ c: Context,
+ sizeDp: Int = 24,
+ @ColorInt color: Int = Color.WHITE,
+ builder: IconicsDrawable.() -> Unit = {}
+): Drawable {
val state = ColorStateList.valueOf(color)
val icon = IconicsDrawable(c).icon(this).color(state)
if (sizeDp > 0) icon.sizeDp(sizeDp)
icon.builder()
return icon
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt
index 8c7c039..8765c69 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Kotterknife.kt
@@ -1,4 +1,19 @@
-@file:Suppress("UNCHECKED_CAST")
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:Suppress("UNCHECKED_CAST", "DEPRECATION")
package ca.allanwang.kau.utils
@@ -8,148 +23,89 @@ package ca.allanwang.kau.utils
* Courtesy of Jake Wharton
*
* https://github.com/JakeWharton/kotterknife/blob/master/src/main/kotlin/kotterknife/ButterKnife.kt
+ *
+ * Note that while this is useful for binding ids, there also exists other alternatives, such as
+ * `kotlin-android-extensions`.
+ *
+ * For fragments, make sure that the views are reset after the fragment lifecycle.
*/
import android.app.Activity
import android.app.Dialog
import android.app.DialogFragment
import android.app.Fragment
-import android.support.v7.widget.RecyclerView.ViewHolder
import android.view.View
-import java.util.*
+import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import java.util.Collections
+import java.util.WeakHashMap
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
-import android.support.v4.app.DialogFragment as SupportDialogFragment
-import android.support.v4.app.Fragment as SupportFragment
-
-private const val DEPRECATION_MESSAGE = "Kotterknife will be removed in favour of the kotlin_android_extensions plugin"
+import androidx.fragment.app.DialogFragment as SupportDialogFragment
+import androidx.fragment.app.Fragment as SupportFragment
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindView(id: Int)
- : ReadOnlyProperty<View, V> = required(id, viewFinder)
+fun <V : View> View.bindView(id: Int): ReadOnlyProperty<View, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindView(id: Int)
- : ReadOnlyProperty<Activity, V> = required(id, viewFinder)
+fun <V : View> Activity.bindView(id: Int): ReadOnlyProperty<Activity, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindView(id: Int)
- : ReadOnlyProperty<Dialog, V> = required(id, viewFinder)
+fun <V : View> Dialog.bindView(id: Int): ReadOnlyProperty<Dialog, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindView(id: Int)
- : ReadOnlyProperty<DialogFragment, V> = required(id, viewFinder)
+fun <V : View> DialogFragment.bindView(id: Int): ReadOnlyProperty<DialogFragment, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindView(id: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, V> = required(id, viewFinder)
+fun <V : View> SupportDialogFragment.bindView(id: Int): ReadOnlyProperty<SupportDialogFragment, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindView(id: Int)
- : ReadOnlyProperty<Fragment, V> = required(id, viewFinder)
+fun <V : View> Fragment.bindView(id: Int): ReadOnlyProperty<Fragment, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindView(id: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, V> = required(id, viewFinder)
+fun <V : View> SupportFragment.bindView(id: Int): ReadOnlyProperty<SupportFragment, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindView(id: Int)
- : ReadOnlyProperty<ViewHolder, V> = required(id, viewFinder)
+fun <V : View> RecyclerView.ViewHolder.bindView(id: Int): ReadOnlyProperty<RecyclerView.ViewHolder, V> = required(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindOptionalView(id: Int)
- : ReadOnlyProperty<View, V?> = optional(id, viewFinder)
+fun <V : View> View.bindOptionalView(id: Int): ReadOnlyProperty<View, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindOptionalView(id: Int)
- : ReadOnlyProperty<Activity, V?> = optional(id, viewFinder)
+fun <V : View> Activity.bindOptionalView(id: Int): ReadOnlyProperty<Activity, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindOptionalView(id: Int)
- : ReadOnlyProperty<Dialog, V?> = optional(id, viewFinder)
+fun <V : View> Dialog.bindOptionalView(id: Int): ReadOnlyProperty<Dialog, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindOptionalView(id: Int)
- : ReadOnlyProperty<DialogFragment, V?> = optional(id, viewFinder)
+fun <V : View> DialogFragment.bindOptionalView(id: Int): ReadOnlyProperty<DialogFragment, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindOptionalView(id: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, V?> = optional(id, viewFinder)
+fun <V : View> SupportDialogFragment.bindOptionalView(id: Int): ReadOnlyProperty<SupportDialogFragment, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindOptionalView(id: Int)
- : ReadOnlyProperty<Fragment, V?> = optional(id, viewFinder)
+fun <V : View> Fragment.bindOptionalView(id: Int): ReadOnlyProperty<Fragment, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindOptionalView(id: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, V?> = optional(id, viewFinder)
+fun <V : View> SupportFragment.bindOptionalView(id: Int): ReadOnlyProperty<SupportFragment, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindOptionalView(id: Int)
- : ReadOnlyProperty<ViewHolder, V?> = optional(id, viewFinder)
+fun <V : View> RecyclerView.ViewHolder.bindOptionalView(id: Int): ReadOnlyProperty<RecyclerView.ViewHolder, V?> = optional(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindViews(vararg ids: Int)
- : ReadOnlyProperty<View, List<V>> = required(ids, viewFinder)
+fun <V : View> View.bindViews(vararg ids: Int): ReadOnlyProperty<View, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindViews(vararg ids: Int)
- : ReadOnlyProperty<Activity, List<V>> = required(ids, viewFinder)
+fun <V : View> Activity.bindViews(vararg ids: Int): ReadOnlyProperty<Activity, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindViews(vararg ids: Int)
- : ReadOnlyProperty<Dialog, List<V>> = required(ids, viewFinder)
+fun <V : View> Dialog.bindViews(vararg ids: Int): ReadOnlyProperty<Dialog, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindViews(vararg ids: Int)
- : ReadOnlyProperty<DialogFragment, List<V>> = required(ids, viewFinder)
+fun <V : View> DialogFragment.bindViews(vararg ids: Int): ReadOnlyProperty<DialogFragment, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindViews(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, List<V>> = required(ids, viewFinder)
+fun <V : View> SupportDialogFragment.bindViews(vararg ids: Int): ReadOnlyProperty<SupportDialogFragment, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindViews(vararg ids: Int)
- : ReadOnlyProperty<Fragment, List<V>> = required(ids, viewFinder)
+fun <V : View> Fragment.bindViews(vararg ids: Int): ReadOnlyProperty<Fragment, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindViews(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, List<V>> = required(ids, viewFinder)
+fun <V : View> SupportFragment.bindViews(vararg ids: Int): ReadOnlyProperty<SupportFragment, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindViews(vararg ids: Int)
- : ReadOnlyProperty<ViewHolder, List<V>> = required(ids, viewFinder)
+fun <V : View> ViewHolder.bindViews(vararg ids: Int): ReadOnlyProperty<ViewHolder, List<V>> = required(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<View, List<V>> = optional(ids, viewFinder)
+fun <V : View> View.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<View, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<Activity, List<V>> = optional(ids, viewFinder)
+fun <V : View> Activity.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<Activity, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<Dialog, List<V>> = optional(ids, viewFinder)
+fun <V : View> Dialog.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<Dialog, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<DialogFragment, List<V>> = optional(ids, viewFinder)
+fun <V : View> DialogFragment.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<DialogFragment, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, List<V>> = optional(ids, viewFinder)
+fun <V : View> SupportDialogFragment.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<SupportDialogFragment, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<Fragment, List<V>> = optional(ids, viewFinder)
+fun <V : View> Fragment.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<Fragment, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, List<V>> = optional(ids, viewFinder)
+fun <V : View> SupportFragment.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<SupportFragment, List<V>> = optional(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindOptionalViews(vararg ids: Int)
- : ReadOnlyProperty<ViewHolder, List<V>> = optional(ids, viewFinder)
+fun <V : View> ViewHolder.bindOptionalViews(vararg ids: Int): ReadOnlyProperty<ViewHolder, List<V>> = optional(ids, viewFinder)
private inline val View.viewFinder: View.(Int) -> View?
get() = { findViewById(it) }
@@ -162,14 +118,14 @@ private inline val DialogFragment.viewFinder: DialogFragment.(Int) -> View?
private inline val SupportDialogFragment.viewFinder: SupportDialogFragment.(Int) -> View?
get() = { dialog.findViewById(it) }
private inline val Fragment.viewFinder: Fragment.(Int) -> View?
- get() = { view.findViewById(it) }
+ get() = { view!!.findViewById(it) }
private inline val SupportFragment.viewFinder: SupportFragment.(Int) -> View?
get() = { view!!.findViewById(it) }
private inline val ViewHolder.viewFinder: ViewHolder.(Int) -> View?
get() = { itemView.findViewById(it) }
private fun viewNotFound(id: Int, desc: KProperty<*>): Nothing =
- throw IllegalStateException("View ID $id for '${desc.name}' not found.")
+ throw IllegalStateException("View ID $id for '${desc.name}' not found.")
private fun <T, V : View> required(id: Int, finder: T.(Int) -> View?) = Lazy { t: T, desc ->
(t.finder(id) as V?)?.apply { } ?: viewNotFound(id, desc)
@@ -183,7 +139,8 @@ private fun <T, V : View> required(ids: IntArray, finder: T.(Int) -> View?) = La
}
}
-private fun <T, V : View> optional(ids: IntArray, finder: T.(Int) -> View?) = Lazy { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() }
+private fun <T, V : View> optional(ids: IntArray, finder: T.(Int) -> View?) =
+ Lazy { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() }
// Like Kotlin's lazy delegate but the initializer gets the target and metadata passed to it
private open class Lazy<in T, out V>(private val initializer: (T, KProperty<*>) -> V) : ReadOnlyProperty<T, V> {
@@ -209,139 +166,76 @@ private open class Lazy<in T, out V>(private val initializer: (T, KProperty<*>)
* Credits to <a href="https://github.com/MichaelRocks">MichaelRocks</a>
*/
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindViewResettable(id: Int)
- : ReadOnlyProperty<View, V> = requiredResettable(id, viewFinder)
+fun <V : View> View.bindViewResettable(id: Int): ReadOnlyProperty<View, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindViewResettable(id: Int)
- : ReadOnlyProperty<Activity, V> = requiredResettable(id, viewFinder)
+fun <V : View> Activity.bindViewResettable(id: Int): ReadOnlyProperty<Activity, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindViewResettable(id: Int)
- : ReadOnlyProperty<Dialog, V> = requiredResettable(id, viewFinder)
+fun <V : View> Dialog.bindViewResettable(id: Int): ReadOnlyProperty<Dialog, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindViewResettable(id: Int)
- : ReadOnlyProperty<DialogFragment, V> = requiredResettable(id, viewFinder)
+fun <V : View> DialogFragment.bindViewResettable(id: Int): ReadOnlyProperty<DialogFragment, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindViewResettable(id: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, V> = requiredResettable(id, viewFinder)
+fun <V : View> SupportDialogFragment.bindViewResettable(id: Int): ReadOnlyProperty<SupportDialogFragment, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindViewResettable(id: Int)
- : ReadOnlyProperty<Fragment, V> = requiredResettable(id, viewFinder)
+fun <V : View> Fragment.bindViewResettable(id: Int): ReadOnlyProperty<Fragment, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindViewResettable(id: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, V> = requiredResettable(id, viewFinder)
+fun <V : View> SupportFragment.bindViewResettable(id: Int): ReadOnlyProperty<SupportFragment, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindViewResettable(id: Int)
- : ReadOnlyProperty<ViewHolder, V> = requiredResettable(id, viewFinder)
+fun <V : View> ViewHolder.bindViewResettable(id: Int): ReadOnlyProperty<ViewHolder, V> = requiredResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<View, V?> = optionalResettable(id, viewFinder)
+fun <V : View> View.bindOptionalViewResettable(id: Int): ReadOnlyProperty<View, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<Activity, V?> = optionalResettable(id, viewFinder)
+fun <V : View> Activity.bindOptionalViewResettable(id: Int): ReadOnlyProperty<Activity, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<Dialog, V?> = optionalResettable(id, viewFinder)
+fun <V : View> Dialog.bindOptionalViewResettable(id: Int): ReadOnlyProperty<Dialog, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<DialogFragment, V?> = optionalResettable(id, viewFinder)
+fun <V : View> DialogFragment.bindOptionalViewResettable(id: Int): ReadOnlyProperty<DialogFragment, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, V?> = optionalResettable(id, viewFinder)
+fun <V : View> SupportDialogFragment.bindOptionalViewResettable(id: Int): ReadOnlyProperty<SupportDialogFragment, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<Fragment, V?> = optionalResettable(id, viewFinder)
+fun <V : View> Fragment.bindOptionalViewResettable(id: Int): ReadOnlyProperty<Fragment, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, V?> = optionalResettable(id, viewFinder)
+fun <V : View> SupportFragment.bindOptionalViewResettable(id: Int): ReadOnlyProperty<SupportFragment, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindOptionalViewResettable(id: Int)
- : ReadOnlyProperty<ViewHolder, V?> = optionalResettable(id, viewFinder)
+fun <V : View> ViewHolder.bindOptionalViewResettable(id: Int): ReadOnlyProperty<ViewHolder, V?> = optionalResettable(id, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<View, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> View.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<View, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<Activity, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> Activity.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<Activity, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<Dialog, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> Dialog.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<Dialog, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<DialogFragment, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> DialogFragment.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<DialogFragment, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> SupportDialogFragment.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<SupportDialogFragment, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<Fragment, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> Fragment.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<Fragment, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> SupportFragment.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<SupportFragment, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<ViewHolder, List<V>> = requiredResettable(ids, viewFinder)
+fun <V : View> ViewHolder.bindViewsResettable(vararg ids: Int): ReadOnlyProperty<ViewHolder, List<V>> = requiredResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> View.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<View, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> View.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<View, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Activity.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<Activity, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> Activity.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<Activity, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Dialog.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<Dialog, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> Dialog.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<Dialog, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> DialogFragment.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<DialogFragment, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> DialogFragment.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<DialogFragment, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportDialogFragment.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.DialogFragment, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> SupportDialogFragment.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<SupportDialogFragment, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> Fragment.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<Fragment, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> Fragment.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<Fragment, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> SupportFragment.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<android.support.v4.app.Fragment, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> SupportFragment.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<SupportFragment, List<V>> = optionalResettable(ids, viewFinder)
-@Deprecated(DEPRECATION_MESSAGE)
-fun <V : View> ViewHolder.bindOptionalViewsResettable(vararg ids: Int)
- : ReadOnlyProperty<ViewHolder, List<V>> = optionalResettable(ids, viewFinder)
+fun <V : View> ViewHolder.bindOptionalViewsResettable(vararg ids: Int): ReadOnlyProperty<RecyclerView.ViewHolder, List<V>> = optionalResettable(ids, viewFinder)
private fun <T, V : View> requiredResettable(id: Int, finder: T.(Int) -> View?) = LazyResettable { t: T, desc ->
(t.finder(id) as V?)?.apply { } ?: viewNotFound(id, desc)
}
-private fun <T, V : View> optionalResettable(id: Int, finder: T.(Int) -> View?) = LazyResettable { t: T, _ -> t.finder(id) as V? }
+private fun <T, V : View> optionalResettable(id: Int, finder: T.(Int) -> View?) =
+ LazyResettable { t: T, _ -> t.finder(id) as V? }
private fun <T, V : View> requiredResettable(ids: IntArray, finder: T.(Int) -> View?) = LazyResettable { t: T, desc ->
ids.map {
@@ -349,7 +243,8 @@ private fun <T, V : View> requiredResettable(ids: IntArray, finder: T.(Int) -> V
}
}
-private fun <T, V : View> optionalResettable(ids: IntArray, finder: T.(Int) -> View?) = LazyResettable { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() }
+private fun <T, V : View> optionalResettable(ids: IntArray, finder: T.(Int) -> View?) =
+ LazyResettable { t: T, _ -> ids.map { t.finder(it) as V? }.filterNotNull() }
//Like Kotterknife's lazy delegate but is resettable
private class LazyResettable<in T, out V>(initializer: (T, KProperty<*>) -> V) : Lazy<T, V>(initializer) {
@@ -363,7 +258,6 @@ private class LazyResettable<in T, out V>(initializer: (T, KProperty<*>) -> V) :
}
}
-@Deprecated(DEPRECATION_MESSAGE)
object Kotterknife {
fun reset(target: Any) {
KotterknifeRegistry.reset(target)
@@ -373,7 +267,8 @@ object Kotterknife {
private object KotterknifeRegistry {
private val lazyMap = WeakHashMap<Any, MutableCollection<LazyResettable<*, *>>>()
- fun register(target: Any, lazy: LazyResettable<*, *>) = lazyMap.getOrPut(target, { Collections.newSetFromMap(WeakHashMap()) }).add(lazy)
+ fun register(target: Any, lazy: LazyResettable<*, *>) =
+ lazyMap.getOrPut(target, { Collections.newSetFromMap(WeakHashMap()) }).add(lazy)
fun reset(target: Any) = lazyMap[target]?.forEach(LazyResettable<*, *>::reset)
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/NetworkUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/NetworkUtils.kt
index 2271c16..32cf084 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/NetworkUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/NetworkUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.annotation.SuppressLint
@@ -7,6 +22,7 @@ import android.net.ConnectivityManager
/**
* Created by Allan Wang on 2017-07-07.
*/
+@Deprecated("Applications should make use of network callbacks instead of individual queries")
inline val Context.isNetworkAvailable: Boolean
@SuppressLint("MissingPermission")
get() {
@@ -15,6 +31,7 @@ inline val Context.isNetworkAvailable: Boolean
return activeNetworkInfo?.isConnectedOrConnecting ?: false
}
+@Deprecated("Applications should make use of network callbacks instead of individual queries")
inline val Context.isWifiConnected: Boolean
@SuppressLint("MissingPermission")
get() {
@@ -23,10 +40,11 @@ inline val Context.isWifiConnected: Boolean
return (activeNetworkInfo?.type ?: -1) == ConnectivityManager.TYPE_WIFI
}
+@Deprecated("Applications should make use of network callbacks instead of individual queries")
inline val Context.isMobileDataConnected: Boolean
@SuppressLint("MissingPermission")
get() {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
return (activeNetworkInfo?.type ?: -1) == ConnectivityManager.TYPE_MOBILE
- } \ No newline at end of file
+ }
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/NotificationUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/NotificationUtils.kt
index 1eb0076..126b133 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/NotificationUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/NotificationUtils.kt
@@ -1,10 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.Context
-import android.support.v4.app.NotificationManagerCompat
-
+import androidx.core.app.NotificationManagerCompat
/**
* Created by Allan Wang on 2017-08-04.
*/
-fun Context.cancelNotification(notifId: Int) = NotificationManagerCompat.from(this).cancel(notifId) \ No newline at end of file
+fun Context.cancelNotification(notifId: Int) = NotificationManagerCompat.from(this).cancel(notifId)
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt
index 77750d3..4055847 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/PackageUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.ActivityNotFoundException
@@ -70,4 +85,4 @@ inline val Context.isFromGooglePlay: Boolean
get() {
val installer = installerPackageName
return arrayOf(INSTALLER_GOOGLE_PLAY_FEEDBACK, INSTALLER_GOOGLE_PLAY_VENDING).any { it == installer }
- } \ No newline at end of file
+ }
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/RecyclerUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/RecyclerUtils.kt
index 3a34db5..11494b3 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/RecyclerUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/RecyclerUtils.kt
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.graphics.Rect
-import android.support.v7.widget.RecyclerView
import android.view.View
+import androidx.recyclerview.widget.RecyclerView
/**
* Created by Allan Wang on 2017-07-11.
@@ -22,4 +37,4 @@ class MarginItemDecoration(sizeDp: Int, val edgeFlags: Int) : RecyclerView.ItemD
if (edgeFlags and KAU_RIGHT > 0) outRect.right += sizePx
if (edgeFlags and KAU_BOTTOM > 0) outRect.bottom += sizePx
}
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt
index ec206ee..523a586 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/TransitionUtils.kt
@@ -1,14 +1,29 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.os.Build
-import android.support.annotation.RequiresApi
-import android.support.annotation.TransitionRes
-import android.support.transition.AutoTransition
-import android.support.transition.TransitionInflater
-import android.support.transition.TransitionManager
import android.transition.Transition
import android.view.ViewGroup
-import android.support.transition.Transition as SupportTransition
+import androidx.annotation.RequiresApi
+import androidx.annotation.TransitionRes
+import androidx.transition.AutoTransition
+import androidx.transition.TransitionInflater
+import androidx.transition.TransitionManager
+import androidx.transition.Transition as SupportTransition
/**
* Created by Allan Wang on 2017-06-24.
@@ -29,7 +44,8 @@ fun Transition.addEndListener(onEnd: (transition: Transition) -> Unit) {
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
-class SupportTransitionEndListener(val onEnd: (transition: SupportTransition) -> Unit) : SupportTransition.TransitionListener {
+class SupportTransitionEndListener(val onEnd: (transition: SupportTransition) -> Unit) :
+ SupportTransition.TransitionListener {
override fun onTransitionEnd(transition: SupportTransition) = onEnd(transition)
override fun onTransitionResume(transition: SupportTransition) {}
override fun onTransitionPause(transition: SupportTransition) {}
@@ -52,9 +68,9 @@ fun ViewGroup.transitionAuto(builder: AutoTransition.() -> Unit = {}) {
}
@KauUtils
-fun ViewGroup.transitionDelayed(@TransitionRes id: Int, builder: android.support.transition.Transition.() -> Unit = {}) {
+fun ViewGroup.transitionDelayed(@TransitionRes id: Int, builder: androidx.transition.Transition.() -> Unit = {}) {
if (!buildIsLollipopAndUp) return
val transition = TransitionInflater.from(context).inflateTransition(id)
transition.builder()
TransitionManager.beginDelayedTransition(this, transition)
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt
index 46e29b2..48a2028 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/Utils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.content.Context
@@ -8,12 +23,11 @@ import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Handler
import android.os.Looper
-import android.support.annotation.IntRange
+import androidx.annotation.IntRange
import ca.allanwang.kau.R
import java.math.RoundingMode
import java.text.DecimalFormat
-
/**
* Created by Allan Wang on 2017-05-28.
*/
@@ -127,10 +141,10 @@ fun postDelayed(delay: Long, action: () -> Unit) {
}
inline val kauIsMainThread: Boolean
- get() = Looper.myLooper() == Looper.getMainLooper()
+ get() = Looper.myLooper() == ContextHelper.looper
class KauException(message: String) : RuntimeException(message)
fun String.withMaxLength(n: Int): String =
- if (length <= n) this
- else substring(0, n - 1) + KAU_ELLIPSIS \ No newline at end of file
+ if (length <= n) this
+ else substring(0, n - 1) + KAU_ELLIPSIS
diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt
index 4e020bc..186d125 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ViewUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
@file:Suppress("NOTHING_TO_INLINE")
package ca.allanwang.kau.utils
@@ -7,15 +22,6 @@ import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.os.Build
-import android.support.annotation.ColorInt
-import android.support.annotation.ColorRes
-import android.support.annotation.RequiresApi
-import android.support.annotation.StringRes
-import android.support.design.widget.FloatingActionButton
-import android.support.design.widget.Snackbar
-import android.support.design.widget.TextInputEditText
-import android.support.v7.widget.LinearLayoutManager
-import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
@@ -23,11 +29,19 @@ import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.ImageView
+import androidx.annotation.ColorInt
+import androidx.annotation.ColorRes
+import androidx.annotation.RequiresApi
+import androidx.annotation.StringRes
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.ui.createSimpleRippleDrawable
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import com.google.android.material.snackbar.Snackbar
+import com.google.android.material.textfield.TextInputEditText
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.IIcon
-
/**
* Created by Allan Wang on 2017-05-31.
*/
@@ -81,10 +95,16 @@ fun View.snackbar(text: String, duration: Int = Snackbar.LENGTH_LONG, builder: S
return snackbar
}
-fun View.snackbar(@StringRes textId: Int, duration: Int = Snackbar.LENGTH_LONG, builder: Snackbar.() -> Unit = {}) = snackbar(context.string(textId), duration, builder)
+fun View.snackbar(@StringRes textId: Int, duration: Int = Snackbar.LENGTH_LONG, builder: Snackbar.() -> Unit = {}) =
+ snackbar(context.string(textId), duration, builder)
@KauUtils
-fun ImageView.setIcon(icon: IIcon?, sizeDp: Int = 24, @ColorInt color: Int = Color.WHITE, builder: IconicsDrawable.() -> Unit = {}) {
+fun ImageView.setIcon(
+ icon: IIcon?,
+ sizeDp: Int = 24,
+ @ColorInt color: Int = Color.WHITE,
+ builder: IconicsDrawable.() -> Unit = {}
+) {
if (icon == null) return
setImageDrawable(icon.toDrawable(context, sizeDp = sizeDp, color = color, builder = builder))
}
@@ -98,7 +118,8 @@ fun FloatingActionButton.showIf(show: Boolean) = if (show) show() else hide()
fun FloatingActionButton.hideIf(hide: Boolean) = if (hide) hide() else show()
@KauUtils
-fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View = LayoutInflater.from(context).inflate(layoutId, this, attachToRoot)
+fun ViewGroup.inflate(layoutId: Int, attachToRoot: Boolean = false): View =
+ LayoutInflater.from(context).inflate(layoutId, this, attachToRoot)
/**
* Set left margin to a value in px
@@ -150,10 +171,10 @@ fun View.setMargin(margin: Int) = setMargins(margin, KAU_ALL)
private fun View.setMargins(margin: Int, flag: Int): Boolean {
val p = (layoutParams as? ViewGroup.MarginLayoutParams) ?: return false
p.setMargins(
- if (flag and KAU_LEFT > 0) margin else p.leftMargin,
- if (flag and KAU_TOP > 0) margin else p.topMargin,
- if (flag and KAU_RIGHT > 0) margin else p.rightMargin,
- if (flag and KAU_BOTTOM > 0) margin else p.bottomMargin
+ if (flag and KAU_LEFT > 0) margin else p.leftMargin,
+ if (flag and KAU_TOP > 0) margin else p.topMargin,
+ if (flag and KAU_RIGHT > 0) margin else p.rightMargin,
+ if (flag and KAU_BOTTOM > 0) margin else p.bottomMargin
)
return true
}
@@ -206,26 +227,31 @@ fun View.setPadding(padding: Int) = setPadding(padding, KAU_ALL)
@KauUtils
private fun View.setPadding(padding: Int, flag: Int) {
setPadding(
- if (flag and KAU_LEFT > 0) padding else paddingLeft,
- if (flag and KAU_TOP > 0) padding else paddingTop,
- if (flag and KAU_RIGHT > 0) padding else paddingRight,
- if (flag and KAU_BOTTOM > 0) padding else paddingBottom
+ if (flag and KAU_LEFT > 0) padding else paddingLeft,
+ if (flag and KAU_TOP > 0) padding else paddingTop,
+ if (flag and KAU_RIGHT > 0) padding else paddingRight,
+ if (flag and KAU_BOTTOM > 0) padding else paddingBottom
)
}
@KauUtils
fun View.hideKeyboard() {
clearFocus()
- (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(windowToken, 0)
+ (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(
+ windowToken,
+ 0
+ )
}
@KauUtils
fun View.showKeyboard() {
requestFocus()
- (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
+ (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(
+ this,
+ InputMethodManager.SHOW_IMPLICIT
+ )
}
-
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@KauUtils
fun View.setRippleBackground(@ColorInt foregroundColor: Int, @ColorInt backgroundColor: Int) {
@@ -243,12 +269,14 @@ inline val TextInputEditText.value: String get() = text.toString().trim()
/**
* Generates a recycler view with match parent and a linearlayoutmanager, since it's so commonly used
*/
-fun Context.fullLinearRecycler(rvAdapter: RecyclerView.Adapter<*>? = null, configs: RecyclerView.() -> Unit = {}) = RecyclerView(this).apply {
- layoutManager = LinearLayoutManager(this@fullLinearRecycler)
- layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT)
- if (rvAdapter != null) adapter = rvAdapter
- configs()
-}
+fun Context.fullLinearRecycler(rvAdapter: RecyclerView.Adapter<*>? = null, configs: RecyclerView.() -> Unit = {}) =
+ RecyclerView(this).apply {
+ layoutManager = LinearLayoutManager(this@fullLinearRecycler)
+ layoutParams =
+ RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT)
+ if (rvAdapter != null) adapter = rvAdapter
+ configs()
+ }
/**
* Sets a linear layout manager along with an adapter
@@ -263,7 +291,11 @@ fun RecyclerView.withLinearAdapter(rvAdapter: RecyclerView.Adapter<*>) = apply {
* If it is not shown, the action will be invoked directly and no further actions will be made
* If it is already shown, scaling and alpha animations will be added to the action
*/
-inline fun <T : ImageView> T.fadeScaleTransition(duration: Long = 500L, minScale: Float = 0.7f, crossinline action: T.() -> Unit) {
+inline fun <T : ImageView> T.fadeScaleTransition(
+ duration: Long = 500L,
+ minScale: Float = 0.7f,
+ crossinline action: T.() -> Unit
+) {
if (!isVisible) action()
else {
var transitioned = false
@@ -291,7 +323,7 @@ fun FloatingActionButton.hideOnDownwardsScroll(recycler: RecyclerView) {
recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
- if (newState == android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE && !isShown) show()
+ if (newState == RecyclerView.SCROLL_STATE_IDLE && !isShown) show()
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
@@ -324,4 +356,4 @@ inline fun View.setOnSingleTapListener(crossinline onSingleTap: (v: View, event:
else -> false
}
}
-} \ No newline at end of file
+}
diff --git a/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt b/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt
index 28d51a4..2e66a97 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/xml/Changelog.kt
@@ -1,39 +1,54 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.xml
import android.content.Context
import android.content.res.XmlResourceParser
-import android.support.annotation.ColorInt
-import android.support.annotation.LayoutRes
-import android.support.annotation.XmlRes
-import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
+import androidx.annotation.ColorInt
+import androidx.annotation.LayoutRes
+import androidx.annotation.XmlRes
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.R
+import ca.allanwang.kau.utils.ctxCoroutine
import ca.allanwang.kau.utils.materialDialog
import ca.allanwang.kau.utils.use
import com.afollestad.materialdialogs.MaterialDialog
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import com.afollestad.materialdialogs.list.customListAdapter
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.xmlpull.v1.XmlPullParser
-
/**
* Created by Allan Wang on 2017-05-28.
*
* Easy changelog loader
*/
-fun Context.showChangelog(@XmlRes xmlRes: Int, @ColorInt textColor: Int? = null, customize: MaterialDialog.Builder.() -> Unit = {}) {
- doAsync {
- val items = parse(this@showChangelog, xmlRes)
- uiThread {
- materialDialog {
- title(R.string.kau_changelog)
- positiveText(R.string.kau_great)
- adapter(ChangelogAdapter(items, textColor), null)
- customize()
- }
+fun Context.showChangelog(@XmlRes xmlRes: Int, @ColorInt textColor: Int? = null, customize: MaterialDialog.() -> Unit = {}) {
+ ctxCoroutine.launch {
+ val items = withContext(Dispatchers.Default) { parse(this@showChangelog, xmlRes) }
+ materialDialog {
+ title(R.string.kau_changelog)
+ positiveButton(R.string.kau_great)
+ customListAdapter(ChangelogAdapter(items, textColor), null)
+ customize()
}
}
}
@@ -42,10 +57,13 @@ fun Context.showChangelog(@XmlRes xmlRes: Int, @ColorInt textColor: Int? = null,
* Internals of the changelog dialog
* Contains an mainAdapter for each item, as well as the tags to parse
*/
-internal class ChangelogAdapter(val items: List<Pair<String, ChangelogType>>, @ColorInt val textColor: Int? = null) : RecyclerView.Adapter<ChangelogAdapter.ChangelogVH>() {
+internal class ChangelogAdapter(val items: List<Pair<String, ChangelogType>>, @ColorInt val textColor: Int? = null) :
+ RecyclerView.Adapter<ChangelogAdapter.ChangelogVH>() {
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ChangelogVH(LayoutInflater.from(parent.context)
- .inflate(items[viewType].second.layout, parent, false))
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ChangelogVH(
+ LayoutInflater.from(parent.context)
+ .inflate(items[viewType].second.layout, parent, false)
+ )
override fun onBindViewHolder(holder: ChangelogVH, position: Int) {
holder.text.text = items[position].first
@@ -98,4 +116,3 @@ internal enum class ChangelogType(val tag: String, val attr: String, @LayoutRes
return true
}
}
-
diff --git a/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt b/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt
index 7caf5d6..73d7d6c 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/xml/FAQ.kt
@@ -1,13 +1,26 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.xml
import android.content.Context
import android.content.res.XmlResourceParser
-import android.support.annotation.XmlRes
import android.text.Html
import android.text.Spanned
+import androidx.annotation.XmlRes
import ca.allanwang.kau.utils.use
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
import org.xmlpull.v1.XmlPullParser
/**
@@ -15,51 +28,53 @@ import org.xmlpull.v1.XmlPullParser
*/
/**
- * Parse an xml asynchronously with two tags, <question>Text</question> and <answer>Text</answer>,
- * and invoke the [callback] on the ui thread
+ * Parse an xml asynchronously with two tags, <question>Text</question> and <answer>Text</answer>.
+ * Note that this should executed in a background thread.
*/
@Suppress("DEPRECATION")
fun Context.kauParseFaq(
- @XmlRes xmlRes: Int,
- /**
- * If \n is used, it will automatically be converted to </br>
- */
- parseNewLine: Boolean = true,
- callback: (items: List<FaqItem>) -> Unit) {
- doAsync {
- val items = mutableListOf<FaqItem>()
- resources.getXml(xmlRes).use { parser: XmlResourceParser ->
- var eventType = parser.eventType
- var question: Spanned? = null
- var flag = -1 //-1, 0, 1 -> invalid, question, answer
- while (eventType != XmlPullParser.END_DOCUMENT) {
- if (eventType == XmlPullParser.START_TAG) {
- flag = when (parser.name) {
- "question" -> 0
- "answer" -> 1
- else -> -1
+ @XmlRes xmlRes: Int,
+ /**
+ * If \n is used, it will automatically be converted to </br>
+ */
+ parseNewLine: Boolean = true
+): List<FaqItem> {
+ val items = mutableListOf<FaqItem>()
+ resources.getXml(xmlRes).use { parser: XmlResourceParser ->
+ var eventType = parser.eventType
+ var question: Spanned? = null
+ var flag = -1 //-1, 0, 1 -> invalid, question, answer
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ flag = when (parser.name) {
+ "question" -> 0
+ "answer" -> 1
+ else -> -1
+ }
+ } else if (eventType == XmlPullParser.TEXT) {
+ when (flag) {
+ 0 -> {
+ question = Html.fromHtml(parser.text.replace("\n", if (parseNewLine) "<br/>" else ""))
+ flag = -1
}
- } else if (eventType == XmlPullParser.TEXT) {
- when (flag) {
- 0 -> {
- question = Html.fromHtml(parser.text.replace("\n", if (parseNewLine) "<br/>" else ""))
- flag = -1
- }
- 1 -> {
- items.add(FaqItem(items.size + 1,
- question
- ?: throw IllegalArgumentException("KAU FAQ answer found without a question"),
- Html.fromHtml(parser.text.replace("\n", if (parseNewLine) "<br/>" else ""))))
- question = null
- flag = -1
- }
+ 1 -> {
+ items.add(
+ FaqItem(
+ items.size + 1,
+ question
+ ?: throw IllegalArgumentException("KAU FAQ answer found without a question"),
+ Html.fromHtml(parser.text.replace("\n", if (parseNewLine) "<br/>" else ""))
+ )
+ )
+ question = null
+ flag = -1
}
}
- eventType = parser.next()
}
+ eventType = parser.next()
}
- uiThread { callback(items) }
}
+ return items
}
-data class FaqItem(val number: Int, val question: Spanned, val answer: Spanned) \ No newline at end of file
+data class FaqItem(val number: Int, val question: Spanned, val answer: Spanned)
diff --git a/core/src/main/res-public/values-da-rDK/strings_commons.xml b/core/src/main/res-public/values-da-rDK/strings_commons.xml
index 5be1277..745418a 100644
--- a/core/src/main/res-public/values-da-rDK/strings_commons.xml
+++ b/core/src/main/res-public/values-da-rDK/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-de-rDE/strings_commons.xml b/core/src/main/res-public/values-de-rDE/strings_commons.xml
index 015b612..e67292c 100644
--- a/core/src/main/res-public/values-de-rDE/strings_commons.xml
+++ b/core/src/main/res-public/values-de-rDE/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-es-rES/strings_commons.xml b/core/src/main/res-public/values-es-rES/strings_commons.xml
index 7cab287..34e4aa7 100644
--- a/core/src/main/res-public/values-es-rES/strings_commons.xml
+++ b/core/src/main/res-public/values-es-rES/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-fr-rFR/strings_commons.xml b/core/src/main/res-public/values-fr-rFR/strings_commons.xml
index 2d681ff..89a9a99 100644
--- a/core/src/main/res-public/values-fr-rFR/strings_commons.xml
+++ b/core/src/main/res-public/values-fr-rFR/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-gl-rES/strings_commons.xml b/core/src/main/res-public/values-gl-rES/strings_commons.xml
index b9a5564..8b4d1b4 100644
--- a/core/src/main/res-public/values-gl-rES/strings_commons.xml
+++ b/core/src/main/res-public/values-gl-rES/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-hu-rHU/strings_commons.xml b/core/src/main/res-public/values-hu-rHU/strings_commons.xml
index 5488f1d..bae6c1e 100644
--- a/core/src/main/res-public/values-hu-rHU/strings_commons.xml
+++ b/core/src/main/res-public/values-hu-rHU/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-in-rID/strings_commons.xml b/core/src/main/res-public/values-in-rID/strings_commons.xml
index b734377..5532b67 100644
--- a/core/src/main/res-public/values-in-rID/strings_commons.xml
+++ b/core/src/main/res-public/values-in-rID/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-it-rIT/strings_commons.xml b/core/src/main/res-public/values-it-rIT/strings_commons.xml
index 821191e..c2d513a 100644
--- a/core/src/main/res-public/values-it-rIT/strings_commons.xml
+++ b/core/src/main/res-public/values-it-rIT/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-ko-rKR/strings_commons.xml b/core/src/main/res-public/values-ko-rKR/strings_commons.xml
index 112e8d5..48153cb 100644
--- a/core/src/main/res-public/values-ko-rKR/strings_commons.xml
+++ b/core/src/main/res-public/values-ko-rKR/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-nl-rNL/strings_commons.xml b/core/src/main/res-public/values-nl-rNL/strings_commons.xml
new file mode 100644
index 0000000..a3967ff
--- /dev/null
+++ b/core/src/main/res-public/values-nl-rNL/strings_commons.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
+A collection of common string values
+Most resources are verbatim and x represents a formatted item
+-->
+<resources>
+ <string name="kau_about_app">Over de app</string>
+ <string name="kau_about_x">Over %s</string>
+ <string name="kau_add_account">Account toevoegen</string>
+ <string name="kau_back">Terug</string>
+ <string name="kau_cancel">Annuleren</string>
+ <string name="kau_changelog">Veranderingen</string>
+ <string name="kau_close">Sluiten</string>
+ <string name="kau_contact_us">Contact opnemen</string>
+ <string name="kau_copy">Kopiëren</string>
+ <string name="kau_custom">Aangepast</string>
+ <string name="kau_dark">Donker</string>
+ <string name="kau_default">Standaard</string>
+ <string name="kau_do_not_show_again">Niet opnieuw tonen</string>
+ <string name="kau_done">Gereed</string>
+ <string name="kau_error">Fout</string>
+ <string name="kau_exit">Afsluiten</string>
+ <string name="kau_exit_confirmation">Afsluiten?</string>
+ <string name="kau_exit_confirmation_x">%s afsluiten?</string>
+ <string name="kau_glass">Glas</string>
+ <string name="kau_got_it">Begrepen</string>
+ <string name="kau_great">Geweldig</string>
+ <string name="kau_hide">Verbergen</string>
+ <string name="kau_light">Licht</string>
+ <string name="kau_login">Aanmelden</string>
+ <string name="kau_logout">Afmelden</string>
+ <string name="kau_logout_confirm_as_x">%s uitloggen?</string>
+ <string name="kau_manage_account">Account beheren</string>
+ <string name="kau_maybe">Misschien</string>
+ <string name="kau_menu">Menu</string>
+ <string name="kau_no">Nee</string>
+ <string name="kau_no_results_found">Geen resultaten</string>
+ <string name="kau_none">Geen</string>
+ <string name="kau_ok">OK</string>
+ <string name="kau_play_store">Play Store</string>
+ <string name="kau_rate">Beoordelen</string>
+ <string name="kau_report_bug">Een fout melden</string>
+ <string name="kau_search">Zoeken</string>
+ <string name="kau_send_feedback">Feedback geven</string>
+ <string name="kau_send_via">Verzenden via</string>
+ <string name="kau_settings">Instellingen</string>
+ <string name="kau_share">Delen</string>
+ <string name="kau_text_copied">Tekst naar klembord gekopieerd.</string>
+ <string name="kau_thank_you">Bedankt</string>
+ <string name="kau_uh_oh">Oeps</string>
+ <string name="kau_warning">Waarschuwing</string>
+ <plurals name="kau_x_days">
+ <item quantity="one">%d dag</item>
+ <item quantity="other">%d dagen</item>
+ </plurals>
+ <plurals name="kau_x_hours">
+ <item quantity="one">%d uur</item>
+ <item quantity="other">%d uren</item>
+ </plurals>
+ <plurals name="kau_x_minutes">
+ <item quantity="one">%d minuut</item>
+ <item quantity="other">%d minuten</item>
+ </plurals>
+ <plurals name="kau_x_seconds">
+ <item quantity="one">%d seconde</item>
+ <item quantity="other">%d seconden</item>
+ </plurals>
+ <string name="kau_yes">Ja</string>
+ <string name="kau_permission_denied">Toestemming geweigerd</string>
+</resources>
diff --git a/core/src/main/res-public/values-no-rNO/strings_commons.xml b/core/src/main/res-public/values-no-rNO/strings_commons.xml
index c18b439..e27f20d 100644
--- a/core/src/main/res-public/values-no-rNO/strings_commons.xml
+++ b/core/src/main/res-public/values-no-rNO/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-pl-rPL/strings_commons.xml b/core/src/main/res-public/values-pl-rPL/strings_commons.xml
index 248e409..323a0ff 100644
--- a/core/src/main/res-public/values-pl-rPL/strings_commons.xml
+++ b/core/src/main/res-public/values-pl-rPL/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-pt-rBR/strings_commons.xml b/core/src/main/res-public/values-pt-rBR/strings_commons.xml
index 716e373..4eaea6c 100644
--- a/core/src/main/res-public/values-pt-rBR/strings_commons.xml
+++ b/core/src/main/res-public/values-pt-rBR/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-pt-rPT/strings_commons.xml b/core/src/main/res-public/values-pt-rPT/strings_commons.xml
new file mode 100644
index 0000000..863b8b7
--- /dev/null
+++ b/core/src/main/res-public/values-pt-rPT/strings_commons.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
+A collection of common string values
+Most resources are verbatim and x represents a formatted item
+-->
+<resources>
+ <string name="kau_about_app">Acerca</string>
+ <string name="kau_about_x">Acerca de %s</string>
+ <string name="kau_add_account">Adicionar conta</string>
+ <string name="kau_back">Voltar</string>
+ <string name="kau_cancel">Cancelar</string>
+ <string name="kau_changelog">Registo de alterações</string>
+ <string name="kau_close">Fechar</string>
+ <string name="kau_contact_us">Contacte-nos</string>
+ <string name="kau_copy">Copiar</string>
+ <string name="kau_custom">Personalizada</string>
+ <string name="kau_dark">Escuro</string>
+ <string name="kau_default">Padrão</string>
+ <string name="kau_do_not_show_again">Não mostrar novamente</string>
+ <string name="kau_done">Feito</string>
+ <string name="kau_error">Erro</string>
+ <string name="kau_exit">Sair</string>
+ <string name="kau_exit_confirmation">Tem a certeza de que deseja sair?</string>
+ <string name="kau_exit_confirmation_x">Tem a certeza de que deseja sair de %s?</string>
+ <string name="kau_glass">Vidro</string>
+ <string name="kau_got_it">Percebi</string>
+ <string name="kau_great">Excelente</string>
+ <string name="kau_hide">Ocultar</string>
+ <string name="kau_light">Claro</string>
+ <string name="kau_login">Iniciar sessão</string>
+ <string name="kau_logout">Sair</string>
+ <string name="kau_logout_confirm_as_x">Tem a certeza de que deseja sair como %s?</string>
+ <string name="kau_manage_account">Gerir conta</string>
+ <string name="kau_maybe">Talvez</string>
+ <string name="kau_menu">Menu</string>
+ <string name="kau_no">Não</string>
+ <string name="kau_no_results_found">Não existem resultados</string>
+ <string name="kau_none">Nenhum</string>
+ <string name="kau_ok">OK</string>
+ <string name="kau_play_store">Play Store</string>
+ <string name="kau_rate">Avaliar</string>
+ <string name="kau_report_bug">Comunicar um erro</string>
+ <string name="kau_search">Procurar</string>
+ <string name="kau_send_feedback">Enviar comentários</string>
+ <string name="kau_send_via">Enviar via</string>
+ <string name="kau_settings">Definições</string>
+ <string name="kau_share">Partilhar</string>
+ <string name="kau_text_copied">Texto copiado para a área de transferência.</string>
+ <string name="kau_thank_you">Obrigado</string>
+ <string name="kau_uh_oh">Bolas</string>
+ <string name="kau_warning">Aviso</string>
+ <plurals name="kau_x_days">
+ <item quantity="one">%d dia</item>
+ <item quantity="other">%d dias</item>
+ </plurals>
+ <plurals name="kau_x_hours">
+ <item quantity="one">%d hora</item>
+ <item quantity="other">%d horas</item>
+ </plurals>
+ <plurals name="kau_x_minutes">
+ <item quantity="one">%d minuto</item>
+ <item quantity="other">%d minutos</item>
+ </plurals>
+ <plurals name="kau_x_seconds">
+ <item quantity="one">%d segundo</item>
+ <item quantity="other">%d segundos</item>
+ </plurals>
+ <string name="kau_yes">Sim</string>
+ <string name="kau_permission_denied">Permissão negada</string>
+</resources>
diff --git a/core/src/main/res-public/values-sr-rSP/strings_commons.xml b/core/src/main/res-public/values-sr-rSP/strings_commons.xml
new file mode 100644
index 0000000..213d876
--- /dev/null
+++ b/core/src/main/res-public/values-sr-rSP/strings_commons.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
+A collection of common string values
+Most resources are verbatim and x represents a formatted item
+-->
+<resources>
+ <string name="kau_about_app">О апликацији</string>
+ <string name="kau_about_x">О %s</string>
+ <string name="kau_add_account">Додајте налог</string>
+ <string name="kau_back">Назад</string>
+ <string name="kau_cancel">Откажи</string>
+ <string name="kau_changelog">Евиденција измена</string>
+ <string name="kau_close">Затвори</string>
+ <string name="kau_contact_us">Контактирајте нас</string>
+ <string name="kau_copy">Копирај</string>
+ <string name="kau_custom">Прилагођено</string>
+ <string name="kau_dark">Тамно</string>
+ <string name="kau_default">Подразумевано</string>
+ <string name="kau_do_not_show_again">Не приказуј поново</string>
+ <string name="kau_done">Готово</string>
+ <string name="kau_error">Грешка</string>
+ <string name="kau_exit">Изађи</string>
+ <string name="kau_exit_confirmation">Да ли сте сигурни да желите да изађете?</string>
+ <string name="kau_exit_confirmation_x">Да ли сте сигурно желите да напустите %s?</string>
+ <string name="kau_glass">Стакло</string>
+ <string name="kau_got_it">Разумем</string>
+ <string name="kau_great">Одлично</string>
+ <string name="kau_hide">Сакриј</string>
+ <string name="kau_light">Светло</string>
+ <string name="kau_login">Пријава</string>
+ <string name="kau_logout">Одјави се</string>
+ <string name="kau_logout_confirm_as_x">Заиста желите да се одјавите са %s?</string>
+ <string name="kau_manage_account">Управљај налозима</string>
+ <string name="kau_maybe">Можда</string>
+ <string name="kau_menu">Мени</string>
+ <string name="kau_no">Не</string>
+ <string name="kau_no_results_found">Нема резултата</string>
+ <string name="kau_none">Ниједно</string>
+ <string name="kau_ok">ОК</string>
+ <string name="kau_play_store">Плеј продавница</string>
+ <string name="kau_rate">Оцени</string>
+ <string name="kau_report_bug">Пријави грешку</string>
+ <string name="kau_search">Претражи</string>
+ <string name="kau_send_feedback">Пошаљите повратне информације</string>
+ <string name="kau_send_via">Пошаљи преко</string>
+ <string name="kau_settings">Подешавања</string>
+ <string name="kau_share">Подели</string>
+ <string name="kau_text_copied">Текст је копиран у привремену меморију.</string>
+ <string name="kau_thank_you">Хвала</string>
+ <string name="kau_uh_oh">Јао не</string>
+ <string name="kau_warning">Упозорење</string>
+ <plurals name="kau_x_days">
+ <item quantity="one">%d дан</item>
+ <item quantity="few">%d дана</item>
+ <item quantity="other">%d дана</item>
+ </plurals>
+ <plurals name="kau_x_hours">
+ <item quantity="one">%d сат</item>
+ <item quantity="few">%d сати</item>
+ <item quantity="other">%d сати</item>
+ </plurals>
+ <plurals name="kau_x_minutes">
+ <item quantity="one">%d минут</item>
+ <item quantity="few">%d минута</item>
+ <item quantity="other">%d минута</item>
+ </plurals>
+ <plurals name="kau_x_seconds">
+ <item quantity="one">%d секунду</item>
+ <item quantity="few">%d сек</item>
+ <item quantity="other">%d секунди</item>
+ </plurals>
+ <string name="kau_yes">Да</string>
+ <string name="kau_permission_denied">Немате овлашћења</string>
+</resources>
diff --git a/core/src/main/res-public/values-sv-rSE/strings_commons.xml b/core/src/main/res-public/values-sv-rSE/strings_commons.xml
index 6cc2bb3..8d4362b 100644
--- a/core/src/main/res-public/values-sv-rSE/strings_commons.xml
+++ b/core/src/main/res-public/values-sv-rSE/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-th-rTH/strings_commons.xml b/core/src/main/res-public/values-th-rTH/strings_commons.xml
index 2f4bdec..e47273d 100644
--- a/core/src/main/res-public/values-th-rTH/strings_commons.xml
+++ b/core/src/main/res-public/values-th-rTH/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-tr-rTR/strings_commons.xml b/core/src/main/res-public/values-tr-rTR/strings_commons.xml
index 1e8395e..b36ca43 100644
--- a/core/src/main/res-public/values-tr-rTR/strings_commons.xml
+++ b/core/src/main/res-public/values-tr-rTR/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-uk-rUA/strings_commons.xml b/core/src/main/res-public/values-uk-rUA/strings_commons.xml
index 60ca520..0f62c6a 100644
--- a/core/src/main/res-public/values-uk-rUA/strings_commons.xml
+++ b/core/src/main/res-public/values-uk-rUA/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
@@ -48,6 +50,30 @@ Most resources are verbatim and x represents a formatted item
<string name="kau_thank_you">Дякуємо Вам</string>
<string name="kau_uh_oh">Ой-ой</string>
<string name="kau_warning">Увага</string>
+ <plurals name="kau_x_days">
+ <item quantity="one">%d день</item>
+ <item quantity="few">%d днів</item>
+ <item quantity="many">%d днів</item>
+ <item quantity="other">%d днів</item>
+ </plurals>
+ <plurals name="kau_x_hours">
+ <item quantity="one">%d годину</item>
+ <item quantity="few">%d годин</item>
+ <item quantity="many">%d годин</item>
+ <item quantity="other">%d годин</item>
+ </plurals>
+ <plurals name="kau_x_minutes">
+ <item quantity="one">%d хвилини</item>
+ <item quantity="few">%d хвилин</item>
+ <item quantity="many">%d хвилин</item>
+ <item quantity="other">%d хвилин</item>
+ </plurals>
+ <plurals name="kau_x_seconds">
+ <item quantity="one">%d секунди</item>
+ <item quantity="few">%d секунд</item>
+ <item quantity="many">%d секунд</item>
+ <item quantity="other">%d секунд</item>
+ </plurals>
<string name="kau_yes">Так</string>
<string name="kau_permission_denied">У доступі відмовлено</string>
</resources>
diff --git a/core/src/main/res-public/values-vi-rVN/strings_commons.xml b/core/src/main/res-public/values-vi-rVN/strings_commons.xml
index 767e628..a444dc2 100644
--- a/core/src/main/res-public/values-vi-rVN/strings_commons.xml
+++ b/core/src/main/res-public/values-vi-rVN/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-zh-rCN/strings_commons.xml b/core/src/main/res-public/values-zh-rCN/strings_commons.xml
index 47ddbda..66a7423 100644
--- a/core/src/main/res-public/values-zh-rCN/strings_commons.xml
+++ b/core/src/main/res-public/values-zh-rCN/strings_commons.xml
@@ -1,4 +1,6 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?><!--Generated by crowdin.com--><!--
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
A collection of common string values
Most resources are verbatim and x represents a formatted item
-->
diff --git a/core/src/main/res-public/values-zh-rTW/strings_commons.xml b/core/src/main/res-public/values-zh-rTW/strings_commons.xml
new file mode 100644
index 0000000..bf9f59b
--- /dev/null
+++ b/core/src/main/res-public/values-zh-rTW/strings_commons.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--Generated by crowdin.com-->
+<!--
+A collection of common string values
+Most resources are verbatim and x represents a formatted item
+-->
+<resources>
+ <string name="kau_about_app">關於此程式</string>
+ <string name="kau_about_x">關於 %s</string>
+ <string name="kau_add_account">新增帳號</string>
+ <string name="kau_back">回上頁</string>
+ <string name="kau_cancel">取消</string>
+ <string name="kau_changelog">更新資訊</string>
+ <string name="kau_close">關閉</string>
+ <string name="kau_contact_us">與我們聯繫</string>
+ <string name="kau_copy">複製</string>
+ <string name="kau_custom">自訂</string>
+ <string name="kau_dark">黑色主題</string>
+ <string name="kau_default">默認</string>
+ <string name="kau_do_not_show_again">不要再顯示</string>
+ <string name="kau_done">完成</string>
+ <string name="kau_error">錯誤</string>
+ <string name="kau_exit">結束</string>
+ <string name="kau_exit_confirmation">您確定要離開嗎?</string>
+ <string name="kau_exit_confirmation_x">您確定要離開%s嗎?</string>
+ <string name="kau_glass">玻璃</string>
+ <string name="kau_got_it">知道了</string>
+ <string name="kau_great">讚</string>
+ <string name="kau_hide">隱藏</string>
+ <string name="kau_light">亮色調</string>
+ <string name="kau_login">登入</string>
+ <string name="kau_logout">登出</string>
+ <string name="kau_logout_confirm_as_x">您確定要登出%s嗎?</string>
+ <string name="kau_manage_account">帳戶管理</string>
+ <string name="kau_maybe">可能</string>
+ <string name="kau_menu">選單</string>
+ <string name="kau_no">不</string>
+ <string name="kau_no_results_found">找不到相符的結果</string>
+ <string name="kau_none">無</string>
+ <string name="kau_ok">確定</string>
+ <string name="kau_play_store">Play商店</string>
+ <string name="kau_rate">評分</string>
+ <string name="kau_report_bug">回報程式錯誤</string>
+ <string name="kau_search">搜尋</string>
+ <string name="kau_send_feedback">回饋意見</string>
+ <string name="kau_send_via">來發送</string>
+ <string name="kau_settings">設定</string>
+ <string name="kau_share">分享</string>
+ <string name="kau_text_copied">文字已複製到剪貼簿</string>
+ <string name="kau_thank_you">感謝</string>
+ <string name="kau_uh_oh">噢!</string>
+ <string name="kau_warning">警告</string>
+ <plurals name="kau_x_days">
+ <item quantity="other">%d 天</item>
+ </plurals>
+ <plurals name="kau_x_hours">
+ <item quantity="other">%d 小時</item>
+ </plurals>
+ <plurals name="kau_x_minutes">
+ <item quantity="other">%d 分鐘</item>
+ </plurals>
+ <plurals name="kau_x_seconds">
+ <item quantity="other">%d 秒</item>
+ </plurals>
+ <string name="kau_yes">是</string>
+ <string name="kau_permission_denied">權限不足</string>
+</resources>
diff --git a/core/src/main/res/layout/kau_changelog_content.xml b/core/src/main/res/layout/kau_changelog_content.xml
index 5c463aa..ab94956 100644
--- a/core/src/main/res/layout/kau_changelog_content.xml
+++ b/core/src/main/res/layout/kau_changelog_content.xml
@@ -3,9 +3,9 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:paddingBottom="8.4sp"
android:paddingLeft="@dimen/kau_dialog_margin"
- android:paddingRight="@dimen/kau_dialog_margin">
+ android:paddingRight="@dimen/kau_dialog_margin"
+ android:paddingBottom="8.4sp">
<!--padding bottom is 14sp * 0.6-->
diff --git a/core/src/test/kotlin/ca/allanwang/kau/kotlin/CoroutineTest.kt b/core/src/test/kotlin/ca/allanwang/kau/kotlin/CoroutineTest.kt
new file mode 100644
index 0000000..1e86305
--- /dev/null
+++ b/core/src/test/kotlin/ca/allanwang/kau/kotlin/CoroutineTest.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ca.allanwang.kau.kotlin
+
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
+import org.junit.Test
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+/**
+ * Tests geared towards coroutines
+ */
+class CoroutineTest {
+
+ /**
+ * If a job is cancelled, then a switch to a new context will not run
+ */
+ @Test
+ fun implicitCancellationBefore() {
+ val job = Job()
+ var id = 0
+ try {
+ runBlocking(job) {
+ id++
+ job.cancel()
+ withContext(Dispatchers.IO) {
+ fail("Context switch should not be reached")
+ }
+ }
+ } catch (ignore: CancellationException) {
+ } finally {
+ assertEquals(1, id, "Launcher never executed")
+ }
+ }
+
+ /**
+ * If a job is cancelled, then a switch from a new context will not run
+ */
+ @Test
+ fun implicitCancellationAfter() {
+ val job = Job()
+ var id = 0
+ try {
+ runBlocking(job) {
+ withContext(Dispatchers.IO) {
+ id++
+ job.cancel()
+ }
+ fail("Post context switch should not be reached")
+ }
+ } catch (ignore: CancellationException) {
+ } finally {
+ assertEquals(1, id, "Context switch never executed")
+ }
+ }
+}
diff --git a/core/src/test/kotlin/ca/allanwang/kau/kotlin/DebounceTest.kt b/core/src/test/kotlin/ca/allanwang/kau/kotlin/DebounceTest.kt
index 8ccdab3..c406901 100644
--- a/core/src/test/kotlin/ca/allanwang/kau/kotlin/DebounceTest.kt
+++ b/core/src/test/kotlin/ca/allanwang/kau/kotlin/DebounceTest.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
import org.junit.Test
@@ -48,5 +63,4 @@ class DebounceTest {
Thread.sleep(30)
assertEquals(10, i)
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/test/kotlin/ca/allanwang/kau/kotlin/LazyResettableTest.kt b/core/src/test/kotlin/ca/allanwang/kau/kotlin/LazyResettableTest.kt
index 2025422..eaaaacb 100644
--- a/core/src/test/kotlin/ca/allanwang/kau/kotlin/LazyResettableTest.kt
+++ b/core/src/test/kotlin/ca/allanwang/kau/kotlin/LazyResettableTest.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
import org.junit.Before
@@ -33,5 +48,4 @@ class LazyResettableTest {
assertEquals(t1, t2, "Lazy resettable not returning same value after second call")
assertNotEquals(t1, t3, "Lazy resettable not invalidated by registry")
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/test/kotlin/ca/allanwang/kau/kotlin/StreamsTest.kt b/core/src/test/kotlin/ca/allanwang/kau/kotlin/StreamsTest.kt
index 1c40f57..4dc4a34 100644
--- a/core/src/test/kotlin/ca/allanwang/kau/kotlin/StreamsTest.kt
+++ b/core/src/test/kotlin/ca/allanwang/kau/kotlin/StreamsTest.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kotlin
import org.junit.Test
@@ -38,5 +53,4 @@ class StreamsTest {
items.kauRemoveIf { it == thePotato } //removal by equality
assertEquals(result.size - 1, items.size, "Invalid list removal based on equality")
}
-
-} \ No newline at end of file
+}
diff --git a/core/src/test/kotlin/ca/allanwang/kau/kotlin/ZipTest.kt b/core/src/test/kotlin/ca/allanwang/kau/kotlin/ZipTest.kt
deleted file mode 100644
index 7eeffaf..0000000
--- a/core/src/test/kotlin/ca/allanwang/kau/kotlin/ZipTest.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package ca.allanwang.kau.kotlin
-
-import org.jetbrains.anko.doAsync
-import org.junit.Test
-import java.util.*
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.test.assertTrue
-
-/**
- * Created by Allan Wang on 2017-08-06.
- */
-class ZipTest {
-
- val debug = false
-
- fun p(text: String) {
- if (debug) println(text)
- }
-
- @Test
- fun basic() {
- val start = System.currentTimeMillis()
- val latch = CountDownLatch(1)
- val rnd = Random()
- (0..10).map {
- { callback: ZipCallback<Int> ->
- doAsync {
- val sleepTime = rnd.nextInt(100) + 200L
- p("Task $it will sleep for ${sleepTime}ms")
- Thread.sleep(sleepTime)
- val finish = System.currentTimeMillis()
- p("Task $it finished in ${finish - start}ms at $finish")
- callback(it)
- }; Unit
- }
- }.zip(-1) { results ->
- val finish = System.currentTimeMillis()
- println("Results ${results.contentToString()} received in ${finish - start}ms at $finish")
- assertTrue((0..10).toList().toTypedArray().contentEquals(results), "Basic zip results do not match")
- assertTrue(finish - start < 1000L, "Basic zip does not seem to be running asynchronously")
- latch.countDown()
-
- }
- latch.await(1100, TimeUnit.MILLISECONDS)
- }
-
- @Test
- fun basicAsync() {
- val start = System.currentTimeMillis()
- val latch = CountDownLatch(1)
- val rnd = Random()
- (0..10).map {
- {
- val sleepTime = rnd.nextInt(100) + 200L
- p("Task $it will sleep for ${sleepTime}ms")
- Thread.sleep(sleepTime)
- val finish = System.currentTimeMillis()
- p("Task $it finished in ${finish - start}ms at $finish")
- }
- }.zipAsync {
- val finish = System.currentTimeMillis()
- println("Results received in ${finish - start}ms at $finish")
- assertTrue(finish - start < 1000L, "BasicAsync does not seem to be wrapping the tasks asynchronously")
- latch.countDown()
- }
- latch.await(1100, TimeUnit.MILLISECONDS)
- }
-
-} \ No newline at end of file
diff --git a/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt b/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt
index ce2b757..b9c200a 100644
--- a/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt
+++ b/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.utils
import android.graphics.Color
@@ -17,9 +32,27 @@ class UtilsTest {
}
@Test
+ fun colorWithAlpha() {
+ val origColor = 0xFF123456.toInt()
+ assertEquals(0x00123456, origColor.withAlpha(0), "Failed to convert with alpha 0")
+ assertEquals(0x50123456, origColor.withAlpha(80), "Failed to convert with alpha 80")
+ assertEquals(0xFF123456.toInt(), origColor.withAlpha(255), "Failed to convert with alpha 255")
+ assertEquals(0xFF123456.toInt(), origColor.withAlpha(0xFF), "Failed to convert with alpha 0xFF")
+ assertEquals(Color.TRANSPARENT, Color.BLACK.withAlpha(0), "Failed to convert black to transparent")
+ }
+
+ @Test
+ fun colorWithMinAlpha() {
+ val origColor = 0x80123456.toInt()
+ assertEquals(origColor, origColor.withMinAlpha(0), "Failed to convert with min alpha 0")
+ assertEquals(0xFA123456.toInt(), origColor.withMinAlpha(0xFA), "Failed to convert with min alpha 0xFA")
+ assertEquals(Color.BLUE, Color.BLUE.withMinAlpha(89), "Failed to convert blue with min alpha 89")
+ }
+
+ @Test
fun rounding() {
assertEquals("1.23", 1.23456f.round(2))
assertEquals("22.466", 22.465920439.round(3))
assertEquals("22", 22f.round(3))
}
-} \ No newline at end of file
+}
diff --git a/crowdin.yaml b/crowdin.yaml
deleted file mode 100644
index 9d8a460..0000000
--- a/crowdin.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-"project_identifier": "kotlin-android-utils"
-"base_path": "/"
-
-"files": [
- {
- "source" : "/about/src/main/res/values/strings_about.xml",
- "translation" : "/about/src/main/res/values-%android_code%/strings_about.xml"
- },
- {
- "source" : "/colorpicker/src/main/res/values/strings_colorpicker.xml",
- "translation" : "/colorpicker/src/main/res/values-%android_code%/strings_colorpicker.xml"
- },
- {
- "source" : "/core/src/main/res-public/values/strings_commons.xml",
- "translation" : "/core/src/main/res-public/values-%android_code%/strings_commons.xml"
- },
- {
- "source" : "/mediapicker/src/main/res/values/strings_mediapicker.xml",
- "translation" : "/mediapicker/src/main/res/values-%android_code%/strings_mediapicker.xml"
- }
-] \ No newline at end of file
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 0000000..7e610f0
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,9 @@
+files:
+ - source: /about/src/main/res/values/strings_about.xml
+ translation: /about/src/main/res/values-%android_code%/strings_about.xml
+ - source: /colorpicker/src/main/res/values/strings_colorpicker.xml
+ translation: /colorpicker/src/main/res/values-%android_code%/strings_colorpicker.xml
+ - source: /core/src/main/res-public/values/strings_commons.xml
+ translation: /core/src/main/res-public/values-%android_code%/strings_commons.xml
+ - source: /mediapicker/src/main/res/values/strings_mediapicker.xml
+ translation: /mediapicker/src/main/res/values-%android_code%/strings_mediapicker.xml
diff --git a/docs/Changelog.md b/docs/Changelog.md
index a5f24f4..a2c38e1 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,5 +1,26 @@
# Changelog
+## v4.1.0
+* :core: Deprecate NetworkUtils, as the underlying functions are deprecated
+* :core: Permission manager no longer synchronized, as all actions should occur in the main thread
+* :kpref-activity: Getter and setter now have action context, with the option to reload self
+
+## v4.0.0
+* Update translations
+
+## v4.0.0-alpha02
+* Update translations
+* :core: Remove anko dependency. Methods that used it now use coroutines; see the migration doc for minor changes
+* :core: Add default CoroutineScope implementation to KauBaseActivity
+* :core: Remove zip class. Coroutines and join can be used as an alternative
+* :core: Delete flyweight implementation. Kotlin already has getOrPut
+* :core: Introduce ContextHelper, where you can get the default looper, handler, and dispatcher for Android
+* :mediapicker: Use video preloading instead of full async loading
+
+## v4.0.0-alpha01
+* Migrate to androidx. See migration for external dependency changes.
+* :core: Remove deprecation warning for Kotterknife
+
## v3.8.0
* Update everything to Android Studio 3.1
* Fix new lint issues (see Migration for resource related methods)
diff --git a/docs/Migration.md b/docs/Migration.md
index ea30c0d..593056e 100644
--- a/docs/Migration.md
+++ b/docs/Migration.md
@@ -2,12 +2,43 @@
Below are some highlights on major refactoring/breaking changes
-# v4.0.0
+# v5.0.0
+
+## Material Dialog Update
+
+Material Dialog is now 3.x.
+This leads to a whole new API, but fortunately it is based around kotlin.
+Please refer to [MD's documents](https://github.com/afollestad/material-dialogs/tree/3.0.0-rc2/documentation) for the new methods.
+
+Alongside such changes, `:colorpicker` is no longer as necessary. It exists mainly to provide an internal interface for other submodules.
## Update ProgressAnimator
`ProgressAnimator` has been completely rewritten to be an extension of `ValueAnimator`.
This for the most part is not a breaking change, apart from the fact that creating an animator will not start it immediately.
+Make sure to call `.start()` to begin the animation.
+
+# v4.0.1-alpha02
+
+* `kauParseFaq` is now synchronous.
+
+## Anko has been removed
+
+A lot of the methods are already implemented in KAU, and it was primarily imported for its `doAsync` methods. Now, they have been replaced with coroutines.
+Some methods have been copied over:
+
+* import org.jetbrains.anko.runOnUiThread > import ca.allanwang.kau.utils.runOnUiThread
+* import org.jetbrains.anko.contentView > import ca.allanwang.kau.utils.contentView
+* import org.jetbrains.anko.bundleOf > import ca.allanwang.kau.utils.bundleOf
+
+# v4.0.0-alpha01
+
+This is the first introduction of androidx. The goal is to just do a migration with minimal changes.
+Nothing has been changed internally, but the dependencies are updated.
+Notably, Android-Iconics [split their Community Icons](https://github.com/mikepenz/Android-Iconics/blob/develop/MIGRATION.md) into two enums.
+
+Kotterknife is also no longer deprecated. There are some use cases where `kotlin-android-extensions` isn't the best, such as when multiple layout files are used, or when ids are defined in the id.xml.
+It is still recommended to use the extension where applicable.
# v3.8.0
diff --git a/favicon/android-chrome-192x192.png b/favicon/android-chrome-192x192.png
new file mode 100644
index 0000000..2d2a7fa
--- /dev/null
+++ b/favicon/android-chrome-192x192.png
Binary files differ
diff --git a/favicon/android-chrome-512x512.png b/favicon/android-chrome-512x512.png
new file mode 100644
index 0000000..6b7cee2
--- /dev/null
+++ b/favicon/android-chrome-512x512.png
Binary files differ
diff --git a/favicon/apple-touch-icon.png b/favicon/apple-touch-icon.png
new file mode 100644
index 0000000..a62432c
--- /dev/null
+++ b/favicon/apple-touch-icon.png
Binary files differ
diff --git a/favicon/browserconfig.xml b/favicon/browserconfig.xml
new file mode 100644
index 0000000..ed5dd79
--- /dev/null
+++ b/favicon/browserconfig.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+ <msapplication>
+ <tile>
+ <square150x150logo src="favicon/mstile-150x150.png"/>
+ <TileColor>#da532c</TileColor>
+ </tile>
+ </msapplication>
+</browserconfig>
diff --git a/favicon/favicon-16x16.png b/favicon/favicon-16x16.png
new file mode 100644
index 0000000..edd0ca3
--- /dev/null
+++ b/favicon/favicon-16x16.png
Binary files differ
diff --git a/favicon/favicon-32x32.png b/favicon/favicon-32x32.png
new file mode 100644
index 0000000..34ab2f4
--- /dev/null
+++ b/favicon/favicon-32x32.png
Binary files differ
diff --git a/favicon/favicon.ico b/favicon/favicon.ico
new file mode 100644
index 0000000..f6c4784
--- /dev/null
+++ b/favicon/favicon.ico
Binary files differ
diff --git a/favicon/mstile-150x150.png b/favicon/mstile-150x150.png
new file mode 100644
index 0000000..44d2059
--- /dev/null
+++ b/favicon/mstile-150x150.png
Binary files differ
diff --git a/favicon/safari-pinned-tab.svg b/favicon/safari-pinned-tab.svg
new file mode 100644
index 0000000..c64d556
--- /dev/null
+++ b/favicon/safari-pinned-tab.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
+ preserveAspectRatio="xMidYMid meet">
+<metadata>
+Created by potrace 1.11, written by Peter Selinger 2001-2013
+</metadata>
+<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M2420 4754 c-495 -44 -915 -214 -1272 -514 l-98 -81 0 -1599 0 -1599
+82 -71 c115 -99 299 -220 441 -292 324 -162 623 -232 987 -232 361 0 669 72
+985 230 200 101 421 261 565 408 l55 56 -753 753 -752 752 750 750 750 750
+-58 58 c-258 264 -662 487 -1042 576 -181 42 -487 69 -640 55z"/>
+</g>
+</svg>
diff --git a/favicon/site.webmanifest b/favicon/site.webmanifest
new file mode 100644
index 0000000..1edcfef
--- /dev/null
+++ b/favicon/site.webmanifest
@@ -0,0 +1,19 @@
+{
+ "name": "",
+ "short_name": "",
+ "icons": [
+ {
+ "src": "android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "android-chrome-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ],
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
+ "display": "standalone"
+}
diff --git a/files/translation_migration.sh b/files/translation_migration.sh
index 9adfdc4..d1372d1 100644
--- a/files/translation_migration.sh
+++ b/files/translation_migration.sh
@@ -6,12 +6,13 @@ cd ..
current=${PWD##*/}
-if [ "$current" != "$MODULE" ]; then
+if [[ "$current" != "$MODULE" ]]; then
echo "Not in $MODULE";
else
# DANGEROUS! Removes all files matching regex
- egrep -lir --include="*.xml" "<resources.*></resources>" "./" | tr '\n' '\0' | xargs -0 -n1 rm
+ grep -Lir "</string>" --include="strings*.xml" "." | tr '\n' '\0' | xargs -0 -n1 rm
# Delete empty directories
find . -type d -empty -delete
fi
+echo "Finished cleanieckng files" \ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index f1c49f3..1e0c1d3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,6 +9,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
+android.enableJetifier=true
+android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 9a4163a..9fccf04 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
+#Tue May 21 11:47:57 PDT 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/kpref-activity/build.gradle b/kpref-activity/build.gradle
index 8b2d12d..ef91e2b 100644
--- a/kpref-activity/build.gradle
+++ b/kpref-activity/build.gradle
@@ -6,8 +6,8 @@ apply from: '../android-lib.gradle'
dependencies {
implementation project(':core')
- implementation project(':adapter')
implementation project(':colorpicker')
+ implementation project(':adapter')
}
apply from: '../artifacts.gradle'
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KClick.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KClick.kt
index c02b024..119f5eb 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KClick.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KClick.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity
import android.content.Context
@@ -24,4 +39,4 @@ interface KClick<T> {
* The item holding the data
*/
val item: KPrefItemBase<T>
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt
index b9681e9..edaf347 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefActivity.kt
@@ -1,22 +1,42 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity
import android.annotation.SuppressLint
import android.os.Bundle
-import android.support.annotation.StringRes
-import android.support.v7.widget.Toolbar
import android.view.View
+import androidx.annotation.StringRes
+import androidx.appcompat.widget.Toolbar
import ca.allanwang.kau.animators.KauAnimator
import ca.allanwang.kau.animators.SlideAnimatorAdd
import ca.allanwang.kau.animators.SlideAnimatorRemove
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.kpref.activity.items.KPrefItemCore
import ca.allanwang.kau.ui.views.RippleCanvas
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.KAU_LEFT
+import ca.allanwang.kau.utils.KAU_RIGHT
+import ca.allanwang.kau.utils.resolveColor
+import ca.allanwang.kau.utils.statusBarColor
+import ca.allanwang.kau.utils.withLinearAdapter
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import kotlinx.android.synthetic.main.kau_pref_activity.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
-import java.util.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.util.Stack
abstract class KPrefActivity : KauBaseActivity(), KPrefActivityContract {
@@ -32,12 +52,16 @@ abstract class KPrefActivity : KauBaseActivity(), KPrefActivityContract {
var animate: Boolean = true
private val recyclerAnimatorNext: KauAnimator by lazy {
- KauAnimator(SlideAnimatorAdd(KAU_RIGHT, itemDelayFactor = 0f),
- SlideAnimatorRemove(KAU_LEFT, itemDelayFactor = 0f))
+ KauAnimator(
+ SlideAnimatorAdd(KAU_RIGHT, itemDelayFactor = 0f),
+ SlideAnimatorRemove(KAU_LEFT, itemDelayFactor = 0f)
+ )
}
private val recyclerAnimatorPrev: KauAnimator by lazy {
- KauAnimator(SlideAnimatorAdd(KAU_LEFT, itemDelayFactor = 0f),
- SlideAnimatorRemove(KAU_RIGHT, itemDelayFactor = 0f))
+ KauAnimator(
+ SlideAnimatorAdd(KAU_LEFT, itemDelayFactor = 0f),
+ SlideAnimatorRemove(KAU_RIGHT, itemDelayFactor = 0f)
+ )
}
/**
@@ -69,26 +93,36 @@ abstract class KPrefActivity : KauBaseActivity(), KPrefActivityContract {
globalOptions = GlobalOptions(core, this)
kau_recycler.withLinearAdapter(adapter)
adapter.withSelectable(false)
- .withOnClickListener { v, _, item, _ -> item.onClick(v!!); true }
+ .withOnClickListener { v, _, item, _ -> item.onClick(v!!); true }
showNextPrefs(R.string.kau_settings, onCreateKPrefs(savedInstanceState), true)
}
- override fun showNextPrefs(@StringRes toolbarTitleRes: Int, builder: KPrefAdapterBuilder.() -> Unit) = showNextPrefs(toolbarTitleRes, builder, false)
-
- private fun showNextPrefs(@StringRes toolbarTitleRes: Int, builder: KPrefAdapterBuilder.() -> Unit, first: Boolean) {
- doAsync {
- val items = KPrefAdapterBuilder(globalOptions)
- builder(items)
- kprefStack.push(toolbarTitleRes to items.list)
- kau_recycler.itemAnimator = if (animate && !first) recyclerAnimatorNext else null
- uiThread {
- adapter.clear()
- adapter.add(items.list.filter { it.core.visible() })
- toolbar.setTitle(toolbarTitleRes)
+ override fun showNextPrefs(@StringRes toolbarTitleRes: Int, builder: KPrefAdapterBuilder.() -> Unit) =
+ showNextPrefs(toolbarTitleRes, builder, false)
+
+ private fun showNextPrefs(
+ @StringRes toolbarTitleRes: Int,
+ builder: KPrefAdapterBuilder.() -> Unit,
+ first: Boolean
+ ) {
+ launch {
+ val items = withContext(Dispatchers.Default) {
+ val items = KPrefAdapterBuilder(globalOptions)
+ builder(items)
+ kprefStack.push(toolbarTitleRes to items.list)
+ items.list
}
+ kau_recycler.itemAnimator = if (animate && !first) recyclerAnimatorNext else null
+ show(toolbarTitleRes, items)
}
}
+ private fun show(@StringRes toolbarTitleRes: Int, items: List<KPrefItemCore>) {
+ toolbar.setTitle(toolbarTitleRes)
+ adapter.clear()
+ adapter.add(items.filter { it.core.visible() })
+ }
+
/**
* Pops the stack and loads the next kpref list
* Indices are not checked so ensure that this is possible first
@@ -97,9 +131,7 @@ abstract class KPrefActivity : KauBaseActivity(), KPrefActivityContract {
kprefStack.pop()
val (title, list) = kprefStack.peek()
kau_recycler.itemAnimator = if (animate) recyclerAnimatorPrev else null
- adapter.clear()
- adapter.add(list.filter { it.core.visible() })
- toolbar.setTitle(title)
+ show(title, list)
}
/**
@@ -162,4 +194,3 @@ abstract class KPrefActivity : KauBaseActivity(), KPrefActivityContract {
return false
}
}
-
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt
index 2cdeae2..764831e 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefBinder.kt
@@ -1,7 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity
-import android.support.annotation.StringRes
-import ca.allanwang.kau.kpref.activity.items.*
+import androidx.annotation.StringRes
+import ca.allanwang.kau.kpref.activity.items.KPrefCheckbox
+import ca.allanwang.kau.kpref.activity.items.KPrefColorPicker
+import ca.allanwang.kau.kpref.activity.items.KPrefHeader
+import ca.allanwang.kau.kpref.activity.items.KPrefItemBase
+import ca.allanwang.kau.kpref.activity.items.KPrefItemCore
+import ca.allanwang.kau.kpref.activity.items.KPrefPlainText
+import ca.allanwang.kau.kpref.activity.items.KPrefSeekbar
+import ca.allanwang.kau.kpref.activity.items.KPrefSubItems
+import ca.allanwang.kau.kpref.activity.items.KPrefText
+import ca.allanwang.kau.kpref.activity.items.KPrefTimePicker
/**
* Created by Allan Wang on 2017-06-08.
@@ -35,11 +59,11 @@ interface KPrefActivityContract {
fun reloadByTitle(@StringRes vararg title: Int)
}
-
-class GlobalOptions(core: CoreAttributeContract, activity: KPrefActivityContract
+class GlobalOptions(
+ core: CoreAttributeContract,
+ activity: KPrefActivityContract
) : CoreAttributeContract by core, KPrefActivityContract by activity
-
/**
* Builder for kpref items
* Contains DSLs for every possible item
@@ -56,51 +80,79 @@ class KPrefAdapterBuilder(val globalOptions: GlobalOptions) {
fun header(@StringRes title: Int) = list.add(KPrefHeader(KPrefItemCore.CoreBuilder(globalOptions, title)))
@KPrefMarker
- fun checkbox(@StringRes title: Int,
- getter: (() -> Boolean),
- setter: ((value: Boolean) -> Unit),
- builder: KPrefItemBase.BaseContract<Boolean>.() -> Unit = {}) = list.add(KPrefCheckbox(KPrefItemBase.BaseBuilder(globalOptions, title, getter, setter)
- .apply { builder() }))
+ fun checkbox(
+ @StringRes title: Int,
+ getter: () -> Boolean,
+ setter: KPrefItemActions.(value: Boolean) -> Unit,
+ builder: KPrefItemBase.BaseContract<Boolean>.() -> Unit = {}
+ ) = list.add(
+ KPrefCheckbox(KPrefItemBase.BaseBuilder(globalOptions, title, getter, setter)
+ .apply { builder() })
+ )
@KPrefMarker
- fun colorPicker(@StringRes title: Int,
- getter: (() -> Int),
- setter: ((value: Int) -> Unit),
- builder: KPrefColorPicker.KPrefColorContract.() -> Unit = {}) = list.add(KPrefColorPicker(KPrefColorPicker.KPrefColorBuilder(globalOptions, title, getter, setter)
- .apply { builder() }))
+ fun colorPicker(
+ @StringRes title: Int,
+ getter: () -> Int,
+ setter: KPrefItemActions.(value: Int) -> Unit,
+ builder: KPrefColorPicker.KPrefColorContract.() -> Unit = {}
+ ) = list.add(
+ KPrefColorPicker(KPrefColorPicker.KPrefColorBuilder(globalOptions, title, getter, setter)
+ .apply { builder() })
+ )
@KPrefMarker
- fun <T> text(@StringRes title: Int,
- getter: (() -> T),
- setter: ((value: T) -> Unit),
- builder: KPrefText.KPrefTextContract<T>.() -> Unit = {}) = list.add(KPrefText(KPrefText.KPrefTextBuilder(globalOptions, title, getter, setter)
- .apply { builder() }))
+ fun <T> text(
+ @StringRes title: Int,
+ getter: () -> T,
+ setter: KPrefItemActions.(value: T) -> Unit,
+ builder: KPrefText.KPrefTextContract<T>.() -> Unit = {}
+ ) = list.add(
+ KPrefText(KPrefText.KPrefTextBuilder(globalOptions, title, getter, setter)
+ .apply { builder() })
+ )
@KPrefMarker
- fun subItems(@StringRes title: Int,
- itemBuilder: KPrefAdapterBuilder.() -> Unit,
- builder: KPrefSubItems.KPrefSubItemsContract.() -> Unit) = list.add(KPrefSubItems(KPrefSubItems.KPrefSubItemsBuilder(globalOptions, title, itemBuilder)
- .apply { builder() }))
+ fun subItems(
+ @StringRes title: Int,
+ itemBuilder: KPrefAdapterBuilder.() -> Unit,
+ builder: KPrefSubItems.KPrefSubItemsContract.() -> Unit
+ ) = list.add(
+ KPrefSubItems(KPrefSubItems.KPrefSubItemsBuilder(globalOptions, title, itemBuilder)
+ .apply { builder() })
+ )
@KPrefMarker
- fun plainText(@StringRes title: Int,
- builder: KPrefItemBase.BaseContract<Unit>.() -> Unit = {}) = list.add(KPrefPlainText(KPrefPlainText.KPrefPlainTextBuilder(globalOptions, title)
- .apply { builder() }))
+ fun plainText(
+ @StringRes title: Int,
+ builder: KPrefItemBase.BaseContract<Unit>.() -> Unit = {}
+ ) = list.add(
+ KPrefPlainText(KPrefPlainText.KPrefPlainTextBuilder(globalOptions, title)
+ .apply { builder() })
+ )
@KPrefMarker
- fun seekbar(@StringRes title: Int,
- getter: (() -> Int),
- setter: ((value: Int) -> Unit),
- builder: KPrefSeekbar.KPrefSeekbarContract.() -> Unit = {}) = list.add(KPrefSeekbar(KPrefSeekbar.KPrefSeekbarBuilder(globalOptions, title, getter, setter)
- .apply { builder() }))
+ fun seekbar(
+ @StringRes title: Int,
+ getter: () -> Int,
+ setter: KPrefItemActions.(value: Int) -> Unit,
+ builder: KPrefSeekbar.KPrefSeekbarContract.() -> Unit = {}
+ ) = list.add(
+ KPrefSeekbar(KPrefSeekbar.KPrefSeekbarBuilder(globalOptions, title, getter, setter)
+ .apply { builder() })
+ )
@KPrefMarker
- fun timePicker(@StringRes title: Int,
- getter: (() -> Int),
- setter: ((value: Int) -> Unit),
- builder: KPrefTimePicker.KPrefTimeContract.() -> Unit = {}) = list.add(KPrefTimePicker(KPrefTimePicker.KPrefTimeBuilder(globalOptions, title, getter, setter)
- .apply { builder() }))
+ fun timePicker(
+ @StringRes title: Int,
+ getter: () -> Int,
+ setter: KPrefItemActions.(value: Int) -> Unit,
+ builder: KPrefTimePicker.KPrefTimeContract.() -> Unit = {}
+ ) = list.add(
+ KPrefTimePicker(KPrefTimePicker.KPrefTimeBuilder(globalOptions, title, getter, setter)
+ .apply { builder() })
+ )
@KPrefMarker
val list: MutableList<KPrefItemCore> = mutableListOf()
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefItemActions.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefItemActions.kt
new file mode 100644
index 0000000..e28bac6
--- /dev/null
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/KPrefItemActions.kt
@@ -0,0 +1,11 @@
+package ca.allanwang.kau.kpref.activity
+
+/**
+ * Applicable actions
+ */
+interface KPrefItemActions {
+ /**
+ * Attempts to reload current item by identifying it with its titleId
+ */
+ fun reloadSelf()
+} \ No newline at end of file
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefCheckbox.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefCheckbox.kt
index f391747..0f025a6 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefCheckbox.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefCheckbox.kt
@@ -1,7 +1,22 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
-import android.support.v7.widget.AppCompatCheckBox
import android.widget.CheckBox
+import androidx.appcompat.widget.AppCompatCheckBox
import ca.allanwang.kau.kpref.activity.KClick
import ca.allanwang.kau.kpref.activity.R
import ca.allanwang.kau.utils.tint
@@ -28,5 +43,4 @@ open class KPrefCheckbox(builder: BaseContract<Boolean>) : KPrefItemBase<Boolean
}
override fun getType(): Int = R.id.kau_item_pref_checkbox
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt
index 3201fbd..8b051c5 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefColorPicker.kt
@@ -1,12 +1,29 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import ca.allanwang.kau.colorpicker.CircleView
import ca.allanwang.kau.colorpicker.ColorBuilder
import ca.allanwang.kau.colorpicker.ColorContract
-import ca.allanwang.kau.colorpicker.colorPickerDialog
+import ca.allanwang.kau.colorpicker.kauColorChooser
import ca.allanwang.kau.kpref.activity.GlobalOptions
import ca.allanwang.kau.kpref.activity.KClick
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.R
+import com.afollestad.materialdialogs.MaterialDialog
/**
* Created by Allan Wang on 2017-06-07.
@@ -18,50 +35,52 @@ open class KPrefColorPicker(open val builder: KPrefColorContract) : KPrefItemBas
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
- builder.apply {
- titleRes = core.titleFun()
- colorCallback = { pref = it }
- }
if (builder.showPreview) {
val preview = holder.bindInnerView<CircleView>(R.layout.kau_pref_color)
preview.setBackgroundColor(pref)
preview.withBorder = true
- builder.apply {
- colorCallback = {
- pref = it
- if (builder.showPreview)
- preview.setBackgroundColor(it)
- holder.updateTitle()
- holder.updateDesc()
- }
+ builder.callback = { _, color ->
+ pref = color
+ if (builder.showPreview)
+ preview.setBackgroundColor(color)
+ holder.updateTitle()
+ holder.updateDesc()
}
+ } else {
+ builder.callback = { _, color -> pref = color }
}
}
override fun KClick<Int>.defaultOnClick() {
builder.defaultColor = pref
- context.colorPickerDialog(builder).show()
+ MaterialDialog(context).show {
+ kauColorChooser(builder)
+ builder.dialogBuilder(this)
+ title(core.titleFun())
+ }
}
/**
* Extension of the base contract and [ColorContract] along with a showPreview option
*/
- interface KPrefColorContract : BaseContract<Int>, ColorContract {
+ interface KPrefColorContract : KPrefItemBase.BaseContract<Int>, ColorContract {
var showPreview: Boolean
+ var dialogBuilder: MaterialDialog.() -> Unit
}
/**
* Default implementation of [KPrefColorContract]
*/
- class KPrefColorBuilder(globalOptions: GlobalOptions,
- titleId: Int,
- getter: () -> Int,
- setter: (value: Int) -> Unit
- ) : KPrefColorContract, BaseContract<Int> by BaseBuilder(globalOptions, titleId, getter, setter),
- ColorContract by ColorBuilder() {
+ class KPrefColorBuilder(
+ globalOptions: GlobalOptions,
+ titleId: Int,
+ getter: () -> Int,
+ setter: KPrefItemActions.(value: Int) -> Unit
+ ) : KPrefColorContract, KPrefItemBase.BaseContract<Int> by BaseBuilder(globalOptions, titleId, getter, setter),
+ ColorContract by ColorBuilder() {
override var showPreview: Boolean = true
+ override var dialogBuilder: MaterialDialog.() -> Unit = {}
}
override fun getType(): Int = R.id.kau_item_pref_color_picker
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefHeader.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefHeader.kt
index 9b63a52..7d73322 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefHeader.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefHeader.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import ca.allanwang.kau.kpref.activity.R
@@ -18,5 +33,4 @@ open class KPrefHeader(builder: CoreContract) : KPrefItemCore(builder) {
}
override fun getType() = R.id.kau_item_pref_header
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemBase.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemBase.kt
index 5081f50..c597b63 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemBase.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemBase.kt
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
-import android.support.annotation.CallSuper
import android.view.View
+import androidx.annotation.CallSuper
import ca.allanwang.kau.kpref.activity.GlobalOptions
import ca.allanwang.kau.kpref.activity.KClick
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.R
import ca.allanwang.kau.utils.resolveDrawable
@@ -17,7 +33,7 @@ abstract class KPrefItemBase<T>(protected val base: BaseContract<T>) : KPrefItem
open var pref: T
get() = base.getter()
set(value) {
- base.setter(value)
+ base.setter(this, value)
}
private var _enabled: Boolean = true
@@ -78,20 +94,20 @@ abstract class KPrefItemBase<T>(protected val base: BaseContract<T>) : KPrefItem
var onClick: (KClick<T>.() -> Unit)?
var onDisabledClick: (KClick<T>.() -> Unit)?
val getter: () -> T
- val setter: (value: T) -> Unit
+ val setter: KPrefItemActions.(value: T) -> Unit
}
/**
* Default implementation of [BaseContract]
*/
- class BaseBuilder<T>(globalOptions: GlobalOptions,
- titleId: Int,
- override val getter: () -> T,
- override val setter: (value: T) -> Unit
+ class BaseBuilder<T>(
+ globalOptions: GlobalOptions,
+ titleId: Int,
+ override val getter: () -> T,
+ override val setter: KPrefItemActions.(value: T) -> Unit
) : CoreContract by CoreBuilder(globalOptions, titleId), BaseContract<T> {
override var enabler: () -> Boolean = { true }
override var onClick: (KClick<T>.() -> Unit)? = null
override var onDisabledClick: (KClick<T>.() -> Unit)? = null
}
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt
index fcc13ba..36bf670 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefItemCore.kt
@@ -1,23 +1,44 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import android.annotation.SuppressLint
-import android.support.annotation.CallSuper
-import android.support.annotation.IdRes
-import android.support.annotation.LayoutRes
-import android.support.annotation.StringRes
-import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
+import androidx.annotation.CallSuper
+import androidx.annotation.IdRes
+import androidx.annotation.LayoutRes
+import androidx.annotation.StringRes
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapters.ThemableIItem
import ca.allanwang.kau.adapters.ThemableIItemDelegate
import ca.allanwang.kau.kpref.activity.GlobalOptions
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.KPrefMarker
import ca.allanwang.kau.kpref.activity.R
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.INVALID_ID
+import ca.allanwang.kau.utils.adjustAlpha
+import ca.allanwang.kau.utils.buildIsLollipopAndUp
+import ca.allanwang.kau.utils.gone
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.visible
import com.mikepenz.fastadapter.items.AbstractItem
import com.mikepenz.iconics.typeface.IIcon
@@ -27,8 +48,8 @@ import com.mikepenz.iconics.typeface.IIcon
* Core class containing nothing but the view items
*/
-abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCore, KPrefItemCore.ViewHolder>(),
- ThemableIItem by ThemableIItemDelegate() {
+abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCore, KPrefItemCore.ViewHolder>(), KPrefItemActions by core,
+ ThemableIItem by ThemableIItemDelegate() {
final override fun getViewHolder(v: View) = ViewHolder(v)
@@ -69,13 +90,15 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCor
}
protected inline fun withAccentColor(action: (color: Int) -> Unit) =
- withColor(core.globalOptions.accentColor, action)
+ withColor(core.globalOptions.accentColor, action)
protected inline fun withTextColor(action: (color: Int) -> Unit) =
- withColor(core.globalOptions.textColor, action)
+ withColor(core.globalOptions.textColor, action)
- protected inline fun withColor(noinline supplier: (() -> Int)?,
- action: (color: Int) -> Unit) {
+ protected inline fun withColor(
+ noinline supplier: (() -> Int)?,
+ action: (color: Int) -> Unit
+ ) {
val color = supplier?.invoke() ?: return
action(color)
}
@@ -97,7 +120,7 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCor
* Core values for all kpref items
*/
@KPrefMarker
- interface CoreContract {
+ interface CoreContract : KPrefItemActions {
val globalOptions: GlobalOptions
val titleId: Int
var titleFun: () -> Int
@@ -106,18 +129,15 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCor
var descFun: () -> Int
var iicon: IIcon?
var visible: () -> Boolean
-
- /**
- * Attempts to reload current item by identifying it with its [id]
- */
- fun reloadSelf()
}
/**
* Default implementation of [CoreContract]
*/
- class CoreBuilder(override val globalOptions: GlobalOptions,
- override val titleId: Int) : CoreContract {
+ class CoreBuilder(
+ override val globalOptions: GlobalOptions,
+ override val titleId: Int
+ ) : CoreContract {
override var descRes: Int = INVALID_ID
set(value) {
field = value
@@ -149,7 +169,7 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCor
inline fun <reified T : View> bindInnerView(@LayoutRes id: Int, onFirstBind: (T) -> Unit): T {
val innerFrame = this.innerFrame
- ?: throw IllegalStateException("Cannot bind inner view when innerFrame does not exist")
+ ?: throw IllegalStateException("Cannot bind inner view when innerFrame does not exist")
if (innerView !is T) {
innerFrame.removeAllViews()
LayoutInflater.from(innerFrame.context).inflate(id, innerFrame)
@@ -162,7 +182,7 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCor
inline fun <reified T : View> bindLowerView(@LayoutRes id: Int, onFirstBind: (T) -> Unit): T {
val lowerFrame = this.lowerFrame
- ?: throw IllegalStateException("Cannot bind inner view when lowerContent does not exist")
+ ?: throw IllegalStateException("Cannot bind inner view when lowerContent does not exist")
if (lowerContent !is T) {
lowerFrame.removeAllViews()
LayoutInflater.from(lowerFrame.context).inflate(id, lowerFrame)
@@ -173,4 +193,4 @@ abstract class KPrefItemCore(val core: CoreContract) : AbstractItem<KPrefItemCor
operator fun get(@IdRes id: Int): View = itemView.findViewById(id)
}
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt
index 40bf284..6a0aaf5 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefPlainText.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import ca.allanwang.kau.kpref.activity.GlobalOptions
@@ -17,10 +32,9 @@ open class KPrefPlainText(open val builder: KPrefPlainTextBuilder) : KPrefItemBa
override fun KClick<Unit>.defaultOnClick() = Unit
class KPrefPlainTextBuilder(
- globalOptions: GlobalOptions,
- titleId: Int
+ globalOptions: GlobalOptions,
+ titleId: Int
) : BaseContract<Unit> by BaseBuilder(globalOptions, titleId, {}, {})
override fun getType(): Int = R.id.kau_item_pref_plain_text
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSeekbar.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSeekbar.kt
index ce61e8f..a582ec4 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSeekbar.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSeekbar.kt
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import android.widget.SeekBar
import android.widget.TextView
import ca.allanwang.kau.kpref.activity.GlobalOptions
import ca.allanwang.kau.kpref.activity.KClick
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.R
import ca.allanwang.kau.utils.tint
@@ -67,10 +83,10 @@ open class KPrefSeekbar(val builder: KPrefSeekbarContract) : KPrefItemBase<Int>(
* Default implementation of [KPrefSeekbarContract]
*/
class KPrefSeekbarBuilder(
- globalOptions: GlobalOptions,
- titleId: Int,
- getter: () -> Int,
- setter: (value: Int) -> Unit
+ globalOptions: GlobalOptions,
+ titleId: Int,
+ getter: () -> Int,
+ setter: KPrefItemActions.(value: Int) -> Unit
) : KPrefSeekbarContract, BaseContract<Int> by BaseBuilder(globalOptions, titleId, getter, setter) {
override var min: Int = 0
@@ -103,5 +119,4 @@ open class KPrefSeekbar(val builder: KPrefSeekbarContract) : KPrefItemBase<Int>(
get() = this * increment + min
override fun getType(): Int = R.id.kau_item_pref_seekbar
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt
index 6753142..1fa528b 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefSubItems.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import android.view.View
@@ -31,11 +46,10 @@ open class KPrefSubItems(open val builder: KPrefSubItemsContract) : KPrefItemCor
* Default implementation of [KPrefTextContract]
*/
class KPrefSubItemsBuilder(
- globalOptions: GlobalOptions,
- titleId: Int,
- override val itemBuilder: KPrefAdapterBuilder.() -> Unit
+ globalOptions: GlobalOptions,
+ titleId: Int,
+ override val itemBuilder: KPrefAdapterBuilder.() -> Unit
) : KPrefSubItemsContract, CoreContract by CoreBuilder(globalOptions, titleId)
override fun getType(): Int = R.id.kau_item_pref_sub_item
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt
index 2ab911b..76c9e20 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefText.kt
@@ -1,8 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import android.widget.TextView
import ca.allanwang.kau.kpref.activity.GlobalOptions
import ca.allanwang.kau.kpref.activity.KClick
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.R
import ca.allanwang.kau.utils.toast
@@ -22,7 +38,7 @@ open class KPrefText<T>(open val builder: KPrefTextContract<T>) : KPrefItemBase<
override var pref: T
get() = base.getter()
set(value) {
- base.setter(value)
+ base.setter(this, value)
builder.reloadSelf()
}
@@ -48,14 +64,13 @@ open class KPrefText<T>(open val builder: KPrefTextContract<T>) : KPrefItemBase<
* Default implementation of [KPrefTextContract]
*/
class KPrefTextBuilder<T>(
- globalOptions: GlobalOptions,
- titleId: Int,
- getter: () -> T,
- setter: (value: T) -> Unit
+ globalOptions: GlobalOptions,
+ titleId: Int,
+ getter: () -> T,
+ setter: KPrefItemActions.(value: T) -> Unit
) : KPrefTextContract<T>, BaseContract<T> by BaseBuilder<T>(globalOptions, titleId, getter, setter) {
override var textGetter: (T) -> String? = { it?.toString() }
}
override fun getType(): Int = R.id.kau_item_pref_text
-
-} \ No newline at end of file
+}
diff --git a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt
index f6fc40a..f50397c 100644
--- a/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt
+++ b/kpref-activity/src/main/kotlin/ca/allanwang/kau/kpref/activity/items/KPrefTimePicker.kt
@@ -1,11 +1,27 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.kpref.activity.items
import android.app.TimePickerDialog
import android.widget.TimePicker
import ca.allanwang.kau.kpref.activity.GlobalOptions
import ca.allanwang.kau.kpref.activity.KClick
+import ca.allanwang.kau.kpref.activity.KPrefItemActions
import ca.allanwang.kau.kpref.activity.R
-import java.util.*
+import java.util.Locale
/**
* Created by Allan Wang on 2017-06-14.
@@ -30,11 +46,11 @@ open class KPrefTimePicker(override val builder: KPrefTimeContract) : KPrefText<
* Default implementation of [KPrefTimeContract]
*/
class KPrefTimeBuilder(
- globalOptions: GlobalOptions,
- titleId: Int,
- getter: () -> Int,
- setter: (value: Int) -> Unit
- ) : KPrefTimeContract, BaseContract<Int> by BaseBuilder<Int>(globalOptions, titleId, getter, setter) {
+ globalOptions: GlobalOptions,
+ titleId: Int,
+ getter: () -> Int,
+ setter: KPrefItemActions.(value: Int) -> Unit
+ ) : KPrefTimeContract, BaseContract<Int> by BaseBuilder(globalOptions, titleId, getter, setter) {
override var use24HourFormat: Boolean = false
@@ -50,15 +66,13 @@ open class KPrefTimePicker(override val builder: KPrefTimeContract) : KPrefText<
else
String.format(Locale.CANADA, "%d:%02d %s", hour % 12, min, if (hour >= 12) "PM" else "AM")
}
-
}
override fun getType(): Int = R.id.kau_item_pref_time_picker
-
}
private val Int.splitTime: Pair<Int, Int>
get() = Pair(this / 100, this % 100)
private val Pair<Int, Int>.mergeTime: Int
- get() = first * 100 + second \ No newline at end of file
+ get() = first * 100 + second
diff --git a/kpref-activity/src/main/res/layout/kau_pref_activity.xml b/kpref-activity/src/main/res/layout/kau_pref_activity.xml
index 7651e5a..d6ea6e6 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_activity.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_activity.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -13,7 +13,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@id/kau_toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
@@ -32,7 +32,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/kau_toolbar" />
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/kau_recycler"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -41,4 +41,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/kau_toolbar" />
-</android.support.constraint.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/kpref-activity/src/main/res/layout/kau_pref_checkbox.xml b/kpref-activity/src/main/res/layout/kau_pref_checkbox.xml
index 1fecb4d..6c52b52 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_checkbox.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_checkbox.xml
@@ -1,4 +1,4 @@
-<android.support.v7.widget.AppCompatCheckBox xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.appcompat.widget.AppCompatCheckBox xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/kau_pref_inner_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/kpref-activity/src/main/res/layout/kau_pref_core.xml b/kpref-activity/src/main/res/layout/kau_pref_core.xml
index 72f26d9..2571dd3 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_core.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_core.xml
@@ -12,7 +12,7 @@
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:orientation="horizontal">
- <android.support.constraint.ConstraintLayout
+ <androidx.constraintlayout.widget.ConstraintLayout
android:id="@id/kau_pref_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -22,7 +22,7 @@
<!--As per Android N, icons (24dp) are aligned to the left rather than centered-->
- <android.support.v7.widget.AppCompatImageView
+ <androidx.appcompat.widget.AppCompatImageView
android:id="@id/kau_pref_icon"
android:layout_width="56dp"
android:layout_height="56dp"
@@ -37,7 +37,7 @@
tools:ignore="RtlSymmetry"
tools:layout_editor_absoluteX="0dp" />
- <android.support.v7.widget.AppCompatTextView
+ <androidx.appcompat.widget.AppCompatTextView
android:id="@id/kau_pref_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -52,7 +52,7 @@
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="-175dp" />
- <android.support.v7.widget.AppCompatTextView
+ <androidx.appcompat.widget.AppCompatTextView
android:id="@id/kau_pref_desc"
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -80,7 +80,7 @@
app:layout_constraintTop_toBottomOf="@id/kau_pref_desc"
tools:layout_editor_absoluteX="-175dp" />
- <android.support.constraint.Barrier
+ <androidx.constraintlayout.widget.Barrier
android:id="@id/kau_pref_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -105,6 +105,6 @@
app:layout_constraintVertical_bias="0.5"
tools:layout_editor_absoluteX="1dp" />
- </android.support.constraint.ConstraintLayout>
+ </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> \ No newline at end of file
diff --git a/kpref-activity/src/main/res/layout/kau_pref_header.xml b/kpref-activity/src/main/res/layout/kau_pref_header.xml
index d802a14..65504a3 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_header.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_header.xml
@@ -1,4 +1,4 @@
-<android.support.v7.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.appcompat.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/kau_pref_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/kpref-activity/src/main/res/layout/kau_pref_seekbar.xml b/kpref-activity/src/main/res/layout/kau_pref_seekbar.xml
index 0b07e1c..5ff6351 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_seekbar.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_seekbar.xml
@@ -1,4 +1,4 @@
-<android.support.v7.widget.AppCompatSeekBar xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.appcompat.widget.AppCompatSeekBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/kau_pref_lower_content"
android:layout_width="match_parent"
android:paddingTop="@dimen/kau_padding_normal"
diff --git a/kpref-activity/src/main/res/layout/kau_pref_seekbar_text.xml b/kpref-activity/src/main/res/layout/kau_pref_seekbar_text.xml
index dc11d2a..5834820 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_seekbar_text.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_seekbar_text.xml
@@ -1,6 +1,6 @@
<!--TextView that aligns to the bottom-->
-<android.support.v7.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.appcompat.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/kau_pref_inner_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/kpref-activity/src/main/res/layout/kau_pref_text.xml b/kpref-activity/src/main/res/layout/kau_pref_text.xml
index 40fed2a..b873eaf 100644
--- a/kpref-activity/src/main/res/layout/kau_pref_text.xml
+++ b/kpref-activity/src/main/res/layout/kau_pref_text.xml
@@ -1,4 +1,4 @@
-<android.support.v7.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.appcompat.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/kau_pref_inner_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/BlurredImageView.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/BlurredImageView.kt
index f1e32d1..739bf47 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/BlurredImageView.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/BlurredImageView.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.content.Context
@@ -8,7 +23,11 @@ import android.widget.FrameLayout
import android.widget.ImageView
import ca.allanwang.kau.ui.views.MeasureSpecContract
import ca.allanwang.kau.ui.views.MeasureSpecDelegate
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.inflate
+import ca.allanwang.kau.utils.scaleXY
+import ca.allanwang.kau.utils.setBackgroundColorRes
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.visible
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import jp.wasabeef.blurry.internal.BlurFactor
import jp.wasabeef.blurry.internal.BlurTask
@@ -24,7 +43,9 @@ import kotlinx.android.synthetic.main.kau_blurred_imageview.view.*
* The foreground by default contains a white checkmark, but can be customized or hidden depending on the situation
*/
class BlurredImageView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), MeasureSpecContract by MeasureSpecDelegate() {
private var blurred = false
@@ -51,7 +72,6 @@ class BlurredImageView @JvmOverloads constructor(
private fun View.scaleAnimate(scale: Float) = animate().scaleXY(scale).setDuration(ANIMATION_DURATION)
private fun View.alphaAnimate(alpha: Float) = animate().alpha(alpha).setDuration(ANIMATION_DURATION)
-
fun isBlurred(): Boolean {
return blurred
}
@@ -104,7 +124,6 @@ class BlurredImageView @JvmOverloads constructor(
image_foreground.alphaAnimate(0f).start()
}
-
/**
* Clear all animations and unblur the image
*/
@@ -154,4 +173,4 @@ class BlurredImageView @JvmOverloads constructor(
action(image_blur)
action(image_foreground)
}
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt
index 8bb341c..21a1e9d 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/GlideHelper.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.view.View
@@ -15,4 +30,4 @@ internal interface GlideContract {
internal class GlideDelegate : GlideContract {
override fun glide(v: View) = ((v.context as? MediaPickerCore<*>)?.glide ?: Glide.with(v))!!
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaActionItem.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaActionItem.kt
index 0cf6340..1941ec0 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaActionItem.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaActionItem.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.app.Activity
@@ -15,14 +30,17 @@ import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.typeface.IIcon
import java.io.File
-
/**
* Created by Allan Wang on 2017-08-17.
*/
class MediaActionItem(
- val action: MediaAction,
- val mediaType: MediaType
-) : KauIItem<MediaActionItem, MediaItemBasic.ViewHolder>(R.layout.kau_iitem_image_basic, { MediaItemBasic.ViewHolder(it) }, R.id.kau_item_media_action) {
+ val action: MediaAction,
+ val mediaType: MediaType
+) : KauIItem<MediaActionItem, MediaItemBasic.ViewHolder>(
+ R.layout.kau_iitem_image_basic,
+ { MediaItemBasic.ViewHolder(it) },
+ R.id.kau_item_media_action
+) {
override fun isSelectable(): Boolean = false
@@ -60,7 +78,7 @@ internal const val MEDIA_ACTION_REQUEST_PICKER = 101
* If you just wish to use videos, see [MediaActionCameraVideo]
*/
abstract class MediaActionCamera(
- override var color: Int = MediaPickerCore.accentColor
+ override var color: Int = MediaPickerCore.accentColor
) : MediaAction {
abstract fun createFile(context: Context): File
@@ -78,7 +96,7 @@ abstract class MediaActionCamera(
if (intent.resolveActivity(c.packageManager) == null) {
c.materialDialog {
title(R.string.kau_no_camera_found)
- content(R.string.kau_no_camera_found_content)
+ message(R.string.kau_no_camera_found_content)
}
return@kauRequestPermissions
}
@@ -88,7 +106,7 @@ abstract class MediaActionCamera(
} catch (e: java.io.IOException) {
c.materialDialog {
title(R.string.kau_error)
- content(R.string.kau_temp_file_creation_failed)
+ message(R.string.kau_temp_file_creation_failed)
}
return@kauRequestPermissions
}
@@ -105,7 +123,7 @@ abstract class MediaActionCamera(
* Basic camera action just for videos
*/
class MediaActionCameraVideo(
- override var color: Int = MediaPickerCore.accentColor
+ override var color: Int = MediaPickerCore.accentColor
) : MediaAction {
override fun iicon(item: MediaActionItem) = GoogleMaterial.Icon.gmd_videocam
override operator fun invoke(c: Context, item: MediaActionItem) {
@@ -113,7 +131,7 @@ class MediaActionCameraVideo(
if (intent.resolveActivity(c.packageManager) == null) {
c.materialDialog {
title(R.string.kau_no_camera_found)
- content(R.string.kau_no_camera_found_content)
+ message(R.string.kau_no_camera_found_content)
}
return
}
@@ -126,8 +144,8 @@ class MediaActionCameraVideo(
* The type will be added programmatically
*/
class MediaActionGallery(
- val multiple: Boolean = false,
- override var color: Int = MediaPickerCore.accentColor
+ val multiple: Boolean = false,
+ override var color: Int = MediaPickerCore.accentColor
) : MediaAction {
override fun iicon(item: MediaActionItem) = when (item.mediaType) {
@@ -144,9 +162,10 @@ class MediaActionGallery(
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple)
}
(c as Activity).startActivityForResult(
- Intent.createChooser(intent, c.string(R.string.kau_select_media)),
- MEDIA_ACTION_REQUEST_PICKER)
+ Intent.createChooser(intent, c.string(R.string.kau_select_media)),
+ MEDIA_ACTION_REQUEST_PICKER
+ )
}
}
}
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt
index c0b7e2d..5d3e7b9 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.graphics.drawable.Drawable
-import android.support.v7.widget.RecyclerView
import android.view.View
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.iitems.KauIItem
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
@@ -13,22 +28,23 @@ import com.mikepenz.fastadapter.FastAdapter
/**
* Created by Allan Wang on 2017-07-04.
*/
-class MediaItem(val data: MediaModel)
- : KauIItem<MediaItem, MediaItem.ViewHolder>(R.layout.kau_iitem_image, { ViewHolder(it) }), GlideContract by GlideDelegate() {
+class MediaItem(val data: MediaModel) :
+ KauIItem<MediaItem, MediaItem.ViewHolder>(R.layout.kau_iitem_image, { ViewHolder(it) }),
+ GlideContract by GlideDelegate() {
private var failedToLoad = false
companion object {
fun bindEvents(fastAdapter: FastAdapter<MediaItem>) {
fastAdapter.withMultiSelect(true)
- .withSelectable(true)
- //adapter selector occurs before the on click event
- .withOnClickListener { v, _, item, _ ->
- val image = v as BlurredImageView
- if (item.isSelected) image.blur()
- else image.removeBlur()
- true
- }
+ .withSelectable(true)
+ //adapter selector occurs before the on click event
+ .withOnClickListener { v, _, item, _ ->
+ val image = v as BlurredImageView
+ if (item.isSelected) image.blur()
+ else image.removeBlur()
+ true
+ }
}
}
@@ -37,22 +53,33 @@ class MediaItem(val data: MediaModel)
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
glide(holder.itemView)
- .load(data.data)
- .applyMediaOptions(holder.itemView.context)
- .listener(object : RequestListener<Drawable> {
- override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
- failedToLoad = true
- holder.container.imageBase.setImageDrawable(MediaPickerCore.getErrorDrawable(holder.itemView.context))
- return true
- }
+ .load(data.data)
+ .applyMediaOptions(holder.itemView.context)
+ .listener(object : RequestListener<Drawable> {
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any,
+ target: Target<Drawable>,
+ isFirstResource: Boolean
+ ): Boolean {
+ failedToLoad = true
+ holder.container.imageBase.setImageDrawable(MediaPickerCore.getErrorDrawable(holder.itemView.context))
+ return true
+ }
- override fun onResourceReady(resource: Drawable, model: Any, target: Target<Drawable>, dataSource: DataSource, isFirstResource: Boolean): Boolean {
- holder.container.imageBase.setImageDrawable(resource)
- if (isSelected) holder.container.blurInstantly()
- return true
- }
- })
- .into(holder.container.imageBase)
+ override fun onResourceReady(
+ resource: Drawable,
+ model: Any,
+ target: Target<Drawable>,
+ dataSource: DataSource,
+ isFirstResource: Boolean
+ ): Boolean {
+ holder.container.imageBase.setImageDrawable(resource)
+ if (isSelected) holder.container.blurInstantly()
+ return true
+ }
+ })
+ .into(holder.container.imageBase)
}
override fun unbindView(holder: ViewHolder) {
@@ -65,4 +92,4 @@ class MediaItem(val data: MediaModel)
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
val container: BlurredImageView = v.findViewById(R.id.kau_image)
}
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt
index 59202c0..73647b8 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt
@@ -1,10 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.drawable.Drawable
-import android.support.v7.widget.RecyclerView
import android.view.View
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.iitems.KauIItem
import ca.allanwang.kau.ui.views.MeasuredImageView
import com.bumptech.glide.load.DataSource
@@ -16,18 +31,19 @@ import com.mikepenz.fastadapter.FastAdapter
/**
* Created by Allan Wang on 2017-07-04.
*/
-class MediaItemBasic(val data: MediaModel)
- : KauIItem<MediaItem, MediaItemBasic.ViewHolder>(R.layout.kau_iitem_image_basic, { ViewHolder(it) }), GlideContract by GlideDelegate() {
+class MediaItemBasic(val data: MediaModel) :
+ KauIItem<MediaItem, MediaItemBasic.ViewHolder>(R.layout.kau_iitem_image_basic, { ViewHolder(it) }),
+ GlideContract by GlideDelegate() {
companion object {
@SuppressLint("NewApi")
fun bindEvents(activity: Activity, fastAdapter: FastAdapter<MediaItemBasic>) {
fastAdapter.withSelectable(false)
- //add image data and return right away
- .withOnClickListener { _, _, item, _ ->
- activity.finish(arrayListOf(item.data))
- true
- }
+ //add image data and return right away
+ .withOnClickListener { _, _, item, _ ->
+ activity.finish(arrayListOf(item.data))
+ true
+ }
}
}
@@ -36,19 +52,30 @@ class MediaItemBasic(val data: MediaModel)
override fun bindView(holder: ViewHolder, payloads: List<Any>) {
super.bindView(holder, payloads)
glide(holder.itemView)
- .load(data.data)
- .applyMediaOptions(holder.itemView.context)
- .listener(object : RequestListener<Drawable> {
- override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
- holder.image.setImageDrawable(MediaPickerCore.getErrorDrawable(holder.itemView.context))
- return true
- }
-
- override fun onResourceReady(resource: Drawable, model: Any, target: Target<Drawable>, dataSource: DataSource, isFirstResource: Boolean): Boolean {
- return false
- }
- })
- .into(holder.image)
+ .load(data.data)
+ .applyMediaOptions(holder.itemView.context)
+ .listener(object : RequestListener<Drawable> {
+ override fun onLoadFailed(
+ e: GlideException?,
+ model: Any,
+ target: Target<Drawable>,
+ isFirstResource: Boolean
+ ): Boolean {
+ holder.image.setImageDrawable(MediaPickerCore.getErrorDrawable(holder.itemView.context))
+ return true
+ }
+
+ override fun onResourceReady(
+ resource: Drawable,
+ model: Any,
+ target: Target<Drawable>,
+ dataSource: DataSource,
+ isFirstResource: Boolean
+ ): Boolean {
+ return false
+ }
+ })
+ .into(holder.image)
}
override fun unbindView(holder: ViewHolder) {
@@ -59,4 +86,4 @@ class MediaItemBasic(val data: MediaModel)
class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
val image: MeasuredImageView = v.findViewById(R.id.kau_image)
}
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt
index 26736d4..edd6199 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.database.Cursor
@@ -6,41 +21,45 @@ import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import android.provider.MediaStore
-import android.support.annotation.NonNull
+import androidx.annotation.NonNull
import java.io.File
-
/**
* Created by Allan Wang on 2017-07-14.
*/
data class MediaModel(
- val data: String, val mimeType: String, val size: Long, val dateModified: Long, val displayName: String?
+ val data: String,
+ val mimeType: String,
+ val size: Long,
+ val dateModified: Long,
+ val displayName: String?
) : Parcelable {
@Throws(SQLException::class)
constructor(@NonNull cursor: Cursor) : this(
- cursor.getString(0),
- cursor.getString(1) ?: "",
- cursor.getLong(2),
- cursor.getLong(3),
- cursor.getString(4)
+ cursor.getString(0),
+ cursor.getString(1) ?: "",
+ cursor.getLong(2),
+ cursor.getLong(3),
+ cursor.getString(4)
)
constructor(f: File) : this(
- f.absolutePath,
- f.extension, // this isn't a mime type, but it does give some info
- f.length(),
- f.lastModified(),
- f.nameWithoutExtension
+ f.absolutePath,
+ f.extension, // this isn't a mime type, but it does give some info
+ f.length(),
+ f.lastModified(),
+ f.nameWithoutExtension
)
constructor(parcel: Parcel) : this(
- parcel.readString(),
- parcel.readString(),
- parcel.readLong(),
- parcel.readLong(),
- parcel.readString())
+ parcel.readString()!!,
+ parcel.readString()!!,
+ parcel.readLong(),
+ parcel.readLong(),
+ parcel.readString()
+ )
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(this.data)
@@ -67,11 +86,11 @@ data class MediaModel(
companion object CREATOR : Parcelable.Creator<MediaModel> {
val projection = arrayOf(
- MediaStore.MediaColumns.DATA,
- MediaStore.MediaColumns.MIME_TYPE,
- MediaStore.MediaColumns.SIZE,
- MediaStore.MediaColumns.DATE_MODIFIED,
- MediaStore.MediaColumns.DISPLAY_NAME
+ MediaStore.MediaColumns.DATA,
+ MediaStore.MediaColumns.MIME_TYPE,
+ MediaStore.MediaColumns.SIZE,
+ MediaStore.MediaColumns.DATE_MODIFIED,
+ MediaStore.MediaColumns.DISPLAY_NAME
)
override fun createFromParcel(parcel: Parcel): MediaModel {
@@ -82,5 +101,4 @@ data class MediaModel(
return arrayOfNulls(size)
}
}
-
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityBase.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityBase.kt
index 37f2373..5e5d1ed 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityBase.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityBase.kt
@@ -1,16 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.database.Cursor
import android.os.Bundle
-import android.support.design.widget.AppBarLayout
-import android.support.v4.content.Loader
-import android.support.v7.widget.LinearLayoutManager
+import androidx.loader.content.Loader
+import androidx.recyclerview.widget.LinearLayoutManager
import ca.allanwang.kau.adapters.selectedItems
import ca.allanwang.kau.adapters.selectionSize
import ca.allanwang.kau.utils.hideOnDownwardsScroll
import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.toDrawable
import ca.allanwang.kau.utils.toast
+import com.google.android.material.appbar.AppBarLayout
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import kotlinx.android.synthetic.main.kau_activity_image_picker.*
@@ -22,8 +37,8 @@ import kotlinx.android.synthetic.main.kau_activity_image_picker.*
* Having three layered images makes this slightly slower than [MediaPickerActivityOverlayBase]
*/
abstract class MediaPickerActivityBase(
- mediaType: MediaType,
- mediaActions: List<MediaAction> = emptyList()
+ mediaType: MediaType,
+ mediaActions: List<MediaAction> = emptyList()
) : MediaPickerCore<MediaItem>(mediaType, mediaActions) {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -78,19 +93,21 @@ abstract class MediaPickerActivityBase(
private fun setToolbarScrollable(scrollable: Boolean) {
val params = kau_toolbar.layoutParams as AppBarLayout.LayoutParams
if (scrollable)
- params.scrollFlags = AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS or AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
+ params.scrollFlags = AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS or
+ AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
else
params.scrollFlags = 0
}
override fun onLoadFinished(loader: Loader<Cursor>, data: Cursor?) {
super.onLoadFinished(loader, data)
- setToolbarScrollable((kau_recyclerview.layoutManager as LinearLayoutManager)
- .findLastCompletelyVisibleItemPosition() < adapter.adapterItemCount - 1)
+ setToolbarScrollable(
+ (kau_recyclerview.layoutManager as LinearLayoutManager)
+ .findLastCompletelyVisibleItemPosition() < adapter.adapterItemCount - 1
+ )
}
override fun onStatusChange(loaded: Boolean) {
setToolbarScrollable(loaded)
}
-
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityOverlayBase.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityOverlayBase.kt
index 122838b..a7ee63d 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityOverlayBase.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerActivityOverlayBase.kt
@@ -1,8 +1,23 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.os.Build
import android.os.Bundle
-import android.support.annotation.RequiresApi
+import androidx.annotation.RequiresApi
import ca.allanwang.kau.utils.toast
import kotlinx.android.synthetic.main.kau_activity_image_picker_overlay.*
@@ -16,8 +31,8 @@ import kotlinx.android.synthetic.main.kau_activity_image_picker_overlay.*
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
abstract class MediaPickerActivityOverlayBase(
- mediaType: MediaType,
- mediaActions: List<MediaAction> = emptyList()
+ mediaType: MediaType,
+ mediaActions: List<MediaAction> = emptyList()
) : MediaPickerCore<MediaItemBasic>(mediaType, mediaActions) {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -46,4 +61,4 @@ abstract class MediaPickerActivityOverlayBase(
override fun onBackPressed() {
finishAfterTransition()
}
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt
index 50fe7ae..ac43f9f 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.app.Activity
@@ -31,7 +46,8 @@ inline fun <reified T : MediaPickerCore<*>> Activity.kauLaunchMediaPicker(reques
* call under [Activity.onActivityResult]
* and make sure that the requestCode matches first
*/
-fun Activity.kauOnMediaPickerResult(resultCode: Int, data: Intent?) = MediaPickerCore.onMediaPickerResult(resultCode, data)
+fun Activity.kauOnMediaPickerResult(resultCode: Int, data: Intent?) =
+ MediaPickerCore.onMediaPickerResult(resultCode, data)
internal const val LOADER_ID = 42
internal const val MEDIA_PICKER_RESULT = "media_picker_result"
@@ -39,5 +55,8 @@ internal const val MEDIA_PICKER_RESULT = "media_picker_result"
internal const val ANIMATION_DURATION = 200L
internal const val ANIMATION_SCALE = 0.95f
-internal fun <T> RequestBuilder<T>.applyMediaOptions(context: Context) = apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.RESOURCE).centerCrop().override(MediaPickerCore.viewSize(context)))
-
+internal fun <T> RequestBuilder<T>.applyMediaOptions(context: Context) = apply(
+ RequestOptions().diskCacheStrategy(DiskCacheStrategy.RESOURCE).centerCrop().override(
+ MediaPickerCore.viewSize(context)
+ )
+)
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt
index 6e38d14..e6556ab 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.Manifest
@@ -13,11 +28,11 @@ import android.os.Bundle
import android.provider.BaseColumns
import android.provider.DocumentsContract
import android.provider.MediaStore
-import android.support.v4.app.LoaderManager
-import android.support.v4.content.CursorLoader
-import android.support.v4.content.Loader
-import android.support.v7.widget.GridLayoutManager
-import android.support.v7.widget.RecyclerView
+import androidx.loader.app.LoaderManager
+import androidx.loader.content.CursorLoader
+import androidx.loader.content.Loader
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.adapters.fastAdapter
import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
import ca.allanwang.kau.animators.KauAnimator
@@ -34,10 +49,8 @@ import com.mikepenz.fastadapter.adapters.ItemAdapter
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.IIcon
-import org.jetbrains.anko.doAsync
+import kotlinx.coroutines.CancellationException
import java.io.File
-import java.util.concurrent.ExecutionException
-import java.util.concurrent.Future
/**
* Created by Allan Wang on 2017-07-23.
@@ -45,8 +58,8 @@ import java.util.concurrent.Future
* Container for the main logic behind the both pickers
*/
abstract class MediaPickerCore<T : IItem<*, *>>(
- val mediaType: MediaType,
- val mediaActions: List<MediaAction>
+ val mediaType: MediaType,
+ val mediaActions: List<MediaAction>
) : KauBaseActivity(), LoaderManager.LoaderCallbacks<Cursor> {
companion object {
@@ -79,10 +92,10 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
fun getIconDrawable(context: Context, iicon: IIcon, color: Int): Drawable {
val sizePx = MediaPickerCore.computeViewSize(context)
return IconicsDrawable(context, iicon)
- .sizePx(sizePx)
- .backgroundColor(color)
- .paddingPx(sizePx / 3)
- .color(Color.WHITE)
+ .sizePx(sizePx)
+ .backgroundColor(color)
+ .paddingPx(sizePx / 3)
+ .color(Color.WHITE)
}
var accentColor: Int = 0xff666666.toInt()
@@ -106,7 +119,6 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
lateinit var glide: RequestManager
private var hasPreloaded = false
- private var prefetcher: Future<*>? = null
val adapter = ItemAdapter<T>()
@@ -122,7 +134,7 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
fun initializeRecycler(recycler: RecyclerView) {
val adapterHeader = ItemAdapter<MediaActionItem>()
- val fulladapter = fastAdapter(adapterHeader, adapter)
+ val fulladapter = fastAdapter<IItem<*, *>>(adapterHeader, adapter)
adapterHeader.add(mediaActions.map { MediaActionItem(it, mediaType) })
recycler.apply {
val manager = object : GridLayoutManager(context, computeColumnCount(context)) {
@@ -131,7 +143,6 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
}
}
setItemViewCacheSize(CACHE_SIZE)
- isDrawingCacheEnabled = true
layoutManager = manager
adapter = fulladapter
setHasFixedSize(true)
@@ -155,7 +166,7 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
open fun loadItems() {
kauRequestPermissions(Manifest.permission.READ_EXTERNAL_STORAGE) { granted, _ ->
if (granted) {
- supportLoaderManager.initLoader(LOADER_ID, null, this)
+ LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this)
onStatusChange(true)
} else {
toast(R.string.kau_permission_denied)
@@ -180,18 +191,14 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
addItems(models.map { converter(it) })
if (!hasPreloaded && mediaType == MediaType.VIDEO) {
hasPreloaded = true
- prefetcher = doAsync {
- models.subList(0, Math.min(models.size, 50)).map { it.data }.forEach {
- val target = glide.load(it)
- .applyMediaOptions(this@MediaPickerCore)
- .submit()
- try {
- target.get()
- } catch (ignored: InterruptedException) {
- } catch (ignored: ExecutionException) {
- } finally {
- glide.clear(target)
- }
+ val preloads = models.subList(0, Math.min(models.size, 50)).map {
+ glide.load(it.data)
+ .applyMediaOptions(this@MediaPickerCore)
+ .preload()
+ }
+ job.invokeOnCompletion {
+ if (it is CancellationException) {
+ preloads.forEach(glide::clear)
}
}
}
@@ -227,11 +234,6 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
open fun onStatusChange(loaded: Boolean) {}
- override fun onDestroy() {
- prefetcher?.cancel(true)
- super.onDestroy()
- }
-
/**
* Method used to retrieve uri data for API 19+
* See <a href="http://hmkcode.com/android-display-selected-image-and-its-real-path/"></a>
@@ -274,7 +276,7 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
f = File(tempPath)
tempPath = null
} else if (data?.data != null) {
- f = File(data.data.path)
+ f = File(data.data!!.path)
} else {
KL.d { "Media camera no file found" }
return
@@ -291,8 +293,8 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
private fun onPickerResult(data: Intent?) {
val items = mutableListOf<Uri>()
if (data?.data != null) {
- KL.v { "Media picker data uri: ${data.data.path}" }
- items.add(data.data)
+ KL.v { "Media picker data uri: ${data.data!!.path}" }
+ items.add(data.data!!)
} else if (data != null) {
val clip = data.clipData
if (clip != null) {
@@ -314,4 +316,4 @@ abstract class MediaPickerCore<T : IItem<*, *>>(
}
}
}
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaType.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaType.kt
index 0af4c2e..a42095f 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaType.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaType.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.net.Uri
@@ -7,17 +22,23 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
/**
* Created by Allan Wang on 2017-07-30.
*/
-enum class MediaType(val cacheStrategy: DiskCacheStrategy,
- val mimeType: String,
- val captureType: String,
- val contentUri: Uri) {
- IMAGE(DiskCacheStrategy.AUTOMATIC,
- "image/*",
- MediaStore.ACTION_IMAGE_CAPTURE,
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI),
+enum class MediaType(
+ val cacheStrategy: DiskCacheStrategy,
+ val mimeType: String,
+ val captureType: String,
+ val contentUri: Uri
+) {
+ IMAGE(
+ DiskCacheStrategy.AUTOMATIC,
+ "image/*",
+ MediaStore.ACTION_IMAGE_CAPTURE,
+ MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ ),
- VIDEO(DiskCacheStrategy.AUTOMATIC,
- "video/*",
- MediaStore.ACTION_VIDEO_CAPTURE,
- MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
-} \ No newline at end of file
+ VIDEO(
+ DiskCacheStrategy.AUTOMATIC,
+ "video/*",
+ MediaStore.ACTION_VIDEO_CAPTURE,
+ MediaStore.Video.Media.EXTERNAL_CONTENT_URI
+ )
+}
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaUtils.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaUtils.kt
index f37be75..ff6784b 100644
--- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaUtils.kt
+++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaUtils.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.mediapicker
import android.annotation.SuppressLint
@@ -6,13 +21,14 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Environment
-import android.support.v7.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatActivity
import ca.allanwang.kau.utils.buildIsLollipopAndUp
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
-import java.util.*
-
+import java.util.ArrayList
+import java.util.Date
+import java.util.Locale
/**
* Created by Allan Wang on 2017-08-17.
@@ -26,14 +42,17 @@ internal fun Activity.finish(data: ArrayList<MediaModel>) {
else finish()
}
+/**
+ * Creates a folder named [prefix] as well as a new file with the prefix, current time, and extension.
+ */
@Throws(IOException::class)
fun createMediaFile(prefix: String, extension: String): File {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val imageFileName = "${prefix}_${timeStamp}_"
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
- val frostDir = File(storageDir, prefix)
- if (!frostDir.exists()) frostDir.mkdirs()
- return File.createTempFile(imageFileName, extension, frostDir)
+ val prefixDir = File(storageDir, prefix)
+ if (!prefixDir.exists()) prefixDir.mkdirs()
+ return File.createTempFile(imageFileName, extension, prefixDir)
}
@Throws(IOException::class)
@@ -55,4 +74,4 @@ fun Context.scanMedia(f: File) {
val contentUri = Uri.fromFile(f)
mediaScanIntent.data = contentUri
sendBroadcast(mediaScanIntent)
-} \ No newline at end of file
+}
diff --git a/mediapicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml b/mediapicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml
index a0ce301..d7447b0 100644
--- a/mediapicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml
+++ b/mediapicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml
@@ -7,7 +7,7 @@
app:dragDismissDistance="@dimen/kau_drag_dismiss_distance_large"
app:dragDismissScale="0.95">
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/kau_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/mediapicker/src/main/res/layout/kau_activity_image_picker.xml b/mediapicker/src/main/res/layout/kau_activity_image_picker.xml
index 1b46097..c3458cf 100644
--- a/mediapicker/src/main/res/layout/kau_activity_image_picker.xml
+++ b/mediapicker/src/main/res/layout/kau_activity_image_picker.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/kau_coordinator"
android:layout_width="match_parent"
@@ -7,13 +7,13 @@
android:background="?android:colorBackground"
android:fitsSystemWindows="true">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/kau_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/kau_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
@@ -31,17 +31,17 @@
android:paddingStart="@dimen/kau_padding_normal"
android:text="@string/kau_0" />
- </android.support.v7.widget.Toolbar>
+ </androidx.appcompat.widget.Toolbar>
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@+id/kau_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/kau_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -53,4 +53,4 @@
app:layout_anchorGravity="bottom|right|end" />
-</android.support.design.widget.CoordinatorLayout> \ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/mediapicker/src/main/res/values-da-rDK/strings_mediapicker.xml b/mediapicker/src/main/res/values-da-rDK/strings_mediapicker.xml
index d3636d3..6f37f28 100644
--- a/mediapicker/src/main/res/values-da-rDK/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-da-rDK/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Ingen elementer fundet</string>
<string name="kau_no_items_selected">Ingen elementer er valgt</string>
diff --git a/mediapicker/src/main/res/values-de-rDE/strings_mediapicker.xml b/mediapicker/src/main/res/values-de-rDE/strings_mediapicker.xml
index ae441cc..ff49433 100644
--- a/mediapicker/src/main/res/values-de-rDE/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-de-rDE/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Keine Elemente gefunden</string>
<string name="kau_no_items_selected">Keine Datei ausgewählt</string>
diff --git a/mediapicker/src/main/res/values-es-rES/strings_mediapicker.xml b/mediapicker/src/main/res/values-es-rES/strings_mediapicker.xml
index 21da558..72b8903 100644
--- a/mediapicker/src/main/res/values-es-rES/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-es-rES/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">No se encontraron elementos</string>
<string name="kau_no_items_selected">No se han seleccionado elementos</string>
diff --git a/mediapicker/src/main/res/values-fr-rFR/strings_mediapicker.xml b/mediapicker/src/main/res/values-fr-rFR/strings_mediapicker.xml
index 1705e9e..99a68d4 100644
--- a/mediapicker/src/main/res/values-fr-rFR/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-fr-rFR/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Aucun élément trouvé</string>
<string name="kau_no_items_selected">Aucun élément n\'a été sélectionné</string>
diff --git a/mediapicker/src/main/res/values-gl-rES/strings_mediapicker.xml b/mediapicker/src/main/res/values-gl-rES/strings_mediapicker.xml
index 1ad6650..831c96b 100644
--- a/mediapicker/src/main/res/values-gl-rES/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-gl-rES/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Ningún elemento atopado</string>
<string name="kau_no_items_selected">Ningún elemento seleccionado</string>
diff --git a/mediapicker/src/main/res/values-hu-rHU/strings_mediapicker.xml b/mediapicker/src/main/res/values-hu-rHU/strings_mediapicker.xml
index b191d61..30b6a1b 100644
--- a/mediapicker/src/main/res/values-hu-rHU/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-hu-rHU/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Nem található elem</string>
<string name="kau_no_items_selected">Nincs kijelölt elem</string>
diff --git a/mediapicker/src/main/res/values-in-rID/strings_mediapicker.xml b/mediapicker/src/main/res/values-in-rID/strings_mediapicker.xml
index 8f64d74..3980589 100644
--- a/mediapicker/src/main/res/values-in-rID/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-in-rID/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Item tidak ditemukan</string>
<string name="kau_no_items_selected">Tidak ada item yang dipilih</string>
diff --git a/mediapicker/src/main/res/values-it-rIT/strings_mediapicker.xml b/mediapicker/src/main/res/values-it-rIT/strings_mediapicker.xml
index 4b795b1..f712b12 100644
--- a/mediapicker/src/main/res/values-it-rIT/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-it-rIT/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Nessun elemento trovato</string>
<string name="kau_no_items_selected">Non è stato selezionato alcun elemento</string>
diff --git a/mediapicker/src/main/res/values-ko-rKR/strings_mediapicker.xml b/mediapicker/src/main/res/values-ko-rKR/strings_mediapicker.xml
index aab5e63..26793bc 100644
--- a/mediapicker/src/main/res/values-ko-rKR/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-ko-rKR/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">항목이 없습니다.</string>
<string name="kau_no_items_selected">선택된 항목이 없습니다.</string>
diff --git a/mediapicker/src/main/res/values-nl-rNL/strings_mediapicker.xml b/mediapicker/src/main/res/values-nl-rNL/strings_mediapicker.xml
new file mode 100644
index 0000000..daaad70
--- /dev/null
+++ b/mediapicker/src/main/res/values-nl-rNL/strings_mediapicker.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_no_items_found">Geen items gevonden</string>
+ <string name="kau_no_items_selected">Er zijn geen items geselecteerd</string>
+ <string name="kau_no_items_loaded">Er zijn geen items ingeladen</string>
+ <string name="kau_no_camera_found">Geen camera gevonden</string>
+ <string name="kau_no_camera_found_content">Installeer een camera-app en probeer het opnieuw.</string>
+ <string name="kau_temp_file_creation_failed">Kan tijdelijk bestand niet aanmaken.</string>
+ <string name="kau_select_media">Kies een afbeelding of video</string>
+</resources>
diff --git a/mediapicker/src/main/res/values-no-rNO/strings_mediapicker.xml b/mediapicker/src/main/res/values-no-rNO/strings_mediapicker.xml
index 7b251bc..9ee6501 100644
--- a/mediapicker/src/main/res/values-no-rNO/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-no-rNO/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Ingen elementer funnet</string>
<string name="kau_no_items_selected">Ingen elementer har blitt valgt</string>
diff --git a/mediapicker/src/main/res/values-pl-rPL/strings_mediapicker.xml b/mediapicker/src/main/res/values-pl-rPL/strings_mediapicker.xml
index 5aaaae1..7db61f8 100644
--- a/mediapicker/src/main/res/values-pl-rPL/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-pl-rPL/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Brak pozycji</string>
<string name="kau_no_items_selected">Brak wybranych pozycji</string>
diff --git a/mediapicker/src/main/res/values-pt-rBR/strings_mediapicker.xml b/mediapicker/src/main/res/values-pt-rBR/strings_mediapicker.xml
index bac9913..62abec1 100644
--- a/mediapicker/src/main/res/values-pt-rBR/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-pt-rBR/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Nenhum item encontrado</string>
<string name="kau_no_items_selected">Nenhum item foi selecionado</string>
diff --git a/mediapicker/src/main/res/values-pt-rPT/strings_mediapicker.xml b/mediapicker/src/main/res/values-pt-rPT/strings_mediapicker.xml
new file mode 100644
index 0000000..25b8c46
--- /dev/null
+++ b/mediapicker/src/main/res/values-pt-rPT/strings_mediapicker.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_no_items_found">Nenhum item encontrado</string>
+ <string name="kau_no_items_selected">Não foi selecionado nenhum item</string>
+ <string name="kau_no_items_loaded">Nenhum item carregado</string>
+ <string name="kau_no_camera_found">Nenhuma câmara encontrada</string>
+ <string name="kau_no_camera_found_content">Por favor instale um aplicação de câmara e tente novamente.</string>
+ <string name="kau_temp_file_creation_failed">Falha ao criar um ficheiro temporário.</string>
+ <string name="kau_select_media">Selecionar multimédia</string>
+</resources>
diff --git a/mediapicker/src/main/res/values-sr-rSP/strings_mediapicker.xml b/mediapicker/src/main/res/values-sr-rSP/strings_mediapicker.xml
new file mode 100644
index 0000000..abc3933
--- /dev/null
+++ b/mediapicker/src/main/res/values-sr-rSP/strings_mediapicker.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_no_items_found">Није пронађена ниједна ставка</string>
+ <string name="kau_no_items_selected">Ниједна ставка није одабрана</string>
+ <string name="kau_no_items_loaded">Нема учитаних ставки</string>
+ <string name="kau_no_camera_found">Камера није пронађена</string>
+ <string name="kau_no_camera_found_content">Инсталирајте апликацију за камеру и покушајте поново.</string>
+ <string name="kau_temp_file_creation_failed">Креирање привремене датотеке није успело.</string>
+ <string name="kau_select_media">Одаберите мултимедију</string>
+</resources>
diff --git a/mediapicker/src/main/res/values-sv-rSE/strings_mediapicker.xml b/mediapicker/src/main/res/values-sv-rSE/strings_mediapicker.xml
index 15f991f..0909d2f 100644
--- a/mediapicker/src/main/res/values-sv-rSE/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-sv-rSE/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Inga objekt hittades</string>
<string name="kau_no_items_selected">Inga objekt har valts</string>
diff --git a/mediapicker/src/main/res/values-th-rTH/strings_mediapicker.xml b/mediapicker/src/main/res/values-th-rTH/strings_mediapicker.xml
index 3e97c66..83bd30c 100644
--- a/mediapicker/src/main/res/values-th-rTH/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-th-rTH/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">ไม่พบรายการ</string>
<string name="kau_no_items_selected">ยังไม่ได้เลือกรายการ</string>
diff --git a/mediapicker/src/main/res/values-tr-rTR/strings_mediapicker.xml b/mediapicker/src/main/res/values-tr-rTR/strings_mediapicker.xml
index 55e90b4..601432f 100644
--- a/mediapicker/src/main/res/values-tr-rTR/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-tr-rTR/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Hiç bir öge bulunamadı</string>
<string name="kau_no_items_selected">Hiç bir öge seçilmemişti</string>
diff --git a/mediapicker/src/main/res/values-uk-rUA/strings_mediapicker.xml b/mediapicker/src/main/res/values-uk-rUA/strings_mediapicker.xml
index 6dc767e..f8a9725 100644
--- a/mediapicker/src/main/res/values-uk-rUA/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-uk-rUA/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Нічого не знайдено</string>
<string name="kau_no_items_selected">Жодного елементу не обрано</string>
diff --git a/mediapicker/src/main/res/values-vi-rVN/strings_mediapicker.xml b/mediapicker/src/main/res/values-vi-rVN/strings_mediapicker.xml
index dae9f41..9d5fe5d 100644
--- a/mediapicker/src/main/res/values-vi-rVN/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-vi-rVN/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">Không tìm thấy mục nào</string>
<string name="kau_no_items_selected">Chưa chọn mục nào</string>
diff --git a/mediapicker/src/main/res/values-zh-rCN/strings_mediapicker.xml b/mediapicker/src/main/res/values-zh-rCN/strings_mediapicker.xml
index 2be3fc0..b05f922 100644
--- a/mediapicker/src/main/res/values-zh-rCN/strings_mediapicker.xml
+++ b/mediapicker/src/main/res/values-zh-rCN/strings_mediapicker.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--Generated by crowdin.com-->
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
<resources>
<string name="kau_no_items_found">未找到项目</string>
<string name="kau_no_items_selected">没有选择任何项目</string>
diff --git a/mediapicker/src/main/res/values-zh-rTW/strings_mediapicker.xml b/mediapicker/src/main/res/values-zh-rTW/strings_mediapicker.xml
new file mode 100644
index 0000000..1ecb9e0
--- /dev/null
+++ b/mediapicker/src/main/res/values-zh-rTW/strings_mediapicker.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<resources>
+ <string name="kau_no_items_found">什麼也沒有</string>
+ <string name="kau_no_items_selected">什麼也沒選到</string>
+ <string name="kau_no_items_loaded">什麼也沒載入</string>
+ <string name="kau_no_camera_found">找不到相機</string>
+ <string name="kau_no_camera_found_content">請安裝相機應用程式然後重試</string>
+ <string name="kau_temp_file_creation_failed">無法建立暫存檔</string>
+ <string name="kau_select_media">選取媒體</string>
+</resources>
diff --git a/sample/build.gradle b/sample/build.gradle
index d7199a3..bb7cab0 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -4,11 +4,8 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.github.triplet.play'
play {
- jsonFile = file('../files/gplay-keys.json')
+ serviceAccountCredentials = file('../files/gplay-keys.json')
track = 'beta'
- errorOnSizeLimit = true
- uploadImages = false
- untrackOld = true
}
android {
@@ -27,7 +24,7 @@ android {
versionName androidGitVersion.name()
versionCode androidGitVersion.code()
multiDexEnabled true
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
def releaseSigning = file("../files/kau.properties")
@@ -101,6 +98,18 @@ android {
}
}
}
+
+ // See https://github.com/facebook/flipper/issues/146
+ configurations.all {
+ resolutionStrategy.eachDependency { DependencyResolveDetails details ->
+ def requested = details.requested
+ if (requested.group == "com.android.support") {
+ if (!requested.name.startsWith("multidex")) {
+ details.useVersion "26.+"
+ }
+ }
+ }
+ }
}
dependencies {
@@ -113,17 +122,15 @@ dependencies {
implementation project(':searchview')
implementation project(':mediapicker')
-// androidTestImplementation("com.android.support.test.espresso:espresso-core:${kau.espresso}") {
-// exclude group: 'com.android.support', module: 'support-annotations'
-// }
-// androidTestImplementation("com.android.support.test:runner:${kau.testRunner}") {
-// exclude group: 'com.android.support', module: 'support-annotations'
-// }
-// androidTestImplementation kauDependency.kotlinTest
+ implementation "com.afollestad.material-dialogs:input:${kau.materialDialog}"
+
testImplementation kauDependency.kotlinTest
testImplementation kauDependency.junit
androidTestImplementation kauDependency.kotlinTest
androidTestImplementation kauDependency.espresso
+ androidTestImplementation "androidx.test.espresso:espresso-intents:${kau.espresso}"
+ androidTestImplementation "androidx.test.espresso:espresso-contrib:${kau.espresso}"
+ androidTestImplementation kauDependency.testRules
androidTestImplementation kauDependency.testRunner
}
diff --git a/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/ColorPickerTest.kt b/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/ColorPickerTest.kt
index 39aee93..ef53817 100644
--- a/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/ColorPickerTest.kt
+++ b/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/ColorPickerTest.kt
@@ -1,16 +1,31 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
-import android.support.test.espresso.DataInteraction
-import android.support.test.espresso.Espresso.onData
-import android.support.test.espresso.Espresso.onView
-import android.support.test.espresso.ViewAssertion
-import android.support.test.espresso.action.ViewActions.click
-import android.support.test.espresso.matcher.ViewMatchers.withId
-import android.support.test.espresso.matcher.ViewMatchers.withText
-import android.support.test.filters.MediumTest
-import android.support.test.rule.ActivityTestRule
-import android.support.test.runner.AndroidJUnit4
import android.view.View
+import androidx.test.espresso.DataInteraction
+import androidx.test.espresso.Espresso.onData
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.ViewAssertion
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.rule.ActivityTestRule
import ca.allanwang.kau.colorpicker.CircleView
import org.hamcrest.Matchers.anything
import org.junit.Rule
@@ -19,9 +34,10 @@ import org.junit.runner.RunWith
import kotlin.test.assertEquals
import kotlin.test.fail
-
/**
* Created by Allan Wang on 22/02/2018.
+ *
+ * Tests related to the :colorpicker module
*/
@RunWith(AndroidJUnit4::class)
@MediumTest
@@ -31,11 +47,15 @@ class ColorPickerTest {
val activity: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)
private fun DataInteraction.click(position: Int) =
- atPosition(position).perform(click())
+ atPosition(position).perform(click())
private fun View.colorSelected(selected: Boolean) {
val circle = this as? CircleView ?: fail("View is not a CircleView")
- assertEquals(selected, circle.colorSelected, "CircleView ${circle.tag} ${if (selected) "is not" else "is"} actually selected")
+ assertEquals(
+ selected,
+ circle.colorSelected,
+ "CircleView ${circle.tag} ${if (selected) "is not" else "is"} actually selected"
+ )
}
private val colorSelected = ViewAssertion { view, _ -> view.colorSelected(true) }
@@ -43,7 +63,7 @@ class ColorPickerTest {
private val colorNotSelected = ViewAssertion { view, _ -> view.colorSelected(false) }
@Test
- fun test() {
+ fun colorClick() {
onView(withText(R.string.accent_color)).perform(click())
val colors = onData(anything()).inAdapterView(withId(R.id.md_grid))
@@ -51,11 +71,9 @@ class ColorPickerTest {
colors.click(0).check(colorSelected) // click first grid item
colors.atPosition(1).check(colorNotSelected)
colors.atPosition(2).check(colorNotSelected)
- .perform(click()).check(colorSelected)
+ .perform(click()).check(colorSelected)
colors.atPosition(0).check(colorNotSelected)
- .perform(click()).check(colorSelected)
+ .perform(click()).check(colorSelected)
// first item is now selected
}
-
-
}
diff --git a/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/KPrefViewTest.kt b/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/KPrefViewTest.kt
new file mode 100644
index 0000000..72199cf
--- /dev/null
+++ b/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/KPrefViewTest.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ca.allanwang.kau.sample
+
+import android.view.View
+import android.widget.CheckBox
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.ViewInteraction
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.BoundedMatcher
+import androidx.test.espresso.matcher.ViewMatchers.withChild
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.rule.ActivityTestRule
+import org.hamcrest.BaseMatcher
+import org.hamcrest.Description
+import org.hamcrest.Matcher
+import org.hamcrest.Matchers.allOf
+import org.hamcrest.Matchers.instanceOf
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Created by Allan Wang on 21/12/2018.
+ *
+ * Tests related to the :kpref-activity module
+ */
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+class KPrefViewTest {
+
+ @get:Rule
+ val activity: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java)
+
+ fun verifyCheck(checked: Boolean): Matcher<View> {
+ return object : BoundedMatcher<View, View>(View::class.java) {
+
+ override fun describeTo(description: Description) {
+ description.appendText("Checkbox is ${if (checked) "checked" else "not checked"}")
+ }
+
+ override fun matchesSafely(item: View): Boolean =
+ item.findViewById<CheckBox>(R.id.kau_pref_inner_content).isChecked == checked
+ }
+ }
+
+ inline fun <reified T : View> ViewInteraction.checkInnerContent(
+ desc: String,
+ crossinline matcher: (T) -> Boolean
+ ): ViewInteraction {
+ val viewMatcher = object : BaseMatcher<View>() {
+ override fun describeTo(description: Description) {
+ description.appendText(desc)
+ }
+
+ override fun matches(item: Any?): Boolean {
+ val view = item as? View ?: return false
+ val inner = view.findViewById<View>(R.id.kau_pref_inner_content) as? T
+ ?: return false
+ return matcher(inner)
+ }
+ }
+ return check(matches(viewMatcher))
+ }
+
+ fun ViewInteraction.verifyCheck(tag: String, checked: Boolean, enabled: Boolean = true) =
+ checkInnerContent<CheckBox>("$tag should be ${if (checked) "checked" else "not checked"}") {
+ it.isChecked == checked
+ }.check { view, _ ->
+ ((view.alpha == 1f) == enabled)
+ }
+
+ fun onCheckboxView(vararg matchers: Matcher<View>) =
+ onView(allOf(*matchers, withChild(withChild(instanceOf(CheckBox::class.java)))))
+
+ @Test
+ fun basicCheckboxToggle() {
+ val checkbox1 = onCheckboxView(withChild(withText(R.string.checkbox_1)))
+
+ val initiallyChecked = KPrefSample.check1
+
+ checkbox1.verifyCheck("checkbox1 init", initiallyChecked)
+ checkbox1.perform(click())
+ checkbox1.verifyCheck("checkbox1 after click", !initiallyChecked)
+ }
+
+ /**
+ * Note that checkbox3 depends on checkbox2
+ */
+ @Test
+ fun dependentCheckboxToggle() {
+ val checkbox2 = onCheckboxView(withChild(withText(R.string.checkbox_2)))
+ val checkbox3 =
+ onCheckboxView(withChild(withText(R.string.checkbox_3)), withChild(withText(R.string.desc_dependent)))
+
+ // normalize so that both are checked
+ if (!KPrefSample.check2)
+ checkbox2.perform(click())
+ if (!KPrefSample.check3)
+ checkbox3.perform(click())
+
+ checkbox3.verifyCheck("checkbox3 init", true, true)
+ checkbox3.perform(click())
+ checkbox3.verifyCheck("checkbox3 after click", false, true)
+
+ checkbox2.perform(click())
+ checkbox2.verifyCheck("checkbox2 after click", false, true)
+ checkbox3.verifyCheck("checkbox3 after checkbox2 click", false, false)
+
+ checkbox3.perform(click())
+ checkbox3.verifyCheck("checkbox3 after disabled click", false, false)
+ }
+}
diff --git a/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/utils/EspressoUtils.kt b/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/utils/EspressoUtils.kt
new file mode 100644
index 0000000..09ad00a
--- /dev/null
+++ b/sample/src/androidTest/kotlin/ca/allanwang/kau/sample/utils/EspressoUtils.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ca.allanwang.kau.sample.utils
+
+import org.hamcrest.BaseMatcher
+import org.hamcrest.Description
+import org.hamcrest.Matcher
+
+fun <T> index(index: Int, matcher: Matcher<T>): Matcher<T> =
+ object : BaseMatcher<T>() {
+
+ var current = 0
+
+ override fun describeTo(description: Description) {
+ description.appendText("Should return item at index $index")
+ }
+
+ override fun matches(item: Any?): Boolean {
+ println("AA")
+ return matcher.matches(item) && current++ == index
+ }
+ }
+
+fun <T> first(matcher: Matcher<T>): Matcher<T> = index(0, matcher)
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index d8bbe51..5846c6b 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -49,7 +49,7 @@
android:theme="@style/Kau.Translucent.SlideBottom" />
<provider
- android:name="android.support.v4.content.FileProvider"
+ android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/AboutActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/AboutActivity.kt
index 78f31ae..928070e 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/AboutActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/AboutActivity.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import ca.allanwang.kau.about.AboutActivityBase
@@ -24,4 +39,4 @@ class AboutActivity : AboutActivityBase(R.string::class.java, {
descRes = R.string.about_kau
})
}
-} \ No newline at end of file
+}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/AdapterActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/AdapterActivity.kt
index ada60ca..a11a672 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/AdapterActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/AdapterActivity.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import android.os.Bundle
@@ -17,7 +32,8 @@ class AdapterActivity : ElasticRecyclerActivity() {
override fun onCreate(savedInstanceState: Bundle?, configs: Configs): Boolean {
val adapter = ItemAdapter<IItem<*, *>>()
recycler.adapter = fastAdapter(adapter)
- adapter.add(listOf(
+ adapter.add(
+ listOf(
CardIItem {
titleRes = R.string.kau_text_copied
descRes = R.string.kau_lorem_ipsum
@@ -43,8 +59,9 @@ class AdapterActivity : ElasticRecyclerActivity() {
titleRes = R.string.kau_text_copied
button = "Test"
buttonClick = { toast("HI") }
- }))
+ })
+ )
setOutsideTapListener { finishAfterTransition() }
return true
}
-} \ No newline at end of file
+}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
index c0f928f..349e3d1 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import android.os.Bundle
@@ -10,7 +25,11 @@ import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.swipe.SWIPE_EDGE_LEFT
import ca.allanwang.kau.swipe.kauSwipeOnCreate
import ca.allanwang.kau.swipe.kauSwipeOnDestroy
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.fullLinearRecycler
+import ca.allanwang.kau.utils.startActivity
+import ca.allanwang.kau.utils.toast
+import ca.allanwang.kau.utils.withAlpha
+import ca.allanwang.kau.utils.withSlideOut
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
/**
@@ -27,9 +46,9 @@ class AnimActivity : KauBaseActivity() {
setContentView(fullLinearRecycler(adapter).apply { setBackgroundColor(KPrefSample.bgColor.withAlpha(255)) })
adapter.add(listOf(
- PERMISSION_ACCESS_COARSE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_CAMERA
+ PERMISSION_ACCESS_COARSE_LOCATION,
+ PERMISSION_ACCESS_FINE_LOCATION,
+ PERMISSION_CAMERA
).map { PermissionCheckbox(it) })
adapter.withOnClickListener { _, _, item, _ ->
KL.d { "Perm Click" }
@@ -54,5 +73,4 @@ class AnimActivity : KauBaseActivity() {
withSlideOut(this@AnimActivity)
})
}
-
-} \ No newline at end of file
+}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt
index 0c243e4..0f20880 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/KPrefSample.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import android.graphics.Color
@@ -8,7 +23,7 @@ import ca.allanwang.kau.kpref.kpref
* Created by Allan Wang on 2017-06-07.
*/
object KPrefSample : KPref() {
- var version: Int by kpref("version", -1)
+ var version: Int by kpref("version", -1)
var textColor: Int by kpref("TEXT_COLOR", Color.WHITE)
var accentColor: Int by kpref("ACCENT_COLOR", 0xffff8900.toInt())
var bgColor: Int by kpref("BG_COLOR", 0xff303030.toInt())
@@ -19,5 +34,4 @@ object KPrefSample : KPref() {
var seekbar: Int by kpref("seekbar", 20)
var time12: Int by kpref("time_12", 315)
var time24: Int by kpref("time_24", 2220)
-
-} \ No newline at end of file
+}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
index 6cd9776..d9586c4 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
@@ -1,11 +1,25 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
-import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
-import ca.allanwang.kau.about.AboutActivityBase
+import ca.allanwang.kau.about.kauLaunchAbout
import ca.allanwang.kau.email.sendEmail
import ca.allanwang.kau.kpref.activity.CoreAttributeContract
import ca.allanwang.kau.kpref.activity.KPrefActivity
@@ -17,11 +31,16 @@ import ca.allanwang.kau.searchview.SearchView
import ca.allanwang.kau.searchview.bindSearchView
import ca.allanwang.kau.swipe.SWIPE_EDGE_LEFT
import ca.allanwang.kau.ui.views.RippleCanvas
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.materialDialog
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.startActivity
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.toast
+import ca.allanwang.kau.utils.withSceneTransitionAnimation
import ca.allanwang.kau.xml.showChangelog
+import com.afollestad.materialdialogs.input.input
import com.mikepenz.google_material_typeface_library.GoogleMaterial
-
class MainActivity : KPrefActivity() {
var searchView: SearchView? = null
@@ -30,51 +49,53 @@ class MainActivity : KPrefActivity() {
//some of the most common english words for show
val wordBank: List<String> by lazy {
- listOf("the", "name", "of", "very", "to", "through",
- "and", "just", "a", "form", "in", "much", "is", "great", "it", "think", "you", "say",
- "that", "help", "he", "low", "was", "line", "for", "before", "on", "turn", "are", "cause",
- "with", "same", "as", "mean", "I", "differ", "his", "move", "they", "right", "be", "boy",
- "at", "old", "one", "too", "have", "does", "this", "tell", "from", "sentence", "or", "set",
- "had", "three", "by", "want", "hot", "air", "but", "well", "some", "also", "what", "play",
- "there", "small", "we", "end", "can", "put", "out", "home", "other", "read", "were", "hand",
- "all", "port", "your", "large", "when", "spell", "up", "add", "use", "even", "word", "land",
- "how", "here", "said", "must", "an", "big", "each", "high", "she", "such", "which", "follow",
- "do", "act", "their", "why", "time", "ask", "if", "men", "will", "change", "way", "went",
- "about", "light", "many", "kind", "then", "off", "them", "need", "would", "house", "write",
- "picture", "like", "try", "so", "us", "these", "again", "her", "animal", "long", "point",
- "make", "mother", "thing", "world", "see", "near", "him", "build", "two", "self", "has",
- "earth", "look", "father", "more", "head", "day", "stand", "could", "own", "go", "page",
- "come", "should", "did", "country", "my", "found", "sound", "answer", "no", "school", "most",
- "grow", "number", "study", "who", "still", "over", "learn", "know", "plant", "water", "cover",
- "than", "food", "call", "sun", "first", "four", "people", "thought", "may", "let", "down", "keep",
- "side", "eye", "been", "never", "now", "last", "find", "door", "any", "between", "new", "city",
- "work", "tree", "part", "cross", "take", "since", "get", "hard", "place", "start", "made",
- "might", "live", "story", "where", "saw", "after", "far", "back", "sea", "little", "draw",
- "only", "left", "round", "late", "man", "run", "year", "don't", "came", "while", "show",
- "press", "every", "close", "good", "night", "me", "real", "give", "life", "our", "few", "under",
- "stopRankWordRankWord", "open", "ten", "seem", "simple", "together", "several", "next",
- "vowel", "white", "toward", "children", "war", "begin", "lay", "got", "against", "walk", "pattern",
- "example", "slow", "ease", "center", "paper", "love", "often", "person", "always", "money",
- "music", "serve", "those", "appear", "both", "road", "mark", "map", "book", "science", "letter",
- "rule", "until", "govern", "mile", "pull", "river", "cold", "car", "notice", "feet", "voice",
- "care", "fall", "second", "power", "group", "town", "carry", "fine", "took", "certain", "rain",
- "fly", "eat", "unit", "room", "lead", "friend", "cry", "began", "dark", "idea", "machine",
- "fish", "note", "mountain", "wait", "north", "plan", "once", "figure", "base", "star", "hear",
- "box", "horse", "noun", "cut", "field", "sure", "rest", "watch", "correct", "color", "able",
- "face", "pound", "wood", "done", "main", "beauty", "enough", "drive", "plain", "stood", "girl",
- "contain", "usual", "front", "young", "teach", "ready", "week", "above", "final", "ever", "gave",
- "red", "green", "list", "oh", "though", "quick", "feel", "develop", "talk", "sleep", "bird",
- "warm", "soon", "free", "body", "minute", "dog", "strong", "family", "special", "direct", "mind",
- "pose", "behind", "leave", "clear", "song", "tail", "measure", "produce", "state", "fact", "product",
- "street", "black", "inch", "short", "lot", "numeral", "nothing", "class", "course", "wind", "stay",
- "question", "wheel", "happen", "full", "complete", "force", "ship", "blue", "area", "object", "half",
- "decide", "rock", "surface", "order", "deep", "fire", "moon", "south", "island", "problem", "foot",
- "piece", "yet", "told", "busy", "knew", "test", "pass", "record", "farm", "boat", "top", "common",
- "whole", "gold", "king", "possible", "size", "plane", "heard", "age", "best", "dry", "hour", "wonder",
- "better", "laugh", "true.", "thousand", "during", "ago", "hundred", "ran", "am", "check", "remember",
- "game", "step", "shape", "early", "yes", "hold", "hot", "west", "miss", "ground", "brought", "interest",
- "heat", "reach", "snow", "fast", "bed", "five", "bring", "sing", "sit", "listen", "perhaps", "six",
- "fill", "table", "east", "travel", "weight", "less", "language", "morning", "among")
+ listOf(
+ "the", "name", "of", "very", "to", "through",
+ "and", "just", "a", "form", "in", "much", "is", "great", "it", "think", "you", "say",
+ "that", "help", "he", "low", "was", "line", "for", "before", "on", "turn", "are", "cause",
+ "with", "same", "as", "mean", "I", "differ", "his", "move", "they", "right", "be", "boy",
+ "at", "old", "one", "too", "have", "does", "this", "tell", "from", "sentence", "or", "set",
+ "had", "three", "by", "want", "hot", "air", "but", "well", "some", "also", "what", "play",
+ "there", "small", "we", "end", "can", "put", "out", "home", "other", "read", "were", "hand",
+ "all", "port", "your", "large", "when", "spell", "up", "add", "use", "even", "word", "land",
+ "how", "here", "said", "must", "an", "big", "each", "high", "she", "such", "which", "follow",
+ "do", "act", "their", "why", "time", "ask", "if", "men", "will", "change", "way", "went",
+ "about", "light", "many", "kind", "then", "off", "them", "need", "would", "house", "write",
+ "picture", "like", "try", "so", "us", "these", "again", "her", "animal", "long", "point",
+ "make", "mother", "thing", "world", "see", "near", "him", "build", "two", "self", "has",
+ "earth", "look", "father", "more", "head", "day", "stand", "could", "own", "go", "page",
+ "come", "should", "did", "country", "my", "found", "sound", "answer", "no", "school", "most",
+ "grow", "number", "study", "who", "still", "over", "learn", "know", "plant", "water", "cover",
+ "than", "food", "call", "sun", "first", "four", "people", "thought", "may", "let", "down", "keep",
+ "side", "eye", "been", "never", "now", "last", "find", "door", "any", "between", "new", "city",
+ "work", "tree", "part", "cross", "take", "since", "get", "hard", "place", "start", "made",
+ "might", "live", "story", "where", "saw", "after", "far", "back", "sea", "little", "draw",
+ "only", "left", "round", "late", "man", "run", "year", "don't", "came", "while", "show",
+ "press", "every", "close", "good", "night", "me", "real", "give", "life", "our", "few", "under",
+ "stopRankWordRankWord", "open", "ten", "seem", "simple", "together", "several", "next",
+ "vowel", "white", "toward", "children", "war", "begin", "lay", "got", "against", "walk", "pattern",
+ "example", "slow", "ease", "center", "paper", "love", "often", "person", "always", "money",
+ "music", "serve", "those", "appear", "both", "road", "mark", "map", "book", "science", "letter",
+ "rule", "until", "govern", "mile", "pull", "river", "cold", "car", "notice", "feet", "voice",
+ "care", "fall", "second", "power", "group", "town", "carry", "fine", "took", "certain", "rain",
+ "fly", "eat", "unit", "room", "lead", "friend", "cry", "began", "dark", "idea", "machine",
+ "fish", "note", "mountain", "wait", "north", "plan", "once", "figure", "base", "star", "hear",
+ "box", "horse", "noun", "cut", "field", "sure", "rest", "watch", "correct", "color", "able",
+ "face", "pound", "wood", "done", "main", "beauty", "enough", "drive", "plain", "stood", "girl",
+ "contain", "usual", "front", "young", "teach", "ready", "week", "above", "final", "ever", "gave",
+ "red", "green", "list", "oh", "though", "quick", "feel", "develop", "talk", "sleep", "bird",
+ "warm", "soon", "free", "body", "minute", "dog", "strong", "family", "special", "direct", "mind",
+ "pose", "behind", "leave", "clear", "song", "tail", "measure", "produce", "state", "fact", "product",
+ "street", "black", "inch", "short", "lot", "numeral", "nothing", "class", "course", "wind", "stay",
+ "question", "wheel", "happen", "full", "complete", "force", "ship", "blue", "area", "object", "half",
+ "decide", "rock", "surface", "order", "deep", "fire", "moon", "south", "island", "problem", "foot",
+ "piece", "yet", "told", "busy", "knew", "test", "pass", "record", "farm", "boat", "top", "common",
+ "whole", "gold", "king", "possible", "size", "plane", "heard", "age", "best", "dry", "hour", "wonder",
+ "better", "laugh", "true.", "thousand", "during", "ago", "hundred", "ran", "am", "check", "remember",
+ "game", "step", "shape", "early", "yes", "hold", "hot", "west", "miss", "ground", "brought", "interest",
+ "heat", "reach", "snow", "fast", "bed", "five", "bring", "sing", "sit", "listen", "perhaps", "six",
+ "fill", "table", "east", "travel", "weight", "less", "language", "morning", "among"
+ )
}
const val REQUEST_MEDIA = 27
@@ -93,14 +114,17 @@ class MainActivity : KPrefActivity() {
* This is how the setup looks like with all the proper tags
*/
checkbox(title = R.string.checkbox_1, getter = KPrefSample::check1, setter = { KPrefSample.check1 = it },
- builder = {
- descRes = R.string.desc
- })
+ builder = {
+ descRes = R.string.desc
+ })
/**
* Since we know the order, we may omit the tags
*/
- checkbox(R.string.checkbox_2, KPrefSample::check2, { KPrefSample.check2 = it; reloadByTitle(R.string.checkbox_3) })
+ checkbox(
+ R.string.checkbox_2,
+ KPrefSample::check2,
+ { KPrefSample.check2 = it; reloadByTitle(R.string.checkbox_3) })
/**
* Since the builder is the last argument and is a lambda, we may write the setup cleanly like so:
@@ -139,11 +163,11 @@ class MainActivity : KPrefActivity() {
descRes = R.string.text_desc
onClick = {
itemView.context.materialDialog {
- title("Type Text")
- input("Type here", item.pref, { _, input -> item.pref = input.toString() })
- inputRange(0, 20)
+ title(text = "Type Text")
+ input("Type here", prefill = item.pref, maxLength = 20, allowEmpty = true) { _, input ->
+ item.pref = input.toString()
+ }
}
-
}
}
@@ -189,7 +213,10 @@ class MainActivity : KPrefActivity() {
* Showcases a little trick. The id for reloading is [R.string.checkbox_2],
* but the title displayed is still [R.string.checkbox_3]
*/
- checkbox(R.string.checkbox_2, KPrefSample::check2, { KPrefSample.check2 = it; reloadByTitle(R.string.checkbox_3) }) {
+ checkbox(
+ R.string.checkbox_2,
+ KPrefSample::check2,
+ { KPrefSample.check2 = it; reloadByTitle(R.string.checkbox_3) }) {
titleFun = { R.string.checkbox_3 }
descRes = R.string.kau_lorem_ipsum
}
@@ -208,7 +235,6 @@ class MainActivity : KPrefActivity() {
descRes = R.string.time_desc_24
use24HourFormat = true
}
-
}
fun subPrefs(): KPrefAdapterBuilder.() -> Unit = {
@@ -216,12 +242,11 @@ class MainActivity : KPrefActivity() {
descRes = R.string.text_desc
onClick = {
itemView.context.materialDialog {
- title("Type Text")
- input("Type here", item.pref, { _, input ->
+ title(text = "Type Text")
+ input("Type here", prefill = item.pref, maxLength = 20, allowEmpty = true) { _, input ->
item.pref = input.toString()
reloadSelf()
- })
- inputRange(0, 20)
+ }
}
}
}
@@ -236,9 +261,10 @@ class MainActivity : KPrefActivity() {
KPrefSample.version = BuildConfig.VERSION_CODE
if (!BuildConfig.DEBUG)
showChangelog(R.xml.kau_changelog, KPrefSample.textColor) {
- titleColor(KPrefSample.textColor)
- backgroundColor(KPrefSample.bgColor)
- positiveColor(KPrefSample.accentColor)
+ // TODO MD Color
+// titleColor(KPrefSample.textColor)
+// backgroundColor(KPrefSample.bgColor)
+// positiveColor(KPrefSample.accentColor)
}
}
supportActionBar?.apply {
@@ -273,9 +299,10 @@ class MainActivity : KPrefActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_changelog -> showChangelog(R.xml.kau_changelog, KPrefSample.textColor) {
- titleColor(KPrefSample.textColor)
- backgroundColor(KPrefSample.bgColor)
- positiveColor(KPrefSample.accentColor)
+ // TODO MD Color
+// titleColor(KPrefSample.textColor)
+// backgroundColor(KPrefSample.bgColor)
+// positiveColor(KPrefSample.accentColor)
}
R.id.action_settings -> startActivity<AnimActivity>()
R.id.action_email -> sendEmail(R.string.your_email, R.string.your_subject)
@@ -295,8 +322,3 @@ class MainActivity : KPrefActivity() {
}
}
}
-
-inline fun <reified T : AboutActivityBase> Context.kauLaunchAbout() =
- startActivity<T>(bundleBuilder = {
- withSceneTransitionAnimation(this@kauLaunchAbout)
- }) \ No newline at end of file
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/MediaPicker.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/MediaPicker.kt
index 42de62c..0e6b22f 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MediaPicker.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MediaPicker.kt
@@ -1,9 +1,29 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import android.content.Context
import android.net.Uri
-import android.support.v4.content.FileProvider
-import ca.allanwang.kau.mediapicker.*
+import androidx.core.content.FileProvider
+import ca.allanwang.kau.mediapicker.MediaActionCamera
+import ca.allanwang.kau.mediapicker.MediaActionGallery
+import ca.allanwang.kau.mediapicker.MediaPickerActivityBase
+import ca.allanwang.kau.mediapicker.MediaPickerActivityOverlayBase
+import ca.allanwang.kau.mediapicker.MediaType
+import ca.allanwang.kau.mediapicker.createMediaFile
import java.io.File
/**
@@ -13,8 +33,8 @@ private fun actions(multiple: Boolean) = listOf(object : MediaActionCamera() {
override fun createFile(context: Context): File = createMediaFile("KAU", ".jpg")
- override fun createUri(context: Context, file: File): Uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
-
+ override fun createUri(context: Context, file: File): Uri =
+ FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
}, MediaActionGallery(multiple))
class ImagePickerActivity : MediaPickerActivityBase(MediaType.IMAGE, actions(true))
@@ -23,4 +43,4 @@ class ImagePickerActivityOverlay : MediaPickerActivityOverlayBase(MediaType.IMAG
class VideoPickerActivity : MediaPickerActivityBase(MediaType.VIDEO, actions(true))
-class VideoPickerActivityOverlay : MediaPickerActivityOverlayBase(MediaType.VIDEO, actions(false)) \ No newline at end of file
+class VideoPickerActivityOverlay : MediaPickerActivityOverlayBase(MediaType.VIDEO, actions(false))
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/PermissionCheckbox.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/PermissionCheckbox.kt
index beb1a29..025179d 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/PermissionCheckbox.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/PermissionCheckbox.kt
@@ -1,9 +1,24 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
-import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.CheckBox
import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.iitems.KauIItem
import ca.allanwang.kau.utils.hasPermission
@@ -11,7 +26,7 @@ import ca.allanwang.kau.utils.hasPermission
* Created by Allan Wang on 2017-07-03.
*/
class PermissionCheckbox(val permission: String) : KauIItem<PermissionCheckbox, PermissionCheckbox.ViewHolder>(
- R.layout.permission_checkbox, { ViewHolder(it) }) {
+ R.layout.permission_checkbox, { ViewHolder(it) }) {
override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) {
super.bindView(holder, payloads)
@@ -25,4 +40,4 @@ class PermissionCheckbox(val permission: String) : KauIItem<PermissionCheckbox,
val text: TextView = v.findViewById(R.id.perm_text)
val checkbox: CheckBox = v.findViewById(R.id.perm_checkbox)
}
-} \ No newline at end of file
+}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/SampleApp.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/SampleApp.kt
index 6060245..6e6d718 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/SampleApp.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/SampleApp.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import android.app.Application
@@ -10,4 +25,4 @@ class SampleApp : Application() {
super.onCreate()
KPrefSample.initialize(this, "pref_sample")
}
-} \ No newline at end of file
+}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/SwipeActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/SwipeActivity.kt
index 4197b6d..5107e18 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/SwipeActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/SwipeActivity.kt
@@ -1,10 +1,35 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.sample
import android.app.Activity
import android.os.Bundle
import ca.allanwang.kau.internal.KauBaseActivity
-import ca.allanwang.kau.swipe.*
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.swipe.SWIPE_EDGE_BOTTOM
+import ca.allanwang.kau.swipe.SWIPE_EDGE_LEFT
+import ca.allanwang.kau.swipe.SWIPE_EDGE_RIGHT
+import ca.allanwang.kau.swipe.SWIPE_EDGE_TOP
+import ca.allanwang.kau.swipe.kauSwipeFinish
+import ca.allanwang.kau.swipe.kauSwipeOnCreate
+import ca.allanwang.kau.swipe.kauSwipeOnDestroy
+import ca.allanwang.kau.utils.darken
+import ca.allanwang.kau.utils.navigationBarColor
+import ca.allanwang.kau.utils.rndColor
+import ca.allanwang.kau.utils.startActivity
+import ca.allanwang.kau.utils.statusBarColor
import kotlinx.android.synthetic.main.activity_swipe.*
/**
@@ -24,8 +49,8 @@ class SwipeActivity : KauBaseActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_swipe)
listOf(swipe_from_left, swipe_from_right, swipe_from_top, swipe_from_bottom)
- .zip(listOf(SWIPE_EDGE_LEFT, SWIPE_EDGE_RIGHT, SWIPE_EDGE_TOP, SWIPE_EDGE_BOTTOM))
- .forEach { (button, edge) -> button.setOnClickListener { startActivityWithEdge(edge) } }
+ .zip(listOf(SWIPE_EDGE_LEFT, SWIPE_EDGE_RIGHT, SWIPE_EDGE_TOP, SWIPE_EDGE_BOTTOM))
+ .forEach { (button, edge) -> button.setOnClickListener { startActivityWithEdge(edge) } }
val flag = intent.getIntExtra(SWIPE_EDGE, -1)
swipe_toolbar.title = when (flag) {
SWIPE_EDGE_LEFT -> "Left Edge Swipe"
@@ -54,4 +79,4 @@ class SwipeActivity : KauBaseActivity() {
override fun onBackPressed() {
kauSwipeFinish()
}
-} \ No newline at end of file
+}
diff --git a/sample/src/main/res/layout/activity_swipe.xml b/sample/src/main/res/layout/activity_swipe.xml
index c65bebc..dd52325 100644
--- a/sample/src/main/res/layout/activity_swipe.xml
+++ b/sample/src/main/res/layout/activity_swipe.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipe_container"
@@ -8,7 +8,7 @@
tools:context=".SwipeActivity"
tools:ignore="HardcodedText">
- <android.support.v7.widget.Toolbar
+ <androidx.appcompat.widget.Toolbar
android:id="@+id/swipe_toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
@@ -71,4 +71,4 @@
app:layout_constraintVertical_bias="0.75" />
-</android.support.constraint.ConstraintLayout> \ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml
index f6ec799..53265d0 100644
--- a/sample/src/main/res/xml/kau_changelog.xml
+++ b/sample/src/main/res/xml/kau_changelog.xml
@@ -6,6 +6,36 @@
<item text="" />
-->
+ <version title="v5.0.0" />
+ <item text=":core: Update Material Dialogs to 3.x" />
+ <item text=":colorpicker: Strip down to just the interface; unless you require the accent palette, it may be fine to just use MD's color extension" />
+ <item text="" />
+ <item text="" />
+ <item text="" />
+ <item text="" />
+
+ <version title="v4.1.0" />
+ <item text=":core: Deprecate NetworkUtils, as the underlying functions are deprecated" />
+ <item text=":core: Permission manager no longer synchronized, as all actions should occur in the main thread" />
+ <item text=":kpref-activity: Getter and setter now have action context, with the option to reload self" />
+ <item text="" />
+
+ <version title="v4.0.0" />
+ <item text="Update translations" />
+
+ <version title="v4.0.0-alpha02" />
+ <item text="Update translations" />
+ <item text=":core: Remove anko dependency. Methods that used it now use coroutines; see the migration doc for minor changes" />
+ <item text=":core: Add default CoroutineScope implementation to KauBaseActivity" />
+ <item text=":core: Remove zip class. Coroutines and join can be used as an alternative" />
+ <item text=":core: Delete flyweight implementation. Kotlin already has getOrPut" />
+ <item text=":core: Introduce ContextHelper, where you can get the default looper, handler, and dispatcher for Android" />
+ <item text=":mediapicker: Use video preloading instead of full async loading" />
+
+ <version title="v4.0.0-alpha01" />
+ <item text="Migrate to androidx. See migration for external dependency changes." />
+ <item text=":core: Remove deprecation warning for Kotterknife" />
+
<version title="v3.8.0" />
<item text="Update everything to Android Studio 3.1" />
<item text="Fix new lint issues (see Migration for resource related methods)" />
@@ -13,7 +43,6 @@
<item text=":core: Deprecate Kotterknife; use kotlin_android_extensions" />
<item text=":kpref-activity: Fix seekbar increment" />
<item text=":core: Make KPref use Set&lt;String&gt; vs StringSet" />
- <item text="" />
<version title="v3.7.1" />
<item text="Update appcompat to 27.1.0" />
diff --git a/searchview/README.md b/searchview/README.md
index 37d059a..4d6f010 100644
--- a/searchview/README.md
+++ b/searchview/README.md
@@ -9,4 +9,4 @@ The searchview is:
* Fully themable - set the foreground or background color to style every portion, from text colors to backgrounds to ripples
* Complete - binding the search view to a menu id will set the menu icon (if not previously set) and attach all the necessary listeners
* Configurable - modify any portion of the inner Config class when binding the search view
-* Debouncable - specify a time interval to throttle your queries; see [debouncing](/core#debounce) \ No newline at end of file
+* Debouncable - specify a time interval to throttle your queries; see [debouncing](../core#debounce)
diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt
index 0ae856a..7d754c8 100644
--- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt
+++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchItem.kt
@@ -1,17 +1,36 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.searchview
import android.graphics.Typeface
import android.graphics.drawable.Drawable
-import android.support.constraint.ConstraintLayout
-import android.support.v7.widget.RecyclerView
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.StyleSpan
import android.view.View
import android.widget.ImageView
import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.recyclerview.widget.RecyclerView
import ca.allanwang.kau.iitems.KauIItem
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.adjustAlpha
+import ca.allanwang.kau.utils.gone
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.setRippleBackground
+import ca.allanwang.kau.utils.visible
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.typeface.IIcon
@@ -22,15 +41,16 @@ import com.mikepenz.iconics.typeface.IIcon
* Contains a [key] which acts as a unique identifier (eg url)
* and a [content] which is displayed in the item
*/
-class SearchItem(val key: String,
- val content: String = key,
- val description: String? = null,
- val iicon: IIcon? = GoogleMaterial.Icon.gmd_search,
- val image: Drawable? = null
+class SearchItem(
+ val key: String,
+ val content: String = key,
+ val description: String? = null,
+ val iicon: IIcon? = GoogleMaterial.Icon.gmd_search,
+ val image: Drawable? = null
) : KauIItem<SearchItem, SearchItem.ViewHolder>(
- R.layout.kau_search_iitem,
- { ViewHolder(it) },
- R.id.kau_item_search
+ R.layout.kau_search_iitem,
+ { ViewHolder(it) },
+ R.id.kau_item_search
) {
companion object {
@@ -48,7 +68,12 @@ class SearchItem(val key: String,
val index = content.indexOf(subText, ignoreCase = true)
if (index == -1) return
styledContent = SpannableStringBuilder(content)
- styledContent!!.setSpan(StyleSpan(Typeface.BOLD), index, index + subText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
+ styledContent!!.setSpan(
+ StyleSpan(Typeface.BOLD),
+ index,
+ index + subText.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
}
override fun bindView(holder: ViewHolder, payloads: MutableList<Any>) {
@@ -77,4 +102,4 @@ class SearchItem(val key: String,
val desc: TextView = v.findViewById(R.id.kau_search_desc)
val container: ConstraintLayout = v.findViewById(R.id.kau_search_item_frame)
}
-} \ No newline at end of file
+}
diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt
index d223ec4..169e914 100644
--- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt
+++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchView.kt
@@ -1,33 +1,71 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.searchview
import android.app.Activity
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
-import android.support.annotation.ColorInt
-import android.support.annotation.IdRes
-import android.support.transition.ChangeBounds
-import android.support.transition.TransitionManager
-import android.support.transition.TransitionSet
-import android.support.v7.widget.RecyclerView
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
-import android.view.*
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver
import android.view.inputmethod.EditorInfo
import android.widget.FrameLayout
import android.widget.ImageView
+import androidx.annotation.ColorInt
+import androidx.annotation.IdRes
+import androidx.recyclerview.widget.RecyclerView
+import androidx.transition.ChangeBounds
+import androidx.transition.TransitionManager
+import androidx.transition.TransitionSet
import ca.allanwang.kau.kotlin.Debouncer2
import ca.allanwang.kau.kotlin.debounce
import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.searchview.SearchView.Configs
-import ca.allanwang.kau.utils.*
+import ca.allanwang.kau.utils.INVALID_ID
+import ca.allanwang.kau.utils.addEndListener
+import ca.allanwang.kau.utils.adjustAlpha
+import ca.allanwang.kau.utils.circularHide
+import ca.allanwang.kau.utils.circularReveal
+import ca.allanwang.kau.utils.fadeIn
+import ca.allanwang.kau.utils.fadeOut
+import ca.allanwang.kau.utils.gone
+import ca.allanwang.kau.utils.goneIf
+import ca.allanwang.kau.utils.hideKeyboard
+import ca.allanwang.kau.utils.invisibleIf
+import ca.allanwang.kau.utils.isVisible
+import ca.allanwang.kau.utils.parentViewGroup
+import ca.allanwang.kau.utils.runOnUiThread
+import ca.allanwang.kau.utils.setIcon
+import ca.allanwang.kau.utils.setMarginTop
+import ca.allanwang.kau.utils.showKeyboard
+import ca.allanwang.kau.utils.string
+import ca.allanwang.kau.utils.tint
+import ca.allanwang.kau.utils.toDrawable
+import ca.allanwang.kau.utils.visible
+import ca.allanwang.kau.utils.withLinearAdapter
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.typeface.IIcon
import kotlinx.android.synthetic.main.kau_search_view.view.*
-import org.jetbrains.anko.runOnUiThread
-
/**
* Created by Allan Wang on 2017-06-23.
@@ -41,7 +79,9 @@ import org.jetbrains.anko.runOnUiThread
* https://github.com/lapism/SearchView
*/
class SearchView @JvmOverloads constructor(
- context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
/**
@@ -162,13 +202,15 @@ class SearchView @JvmOverloads constructor(
* Click event for suggestion items
* This event is only triggered when [key] is not blank (like in [noResultsFound]
*/
- var onItemClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit = { _, _, _, _ -> }
+ var onItemClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit =
+ { _, _, _, _ -> }
/**
* Long click event for suggestion items
* This event is only triggered when [key] is not blank (like in [noResultsFound]
*/
- var onItemLongClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit = { _, _, _, _ -> }
+ var onItemLongClick: (position: Int, key: String, content: String, searchView: SearchView) -> Unit =
+ { _, _, _, _ -> }
/**
* If a [SearchItem]'s title contains the submitted query, make that portion bold
@@ -229,7 +271,8 @@ class SearchView @JvmOverloads constructor(
private val configs = Configs()
// views
- private var textCallback: Debouncer2<String, SearchView> = debounce(0) { query, _ -> KL.d { "Search query $query found; set your own textCallback" } }
+ private var textCallback: Debouncer2<String, SearchView> =
+ debounce(0) { query, _ -> KL.d { "Search query $query found; set your own textCallback" } }
private val adapter = FastItemAdapter<SearchItem>()
private var menuItem: MenuItem? = null
val isOpen: Boolean
@@ -274,7 +317,12 @@ class SearchView @JvmOverloads constructor(
if (item.key.isNotBlank()) configs.onItemClick(position, item.key, item.content, this@SearchView); true
}
withOnLongClickListener { _, _, item, position ->
- if (item.key.isNotBlank()) configs.onItemLongClick(position, item.key, item.content, this@SearchView); true
+ if (item.key.isNotBlank()) configs.onItemLongClick(
+ position,
+ item.key,
+ item.content,
+ this@SearchView
+ ); true
}
}
kau_search_edit_text.addTextChangedListener(object : TextWatcher {
@@ -293,8 +341,11 @@ class SearchView @JvmOverloads constructor(
})
kau_search_edit_text.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
- if (configs.searchCallback(kau_search_edit_text.text?.toString()
- ?: "", this)) revealClose()
+ if (configs.searchCallback(
+ kau_search_edit_text.text?.toString()
+ ?: "", this
+ )
+ ) revealClose()
else kau_search_edit_text.hideKeyboard()
return@setOnEditorActionListener true
}
@@ -309,12 +360,12 @@ class SearchView @JvmOverloads constructor(
internal fun cardTransition(builder: TransitionSet.() -> Unit = {}) {
TransitionManager.beginDelayedTransition(kau_search_cardview,
- //we are only using change bounds, as the recyclerview items may be animated as well,
- //which causes a measure IllegalStateException
- TransitionSet().addTransition(ChangeBounds()).apply {
- duration = configs.transitionDuration
- builder()
- })
+ //we are only using change bounds, as the recyclerview items may be animated as well,
+ //which causes a measure IllegalStateException
+ TransitionSet().addTransition(ChangeBounds()).apply {
+ duration = configs.transitionDuration
+ builder()
+ })
}
/**
@@ -330,10 +381,15 @@ class SearchView @JvmOverloads constructor(
* This is assuming that SearchView has already been added to a ViewGroup
* If not, see the extension function [bindSearchView]
*/
- fun bind(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: Int = Color.WHITE, config: Configs.() -> Unit = {}): SearchView {
+ fun bind(
+ menu: Menu,
+ @IdRes id: Int,
+ @ColorInt menuIconColor: Int = Color.WHITE,
+ config: Configs.() -> Unit = {}
+ ): SearchView {
config(config)
val menuItem = menu.findItem(id)
- ?: throw IllegalArgumentException("Menu item with given id doesn't exist")
+ ?: throw IllegalArgumentException("Menu item with given id doesn't exist")
if (menuItem.icon == null) menuItem.icon = GoogleMaterial.Icon.gmd_search.toDrawable(context, 18, menuIconColor)
kau_search_cardview.gone()
menuItem.setOnMenuItemClickListener { revealOpen(); true }
@@ -430,17 +486,16 @@ class SearchView @JvmOverloads constructor(
cardTransition {
addEndListener {
kau_search_cardview.circularHide(menuX, menuHalfHeight, duration = configs.revealDuration,
- onFinish = {
- configs.closeListener?.invoke(this@SearchView)
- if (configs.shouldClearOnClose) kau_search_edit_text.text?.clear()
- })
+ onFinish = {
+ configs.closeListener?.invoke(this@SearchView)
+ if (configs.shouldClearOnClose) kau_search_edit_text.text?.clear()
+ })
}
}
kau_search_recycler.gone()
kau_search_edit_text.hideKeyboard()
}
}
-
}
@DslMarker
@@ -450,7 +505,12 @@ annotation class KauSearch
* Helper function that binds to an activity's main view
*/
@KauSearch
-fun Activity.bindSearchView(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: Int = Color.WHITE, config: SearchView.Configs.() -> Unit = {}): SearchView = findViewById<ViewGroup>(android.R.id.content).bindSearchView(menu, id, menuIconColor, config)
+fun Activity.bindSearchView(
+ menu: Menu,
+ @IdRes id: Int,
+ @ColorInt menuIconColor: Int = Color.WHITE,
+ config: SearchView.Configs.() -> Unit = {}
+): SearchView = findViewById<ViewGroup>(android.R.id.content).bindSearchView(menu, id, menuIconColor, config)
/**
* Bind searchView to a menu item; call this in [Activity.onCreateOptionsMenu]
@@ -458,11 +518,16 @@ fun Activity.bindSearchView(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor:
* it may be worthwhile to hold a reference to the searchview and only bind it if it hasn't been bound before
*/
@KauSearch
-fun ViewGroup.bindSearchView(menu: Menu, @IdRes id: Int, @ColorInt menuIconColor: Int = Color.WHITE, config: SearchView.Configs.() -> Unit = {}): SearchView {
+fun ViewGroup.bindSearchView(
+ menu: Menu,
+ @IdRes id: Int,
+ @ColorInt menuIconColor: Int = Color.WHITE,
+ config: SearchView.Configs.() -> Unit = {}
+): SearchView {
val searchView = SearchView(context)
- searchView.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
+ searchView.layoutParams =
+ FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
addView(searchView)
searchView.bind(menu, id, menuIconColor, config)
return searchView
}
-
diff --git a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt
index 3f81dd0..a33b09b 100644
--- a/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt
+++ b/searchview/src/main/kotlin/ca/allanwang/kau/searchview/SearchViewHolder.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2018 Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package ca.allanwang.kau.searchview
import android.view.MenuItem
@@ -21,5 +36,4 @@ interface SearchViewHolder {
searchView?.unBind(replacementMenuItemClickListener)
searchView = null
}
-
-} \ No newline at end of file
+}
diff --git a/searchview/src/main/res/layout/kau_search_iitem.xml b/searchview/src/main/res/layout/kau_search_iitem.xml
index 16df945..53e33ef 100644
--- a/searchview/src/main/res/layout/kau_search_iitem.xml
+++ b/searchview/src/main/res/layout/kau_search_iitem.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@id/kau_search_item_frame"
android:layout_width="match_parent"
@@ -58,4 +58,4 @@
app:layout_constraintStart_toEndOf="@id/kau_search_icon"
app:layout_constraintTop_toBottomOf="@id/kau_search_title" />
-</android.support.constraint.ConstraintLayout> \ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/searchview/src/main/res/layout/kau_search_view.xml b/searchview/src/main/res/layout/kau_search_view.xml
index c975dad..cfcb2ed 100644
--- a/searchview/src/main/res/layout/kau_search_view.xml
+++ b/searchview/src/main/res/layout/kau_search_view.xml
@@ -43,7 +43,7 @@
android:focusable="true"
android:scaleType="centerInside" />
- <android.support.v7.widget.AppCompatEditText
+ <androidx.appcompat.widget.AppCompatEditText
android:id="@id/kau_search_edit_text"
android:layout_width="0dp"
android:layout_height="match_parent"
@@ -98,7 +98,7 @@
android:layout_height="@dimen/kau_search_divider"
android:background="?android:attr/listDivider" />
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:id="@id/kau_search_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/spotless.gradle b/spotless.gradle
new file mode 100644
index 0000000..22dba3a
--- /dev/null
+++ b/spotless.gradle
@@ -0,0 +1,11 @@
+apply plugin: "com.diffplug.gradle.spotless"
+
+spotless {
+ kotlin {
+ target "**/*.kt"
+ ktlint()
+ licenseHeaderFile '../spotless.license.kt'
+ trimTrailingWhitespace()
+ endWithNewline()
+ }
+} \ No newline at end of file
diff --git a/spotless.license.kt b/spotless.license.kt
new file mode 100644
index 0000000..ce8139e
--- /dev/null
+++ b/spotless.license.kt
@@ -0,0 +1,15 @@
+/*
+ * Copyright $YEAR Allan Wang
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ \ No newline at end of file