aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-07-23 23:26:34 -0700
committerGitHub <noreply@github.com>2017-07-23 23:26:34 -0700
commit50ad7f0ae89fc52ce57fe03328f4221fb57f2eac (patch)
tree69ead8807bb7371428953a0363519343f03f9b5b
parent4706b8f6a8d08a6961da6ab34d15881b63356d79 (diff)
downloadkau-50ad7f0ae89fc52ce57fe03328f4221fb57f2eac.tar.gz
kau-50ad7f0ae89fc52ce57fe03328f4221fb57f2eac.tar.bz2
kau-50ad7f0ae89fc52ce57fe03328f4221fb57f2eac.zip
Fully implement imagepicker and create play store showcase (#12)3.1.1
* Update changelog * Add uri to imagemodel * Revamp image pickers * Prepare play store showcase * Add encrypted files * Test showcase * Clean elastic recycler activity
-rw-r--r--.travis.yml13
-rw-r--r--README.md3
-rw-r--r--adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt4
-rw-r--r--build.gradle3
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/MeasuredImageView.kt1
-rw-r--r--core-ui/src/main/kotlin/ca/allanwang/kau/ui/widgets/ElasticDragDismissFrameLayout.kt14
-rw-r--r--core-ui/src/main/res-public/values/styles.xml3
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt25
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt10
-rw-r--r--docs/Changelog.md9
-rw-r--r--files/.gitignore4
-rw-r--r--files/images/kau_banner.pngbin0 -> 29217 bytes
-rw-r--r--files/images/kau_round.svg120
-rw-r--r--files/images/kau_round_512.pngbin0 -> 21202 bytes
-rw-r--r--files/images/logo.svg (renamed from files/logo.svg)0
-rw-r--r--files/kau.tar.encbin0 -> 10256 bytes
-rw-r--r--files/travis.sh10
-rw-r--r--imagepicker/README.md36
-rw-r--r--imagepicker/build.gradle2
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItem.kt37
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItemBasic.kt71
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageModel.kt4
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityBase.kt118
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityOverlayBase.kt51
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerBinder.kt10
-rw-r--r--imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerCore.kt200
-rw-r--r--imagepicker/src/main/res-public/values-v21/styles.xml9
-rw-r--r--imagepicker/src/main/res-public/values/public.xml1
-rw-r--r--imagepicker/src/main/res-public/values/styles.xml7
-rw-r--r--imagepicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml17
-rw-r--r--imagepicker/src/main/res/layout/kau_activity_image_picker.xml1
-rw-r--r--imagepicker/src/main/res/layout/kau_iitem_image_basic.xml10
-rw-r--r--imagepicker/src/main/res/transition-v21/kau_image_enter.xml16
-rw-r--r--imagepicker/src/main/res/transition-v21/kau_image_exit_bottom.xml16
-rw-r--r--imagepicker/src/main/res/transition-v21/kau_image_exit_top.xml16
-rw-r--r--imagepicker/src/main/res/values/strings.xml1
-rw-r--r--sample/build.gradle24
-rw-r--r--sample/src/main/AndroidManifest.xml7
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt62
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePicker.kt11
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePickerActivity.kt8
-rw-r--r--sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt4
-rw-r--r--sample/src/main/play/contactEmail1
-rw-r--r--sample/src/main/play/defaultLanguage1
-rw-r--r--sample/src/main/play/en-CA/listing/fulldescription3
-rw-r--r--sample/src/main/play/en-CA/listing/shortdescription1
-rw-r--r--sample/src/main/play/en-CA/listing/title1
-rw-r--r--sample/src/main/play/en-CA/whatsnew1
-rw-r--r--sample/src/main/res/mipmap-hdpi/ic_launcher.pngbin3418 -> 2316 bytes
-rw-r--r--sample/src/main/res/mipmap-hdpi/ic_launcher_round.pngbin4208 -> 0 bytes
-rw-r--r--sample/src/main/res/mipmap-mdpi/ic_launcher.pngbin2206 -> 0 bytes
-rw-r--r--sample/src/main/res/mipmap-mdpi/ic_launcher_round.pngbin2555 -> 0 bytes
-rw-r--r--sample/src/main/res/mipmap-xhdpi/ic_launcher.pngbin4842 -> 3053 bytes
-rw-r--r--sample/src/main/res/mipmap-xhdpi/ic_launcher_round.pngbin6114 -> 0 bytes
-rw-r--r--sample/src/main/res/mipmap-xxhdpi/ic_launcher.pngbin7718 -> 4750 bytes
-rw-r--r--sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.pngbin10056 -> 0 bytes
-rw-r--r--sample/src/main/res/mipmap-xxxhdpi/ic_launcher.pngbin10486 -> 6480 bytes
-rw-r--r--sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.pngbin14696 -> 0 bytes
-rw-r--r--sample/src/main/res/values/strings.xml4
-rw-r--r--sample/src/main/res/xml/kau_changelog.xml15
60 files changed, 742 insertions, 243 deletions
diff --git a/.travis.yml b/.travis.yml
index fb97b18..1830df2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,8 +11,10 @@ android:
- extra-android-m2repository
- extra-google-m2repository
licenses:
- - '.+'
-script: ./gradlew lintRelease test
+ - ".+"
+script:
+- ./gradlew --quiet androidGitVersion
+- if [[ "$TRAVIS_BRANCH" == "master" ]]; then ./gradlew lintRelease publishRelease; else ./gradlew lintRelease test; fi
branches:
except:
- gh-pages
@@ -26,6 +28,9 @@ notifications:
sudo: false
cache:
directories:
- - $HOME/.m2
+ - "$HOME/.m2"
before_script:
-- chmod +x gradlew \ No newline at end of file
+- chmod +x gradlew
+before_install:
+- openssl aes-256-cbc -K $encrypted_12e8842891a3_key -iv $encrypted_12e8842891a3_iv
+ -in files/kau.tar.enc -out kau.tar -d
diff --git a/README.md b/README.md
index 771ce01..e2f359f 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,8 @@ dependencies {
## [Image Picker](imagepicker#readme)
* WIP - Overlaying media chooser
* Includes `:core-ui`,
-[`Glide`](https://github.com/bumptech/glide)
+[`Glide`](https://github.com/bumptech/glide),
+[`Blurry`](https://github.com/wasabeef/Blurry)
## [Kpref Activity](kpref-activity#readme)
* Fully programmatic implementation of a Preference Activity, backed by RecyclerViews
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 5b36551..9e52aac 100644
--- a/adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt
+++ b/adapter/src/main/kotlin/ca/allanwang/kau/animators/KauAnimator.kt
@@ -8,13 +8,13 @@ import ca.allanwang.kau.utils.KAU_RIGHT
/**
* Created by Allan Wang on 2017-06-27.
*/
-class KauAnimator(
+open class KauAnimator(
val addAnimator: KauAnimatorAdd = SlideAnimatorAdd(KAU_BOTTOM),
val removeAnimator: KauAnimatorRemove = SlideAnimatorRemove(KAU_RIGHT),
val changeAnimator: KauAnimatorChange = FadeAnimatorChange()
) : BaseItemAnimator() {
- fun startDelay(holder: RecyclerView.ViewHolder, duration: Long, factor: Float)
+ 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 {
diff --git a/build.gradle b/build.gradle
index bd440a8..72d35aa 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
-import groovy.xml.MarkupBuilder
-
buildscript {
repositories {
jcenter()
@@ -10,6 +8,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN}"
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
+ classpath 'com.github.triplet.gradle:play-publisher:1.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
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 ebb6397..5db5eaa 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
@@ -3,7 +3,6 @@ package ca.allanwang.kau.ui.views
import android.content.Context
import android.support.v7.widget.AppCompatImageView
import android.util.AttributeSet
-import android.widget.ImageView
/**
* Created by Allan Wang on 2017-07-14.
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 995ccab..5cdfc92 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
@@ -21,9 +21,12 @@ import android.content.Context
import android.graphics.Color
import android.os.Build
import android.support.annotation.RequiresApi
+import android.support.v7.widget.RecyclerView
+import android.transition.TransitionInflater
import android.util.AttributeSet
import android.view.View
import android.widget.FrameLayout
+import ca.allanwang.kau.logging.KL
import ca.allanwang.kau.ui.R
import ca.allanwang.kau.utils.*
@@ -237,4 +240,15 @@ class ElasticDragDismissFrameLayout @JvmOverloads constructor(
}
}
+ 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.d("New transition")
+ activity.window.returnTransition = TransitionInflater.from(activity)
+ .inflateTransition(if (translationY > 0) transitionBottom else transitionTop)
+ activity.finishAfterTransition()
+ }
+ })
+ }
+
}
diff --git a/core-ui/src/main/res-public/values/styles.xml b/core-ui/src/main/res-public/values/styles.xml
index 583ede7..31c5b74 100644
--- a/core-ui/src/main/res-public/values/styles.xml
+++ b/core-ui/src/main/res-public/values/styles.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
+
<style name="Kau.Translucent">
<item name="android:windowBackground">@color/kau_shadow_overlay</item>
<item name="android:colorBackgroundCacheHint">@null</item>
@@ -13,6 +14,8 @@
<item name="android:windowAnimationStyle">@null</item>
</style>
+ <!--Transitions are only v21+-->
+
<style name="Kau.Translucent.SlideBottom" />
<style name="Kau.Translucent.SlideTop" />
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 54aeaff..5631e70 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ActivityUtils.kt
@@ -2,11 +2,11 @@ package ca.allanwang.kau.utils
import android.annotation.SuppressLint
import android.app.Activity
+import android.app.ActivityOptions
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
@@ -20,6 +20,27 @@ import org.jetbrains.anko.contentView
*/
/**
+ * Helper class to launch an activity for result
+ * Counterpart of [Activity.startActivityForResult]
+ * For starting activities without result, see [startActivity]
+ */
+@SuppressLint("NewApi")
+fun Activity.startActivityForResult(
+ clazz: Class<out Activity>,
+ requestCode: Int,
+ transition: Boolean = false,
+ bundle: Bundle? = null,
+ intentBuilder: Intent.() -> Unit = {}) {
+ val intent = Intent(this, clazz)
+ val fullBundle = if (transition && buildIsLollipopAndUp)
+ ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
+ else Bundle()
+ if (bundle != null) fullBundle.putAll(bundle)
+ intent.intentBuilder()
+ startActivityForResult(intent, requestCode, if (fullBundle.isEmpty) null else fullBundle)
+}
+
+/**
* Restarts an activity from itself with a fade animation
* Keeps its existing extra bundles and has a builder to accept other parameters
*/
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 7a92665..2219b5d 100644
--- a/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
+++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ContextUtils.kt
@@ -26,6 +26,12 @@ import com.afollestad.materialdialogs.MaterialDialog
/**
* Created by Allan Wang on 2017-06-03.
*/
+
+/**
+ * Helper class to launch an activity from a context
+ * Counterpart of [ContextCompat.startActivity]
+ * For starting activities for results, see [startActivityForResult]
+ */
@SuppressLint("NewApi")
fun Context.startActivity(
clazz: Class<out Activity>,
@@ -33,14 +39,14 @@ fun Context.startActivity(
transition: Boolean = false,
bundle: Bundle? = null,
intentBuilder: Intent.() -> Unit = {}) {
- val intent = (Intent(this, clazz))
+ val intent = Intent(this, clazz)
if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
- intent.intentBuilder()
val fullBundle = if (transition && this is Activity && buildIsLollipopAndUp)
ActivityOptions.makeSceneTransitionAnimation(this).toBundle()
else Bundle()
if (transition && this !is Activity) KL.d("Cannot make scene transition when context is not an instance of an Activity")
if (bundle != null) fullBundle.putAll(bundle)
+ intent.intentBuilder()
ContextCompat.startActivity(this, intent, if (fullBundle.isEmpty) null else fullBundle)
if (this is Activity && clearStack) finish()
}
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 4a913b5..99bfb50 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -1,7 +1,14 @@
# Changelog
-## v3.1
+## v3.1.1
+* :imagepicker: Add uri val to ImageModel
+
+## v3.1.0
* :core: Allow for nullable throwables when logging
+* :core: Remove some extra DSL annotations
+* :kpref-activity: Bring down to minSdk 19 and fix compatibility
+* :adapter: Update readme for iitems and animators
+* :about: Move strings to private
## v3.0
* :core: Add setPadding[x]
diff --git a/files/.gitignore b/files/.gitignore
new file mode 100644
index 0000000..e9bf9f6
--- /dev/null
+++ b/files/.gitignore
@@ -0,0 +1,4 @@
+gplay-keys.json
+kau.keystore
+kau.properties
+update-dev.sh
diff --git a/files/images/kau_banner.png b/files/images/kau_banner.png
new file mode 100644
index 0000000..d59b043
--- /dev/null
+++ b/files/images/kau_banner.png
Binary files differ
diff --git a/files/images/kau_round.svg b/files/images/kau_round.svg
new file mode 100644
index 0000000..e8892e6
--- /dev/null
+++ b/files/images/kau_round.svg
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="160mm"
+ height="160mm"
+ viewBox="0 0 566.92911 566.92912"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="kau_round.svg"
+ inkscape:export-filename="C:\Users\User7681\Downloads\kau_round_72.png"
+ inkscape:export-xdpi="11.43"
+ inkscape:export-ydpi="11.43">
+ <defs
+ id="defs4">
+ <filter
+ style="color-interpolation-filters:sRGB"
+ inkscape:label="Drop Shadow"
+ id="filter4312">
+ <feFlood
+ flood-opacity="0.498039"
+ flood-color="rgb(0,0,0)"
+ result="flood"
+ id="feFlood4314" />
+ <feComposite
+ in="flood"
+ in2="SourceGraphic"
+ operator="in"
+ result="composite1"
+ id="feComposite4316" />
+ <feGaussianBlur
+ in="composite1"
+ stdDeviation="3.3"
+ result="blur"
+ id="feGaussianBlur4318" />
+ <feOffset
+ dx="5"
+ dy="5"
+ result="offset"
+ id="feOffset4320" />
+ <feComposite
+ in="SourceGraphic"
+ in2="offset"
+ operator="over"
+ result="composite2"
+ id="feComposite4322" />
+ </filter>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.49497475"
+ inkscape:cx="335.78333"
+ inkscape:cy="368.84238"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="false"
+ inkscape:window-width="1536"
+ inkscape:window-height="841"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ fit-margin-top="9"
+ fit-margin-left="20"
+ fit-margin-right="20"
+ fit-margin-bottom="20"
+ borderlayer="false"
+ inkscape:showpageshadow="true" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-103.41957,-202.20087)">
+ <g
+ id="g4324"
+ transform="translate(-4.5444214,0)">
+ <circle
+ r="217.14285"
+ cy="481.12094"
+ cx="391.42856"
+ id="path4136"
+ style="opacity:1;fill:#ff8900;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="circle4211"
+ d="m 274.76172,306.12695 0,357.85157 a 217.14285,217.14285 0 0 0 116.66601,34.28515 217.14285,217.14285 0 0 0 137.13672,-48.94531 L 274.76172,306.12695 Z"
+ style="opacity:1;fill:#0086dc;fill-opacity:0.8627451;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="circle4206"
+ d="m 391.42773,263.97852 a 217.14285,217.14285 0 0 0 -116.66601,34.04687 l 0,358.08984 253.79101,-343.17578 a 217.14285,217.14285 0 0 0 -137.125,-48.96093 z"
+ style="opacity:1;fill:#00a9ff;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4312)" />
+ </g>
+ </g>
+</svg>
diff --git a/files/images/kau_round_512.png b/files/images/kau_round_512.png
new file mode 100644
index 0000000..0fa7c94
--- /dev/null
+++ b/files/images/kau_round_512.png
Binary files differ
diff --git a/files/logo.svg b/files/images/logo.svg
index 4f5a27b..4f5a27b 100644
--- a/files/logo.svg
+++ b/files/images/logo.svg
diff --git a/files/kau.tar.enc b/files/kau.tar.enc
new file mode 100644
index 0000000..4d39f9f
--- /dev/null
+++ b/files/kau.tar.enc
Binary files differ
diff --git a/files/travis.sh b/files/travis.sh
new file mode 100644
index 0000000..9df9ad9
--- /dev/null
+++ b/files/travis.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+# Add appropriate files for encryption
+
+rm kau.tar.enc
+cd ..
+tar cvf kau.tar files/gplay-keys.json files/kau.keystore files/kau.properties
+travis encrypt-file kau.tar --add
+rm kau.tar
+mv kau.tar.enc files/ \ No newline at end of file
diff --git a/imagepicker/README.md b/imagepicker/README.md
index e37e417..f70de2b 100644
--- a/imagepicker/README.md
+++ b/imagepicker/README.md
@@ -1,12 +1,35 @@
# KAU :imagepicker
ImagePicker is a beautiful gallery activity that allows you to pick images
-from your storage. It is backed by FastAdapter and Glide, and offers blur and fade transitions.
+from your storage. It is backed by FastAdapter and Glide, and stems from the ImagePickerCore model
-`ImagePickerActivityBase` is already fully functional, so you may directly extend it with no further changes
-and add the activity to your manifest
+Currently, there are two options:
-You may also easily launch the activity through the simple binder:
+--------------------------------
+
+## ImagePickerActivityBase
+
+A full screen multi image picker with beautiful animations.
+Images are blurred when selected, and there is a counter on the top right.
+There is a FAB to send back the response.
+
+`R.style.Kau.ImagePicker` is added for your convenience.
+
+## ImagePickerActivityOverlayBase
+
+This overlaying activity makes use of transitions and nested scrolling, and is only for Lollipop and up.
+Only one image can be selected, so the overlay exists immediately upon the first selection.
+Having this model also means that each item is only one simple image, as opposed to the blurrable image view above.
+As a result, this activity has faster loading on scrolling.
+
+`R.style.Kau.ImagePicker.Overlay` is added for your convenience.
+
+--------------------------------
+
+Both activities work out of the box and can be extended without needing further modifications.
+Their convenience styles default to a slide in slide out animation from the bottom edge.
+
+You may also easily launch either activity through the simple binder:
```
Activity.kauLaunchImagePicker(YourClass::class.java, yourRequestCode)
```
@@ -14,6 +37,5 @@ Activity.kauLaunchImagePicker(YourClass::class.java, yourRequestCode)
Note that this launches the activity through a `startActivityForResult` call
You may get the activity response by overriding your `onActivityResult` method
-to first verify that the request code matches and then call `kauOnImagePickerResult`
-
-This module also has a template style `Kau.ImagePicker` that defaults to a slide up animation. \ No newline at end of file
+to first verify that the request code matches and then call `kauOnImagePickerResult`,
+which will return the list of ImageModels. \ No newline at end of file
diff --git a/imagepicker/build.gradle b/imagepicker/build.gradle
index a31fac0..93f52ac 100644
--- a/imagepicker/build.gradle
+++ b/imagepicker/build.gradle
@@ -4,7 +4,7 @@ apply from: '../android-lib.gradle'
dependencies {
- compile project(':adapter')
+ compile project(':core-ui')
compile "com.github.bumptech.glide:glide:${GLIDE}"
kapt "com.github.bumptech.glide:compiler:${GLIDE}"
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItem.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItem.kt
index 2bfc57f..ffeb560 100644
--- a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItem.kt
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItem.kt
@@ -1,22 +1,16 @@
package ca.allanwang.kau.imagepicker
-import android.content.Context
-import android.graphics.Color
import android.graphics.drawable.Drawable
import android.support.v7.widget.RecyclerView
import android.view.View
import ca.allanwang.kau.iitems.KauIItem
import ca.allanwang.kau.utils.bindView
-import ca.allanwang.kau.utils.gone
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.mikepenz.fastadapter.FastAdapter
-import com.mikepenz.google_material_typeface_library.GoogleMaterial
-import com.mikepenz.iconics.IconicsDrawable
-import com.mikepenz.iconics.typeface.IIcon
/**
* Created by Allan Wang on 2017-07-04.
@@ -25,7 +19,6 @@ class ImageItem(val data: ImageModel)
: KauIItem<ImageItem, ImageItem.ViewHolder>(R.layout.kau_iitem_image, { ViewHolder(it) }) {
private var failedToLoad = false
- var withFade = true
companion object {
fun bindEvents(fastAdapter: FastAdapter<ImageItem>) {
@@ -45,50 +38,28 @@ class ImageItem(val data: ImageModel)
override fun bindView(holder: ViewHolder, payloads: List<Any>?) {
super.bindView(holder, payloads)
- if (withFade) holder.container.alpha = 0f
Glide.with(holder.itemView)
.load(data.data)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
- failedToLoad = true;
- holder.container.setIcon(GoogleMaterial.Icon.gmd_error);
- if (withFade) holder.container.animate().alpha(1f).start();
+ failedToLoad = true
+ holder.container.imageBase.setImageDrawable(ImagePickerCore.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()
- if (withFade) holder.container.animate().alpha(1f).start();
return true;
}
})
.into(holder.container.imageBase)
}
- private fun BlurredImageView.setIcon(icon: IIcon) {
- val sizePx = computeViewSize(context)
- imageBase.setImageDrawable(IconicsDrawable(context, icon)
- .sizePx(sizePx)
- .paddingPx(sizePx / 3)
- .color(Color.WHITE))
- imageBase.setBackgroundColor(ImagePickerActivityBase.accentColor)
- imageForeground.gone()
- }
-
- private fun computeViewSize(context: Context): Int {
- val screenWidthPx = context.resources.displayMetrics.widthPixels
- return screenWidthPx / ImagePickerActivityBase.computeColumnCount(context)
- }
-
override fun unbindView(holder: ViewHolder) {
super.unbindView(holder)
- if (!failedToLoad) {
- Glide.with(holder.itemView).clear(holder.container.imageBase)
- holder.container.removeBlurInstantly()
- } else {
- holder.container.fullReset()
- }
+ Glide.with(holder.itemView).clear(holder.container.imageBase)
+ holder.container.removeBlurInstantly()
failedToLoad = false
}
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItemBasic.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItemBasic.kt
new file mode 100644
index 0000000..62a0b09
--- /dev/null
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageItemBasic.kt
@@ -0,0 +1,71 @@
+package ca.allanwang.kau.imagepicker
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.content.Intent
+import android.graphics.drawable.Drawable
+import android.support.v7.app.AppCompatActivity
+import android.support.v7.widget.RecyclerView
+import android.view.View
+import ca.allanwang.kau.iitems.KauIItem
+import ca.allanwang.kau.ui.views.MeasuredImageView
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.buildIsLollipopAndUp
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.DataSource
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.Target
+import com.mikepenz.fastadapter.FastAdapter
+
+/**
+ * Created by Allan Wang on 2017-07-04.
+ */
+class ImageItemBasic(val data: ImageModel)
+ : KauIItem<ImageItem, ImageItemBasic.ViewHolder>(R.layout.kau_iitem_image_basic, { ViewHolder(it) }) {
+
+ companion object {
+ @SuppressLint("NewApi")
+ fun bindEvents(activity: Activity, fastAdapter: FastAdapter<ImageItemBasic>) {
+ fastAdapter.withSelectable(false)
+ //add image data and return right away
+ .withOnClickListener { v, _, item, _ ->
+ val intent = Intent()
+ val data = arrayListOf(item.data)
+ intent.putParcelableArrayListExtra(IMAGE_PICKER_RESULT, data)
+ activity.setResult(AppCompatActivity.RESULT_OK, intent)
+ if (buildIsLollipopAndUp) activity.finishAfterTransition()
+ else activity.finish()
+ true
+ }
+ }
+ }
+
+ override fun isSelectable(): Boolean = false
+
+ override fun bindView(holder: ViewHolder, payloads: List<Any>?) {
+ super.bindView(holder, payloads)
+ Glide.with(holder.itemView)
+ .load(data.data)
+ .listener(object : RequestListener<Drawable> {
+ override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
+ holder.image.setImageDrawable(ImagePickerCore.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) {
+ super.unbindView(holder)
+ Glide.with(holder.itemView).clear(holder.image)
+ }
+
+ class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
+ val image: MeasuredImageView by bindView(R.id.kau_image)
+ }
+} \ No newline at end of file
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageModel.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageModel.kt
index d744650..202805c 100644
--- a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageModel.kt
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImageModel.kt
@@ -1,10 +1,12 @@
package ca.allanwang.kau.imagepicker
import android.database.Cursor
+import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import android.provider.MediaStore
import android.support.annotation.NonNull
+import java.io.File
/**
@@ -34,6 +36,8 @@ data class ImageModel(val size: Long, val dateModified: Long, val data: String,
parcel.writeString(this.displayName)
}
+ val uri: Uri by lazy { Uri.fromFile(File(data)) }
+
override fun describeContents(): Int {
return 0
}
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityBase.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityBase.kt
index 9d988d1..3a9809c 100644
--- a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityBase.kt
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityBase.kt
@@ -1,40 +1,27 @@
package ca.allanwang.kau.imagepicker
-import android.Manifest
-import android.app.Activity
-import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.os.Bundle
-import android.provider.MediaStore
import android.support.design.widget.AppBarLayout
import android.support.design.widget.CoordinatorLayout
import android.support.design.widget.FloatingActionButton
-import android.support.v4.app.LoaderManager
-import android.support.v4.content.CursorLoader
import android.support.v4.content.Loader
-import android.support.v7.app.AppCompatActivity
-import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar
import android.widget.TextView
-import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
-import ca.allanwang.kau.animators.KauAnimator
-import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.utils.*
-import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
import com.mikepenz.google_material_typeface_library.GoogleMaterial
-
/**
* Created by Allan Wang on 2017-07-04.
*
* Base activity for selecting images from storage
+ * Images are blurred when selected, and multiple images can be selected at a time.
+ * Having three layered images makes this slightly slower than [ImagePickerActivityOverlayBase]
*/
-abstract class ImagePickerActivityBase : AppCompatActivity(), LoaderManager.LoaderCallbacks<Cursor> {
-
- val imageAdapter = FastItemAdapter<ImageItem>()
+abstract class ImagePickerActivityBase : ImagePickerCore<ImageItem>() {
val coordinator: CoordinatorLayout by bindView(R.id.kau_coordinator)
val toolbar: Toolbar by bindView(R.id.kau_toolbar)
@@ -42,28 +29,6 @@ abstract class ImagePickerActivityBase : AppCompatActivity(), LoaderManager.Load
val recycler: RecyclerView by bindView(R.id.kau_recyclerview)
val fab: FloatingActionButton by bindView(R.id.kau_fab)
- companion object {
- /**
- * Given the dimensions of our device and a minimum image size,
- * Computer the optimal column count for our grid layout
- *
- * @return column count
- */
- fun computeColumnCount(context: Context): Int {
- val minImageSizePx = context.dimenPixelSize(R.dimen.kau_image_minimum_size)
- val screenWidthPx = context.resources.displayMetrics.widthPixels
- return screenWidthPx / minImageSizePx
- }
-
- var accentColor: Int = 0xff666666.toInt()
-
- fun onImagePickerResult(resultCode: Int, data: Intent?): List<ImageModel> {
- if (resultCode != Activity.RESULT_OK || data == null || !data.hasExtra(IMAGE_PICKER_RESULT))
- return emptyList()
- return data.getParcelableArrayListExtra(IMAGE_PICKER_RESULT)
- }
- }
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -79,12 +44,7 @@ abstract class ImagePickerActivityBase : AppCompatActivity(), LoaderManager.Load
}
toolbar.setNavigationOnClickListener { onBackPressed() }
- recycler.apply {
- layoutManager = GridLayoutManager(context, computeColumnCount(context))
- adapter = imageAdapter
- setHasFixedSize(true)
- itemAnimator = KauAnimator(FadeScaleAnimatorAdd(0.8f))
- }
+ initializeRecycler(recycler)
ImageItem.bindEvents(imageAdapter)
imageAdapter.withSelectionListener({ _, _ -> selectionCount.text = imageAdapter.selections.size.toString() })
@@ -110,24 +70,7 @@ abstract class ImagePickerActivityBase : AppCompatActivity(), LoaderManager.Load
loadImages()
}
- /**
- * Request read permissions and load all external images
- * The result will be filtered through {@link #onLoadFinished(Loader, Cursor)}
- * Call this to make sure that we request permissions each time
- * The adapter will be cleared on each successful call
- */
- private fun loadImages() {
- kauRequestPermissions(Manifest.permission.READ_EXTERNAL_STORAGE) {
- granted, _ ->
- if (granted) {
- supportLoaderManager.initLoader(LOADER_ID, null, this)
- setToolbarScrollable(true)
- } else {
- toast(R.string.kau_permission_denied)
- setToolbarScrollable(false)
- }
- }
- }
+ override fun converter(model: ImageModel): ImageItem = ImageItem(model)
/**
* Decide whether the toolbar can hide itself
@@ -145,56 +88,13 @@ abstract class ImagePickerActivityBase : AppCompatActivity(), LoaderManager.Load
params.scrollFlags = 0
}
- override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
- val columns = arrayOf(
- MediaStore.Images.Media._ID,
- MediaStore.Images.Media.TITLE,
- MediaStore.Images.Media.DATA,
- MediaStore.Images.Media.SIZE,
- MediaStore.Images.Media.DISPLAY_NAME,
- MediaStore.Images.Media.DATE_MODIFIED
- )
- return CursorLoader(this,
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- columns,
- null,
- null,
- //Sort by descending date
- MediaStore.Images.Media.DATE_MODIFIED + " DESC")
- }
-
- override fun onLoadFinished(loader: Loader<Cursor>, data: Cursor?) {
- reset()
- if (data == null || !data.moveToFirst()) {
- toast(R.string.kau_no_images_found)
- setToolbarScrollable(false)
- return
- }
- do {
- val model = ImageModel(data)
- if (!shouldLoad(model)) continue
- imageAdapter.add(ImageItem(model))
- } while (data.moveToNext())
+ override fun onLoadFinished(loader: Loader<Cursor>?, data: Cursor?) {
+ super.onLoadFinished(loader, data)
setToolbarScrollable((recycler.layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition() < imageAdapter.getItemCount() - 1)
}
- /**
- * Optional filter to decide which images get displayed
- * Defaults to checking their sizes to filter out
- * very small images such as lurking drawables/icons
- *
- * Returns true if model should be displayed, false otherwise
- */
- open fun shouldLoad(model: ImageModel): Boolean = model.size > 10000L
-
- private fun reset() {
- imageAdapter.clear();
+ override fun onStatusChange(loaded: Boolean) {
+ setToolbarScrollable(loaded)
}
- override fun onLoaderReset(loader: Loader<Cursor>) = reset()
-
- override fun onBackPressed() {
- setResult(RESULT_CANCELED)
- super.onBackPressed()
- }
} \ No newline at end of file
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityOverlayBase.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityOverlayBase.kt
new file mode 100644
index 0000000..ed8eee4
--- /dev/null
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerActivityOverlayBase.kt
@@ -0,0 +1,51 @@
+package ca.allanwang.kau.imagepicker
+
+import android.os.Build
+import android.os.Bundle
+import android.support.annotation.RequiresApi
+import android.support.v7.widget.RecyclerView
+import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout
+import ca.allanwang.kau.utils.bindView
+import ca.allanwang.kau.utils.toast
+
+/**
+ * Created by Allan Wang on 2017-07-23.
+ *
+ * Base activity for selecting images from storage
+ * This variant is an overlay and selects one image only before returning directly
+ * It is more efficient than [ImagePickerActivityBase], as all images are one layer deep
+ * as opposed to three layers deep
+ */
+@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+abstract class ImagePickerActivityOverlayBase : ImagePickerCore<ImageItemBasic>() {
+
+ val draggable: ElasticDragDismissFrameLayout by bindView(R.id.kau_draggable)
+ val recycler: RecyclerView by bindView(R.id.kau_recyclerview)
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.kau_activity_image_picker_overlay)
+ initializeRecycler(recycler)
+ ImageItemBasic.bindEvents(this, imageAdapter)
+
+ draggable.addExitListener(this, R.transition.kau_image_exit_bottom, R.transition.kau_image_exit_top)
+ draggable.setOnClickListener { finishAfterTransition() }
+
+ loadImages()
+ }
+
+ override fun finishAfterTransition() {
+ recycler.stopScroll()
+ super.finishAfterTransition()
+ }
+
+ override fun onStatusChange(loaded: Boolean) {
+ if (!loaded) toast(R.string.kau_no_images_loaded)
+ }
+
+ override fun converter(model: ImageModel): ImageItemBasic = ImageItemBasic(model)
+
+ override fun onBackPressed() {
+ finishAfterTransition()
+ }
+} \ No newline at end of file
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerBinder.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerBinder.kt
index 8e8a69c..db8d113 100644
--- a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerBinder.kt
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerBinder.kt
@@ -2,6 +2,7 @@ package ca.allanwang.kau.imagepicker
import android.app.Activity
import android.content.Intent
+import ca.allanwang.kau.utils.startActivityForResult
/**
* Created by Allan Wang on 2017-07-21.
@@ -11,10 +12,11 @@ import android.content.Intent
*/
/**
- * Image picker launcher
+ * Image picker launchers
*/
-fun Activity.kauLaunchImagePicker(clazz: Class<out ImagePickerActivityBase>, requestCode: Int) {
- startActivityForResult(Intent(this, clazz), requestCode)
+fun Activity.kauLaunchImagePicker(clazz: Class<out ImagePickerCore<*>>, requestCode: Int) {
+// startActivityForResult(clazz, requestCode, true)
+ startActivityForResult(clazz, requestCode, transition = ImagePickerActivityOverlayBase::class.java.isAssignableFrom(clazz))
}
/**
@@ -22,7 +24,7 @@ fun Activity.kauLaunchImagePicker(clazz: Class<out ImagePickerActivityBase>, req
* call under [Activity.onActivityResult]
* and make sure that the requestCode matches first
*/
-fun Activity.kauOnImagePickerResult(resultCode: Int, data: Intent?) = ImagePickerActivityBase.onImagePickerResult(resultCode, data)
+fun Activity.kauOnImagePickerResult(resultCode: Int, data: Intent?) = ImagePickerCore.onImagePickerResult(resultCode, data)
internal const val LOADER_ID = 42
internal const val IMAGE_PICKER_RESULT = "image_picker_result"
diff --git a/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerCore.kt b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerCore.kt
new file mode 100644
index 0000000..f197a5e
--- /dev/null
+++ b/imagepicker/src/main/kotlin/ca/allanwang/kau/imagepicker/ImagePickerCore.kt
@@ -0,0 +1,200 @@
+package ca.allanwang.kau.imagepicker
+
+import android.Manifest
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.database.Cursor
+import android.graphics.Color
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+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.app.AppCompatActivity
+import android.support.v7.widget.GridLayoutManager
+import android.support.v7.widget.RecyclerView
+import ca.allanwang.kau.animators.FadeScaleAnimatorAdd
+import ca.allanwang.kau.animators.KauAnimator
+import ca.allanwang.kau.permissions.kauRequestPermissions
+import ca.allanwang.kau.utils.dimenPixelSize
+import ca.allanwang.kau.utils.toast
+import com.mikepenz.fastadapter.IItem
+import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
+import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.mikepenz.iconics.IconicsDrawable
+
+/**
+ * Created by Allan Wang on 2017-07-23.
+ *
+ * Container for the main logic behind the image pickers
+ */
+abstract class ImagePickerCore<T : IItem<*, *>> : AppCompatActivity(), LoaderManager.LoaderCallbacks<Cursor> {
+
+ companion object {
+ /**
+ * Given the dimensions of our device and a minimum image size,
+ * Computer the optimal column count for our grid layout
+ *
+ * @return column count
+ */
+ fun computeColumnCount(context: Context): Int {
+ val minImageSizePx = context.dimenPixelSize(R.dimen.kau_image_minimum_size)
+ val screenWidthPx = context.resources.displayMetrics.widthPixels
+ return screenWidthPx / minImageSizePx
+ }
+
+ /**
+ * Compute our resulting image size
+ */
+ fun computeViewSize(context: Context): Int {
+ val screenWidthPx = context.resources.displayMetrics.widthPixels
+ return screenWidthPx / computeColumnCount(context)
+ }
+
+ /**
+ * Create error tile for a given item
+ */
+ fun getErrorDrawable(context: Context): Drawable {
+ val sizePx = ImagePickerCore.computeViewSize(context)
+ return IconicsDrawable(context, GoogleMaterial.Icon.gmd_error)
+ .sizePx(sizePx)
+ .backgroundColor(accentColor)
+ .paddingPx(sizePx / 3)
+ .color(Color.WHITE)
+ }
+
+ var accentColor: Int = 0xff666666.toInt()
+
+ /**
+ * Helper method to retrieve the images from our iamge picker
+ * This is used for both single and multiple photo picks
+ */
+ fun onImagePickerResult(resultCode: Int, data: Intent?): List<ImageModel> {
+ if (resultCode != Activity.RESULT_OK || data == null || !data.hasExtra(IMAGE_PICKER_RESULT))
+ return emptyList()
+ return data.getParcelableArrayListExtra(IMAGE_PICKER_RESULT)
+ }
+
+ /**
+ * Number of loaded images we should cache
+ * This is arbitrary
+ */
+ const val CACHE_SIZE = 80
+
+ /**
+ * We know that Glide takes a while to initially fetch the images
+ * My as well make it look pretty
+ */
+ const val INITIAL_LOAD_DELAY = 600L
+ }
+
+ val imageAdapter: FastItemAdapter<T> = FastItemAdapter()
+
+ /**
+ * Further improve preloading by extending the layout space
+ */
+ val extraSpace: Int by lazy { resources.displayMetrics.heightPixels }
+
+ fun initializeRecycler(recycler: RecyclerView) {
+ recycler.apply {
+ val manager = object : GridLayoutManager(context, computeColumnCount(context)) {
+ override fun getExtraLayoutSpace(state: RecyclerView.State?): Int {
+ return extraSpace
+ }
+ }
+ setItemViewCacheSize(CACHE_SIZE)
+ isDrawingCacheEnabled = true
+ layoutManager = manager
+ adapter = imageAdapter
+ setHasFixedSize(true)
+ itemAnimator = object : KauAnimator(FadeScaleAnimatorAdd(0.8f)) {
+ override fun startDelay(holder: RecyclerView.ViewHolder, duration: Long, factor: Float): Long {
+ return super.startDelay(holder, duration, factor) + INITIAL_LOAD_DELAY
+ }
+ }
+ }
+ }
+
+ //Sort by descending date
+ var sortQuery = MediaStore.Images.Media.DATE_MODIFIED + " DESC"
+
+ /**
+ * Request read permissions and load all external images
+ * The result will be filtered through {@link #onLoadFinished(Loader, Cursor)}
+ * Call this to make sure that we request permissions each time
+ * The adapter will be cleared on each successful call
+ */
+ open fun loadImages() {
+ kauRequestPermissions(Manifest.permission.READ_EXTERNAL_STORAGE) {
+ granted, _ ->
+ if (granted) {
+ supportLoaderManager.initLoader(LOADER_ID, null, this)
+ onStatusChange(true)
+ } else {
+ toast(R.string.kau_permission_denied)
+ onStatusChange(false)
+ }
+ }
+ }
+
+ override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {
+ val columns = arrayOf(
+ MediaStore.Images.Media._ID,
+ MediaStore.Images.Media.TITLE,
+ MediaStore.Images.Media.DATA,
+ MediaStore.Images.Media.SIZE,
+ MediaStore.Images.Media.DISPLAY_NAME,
+ MediaStore.Images.Media.DATE_MODIFIED
+ )
+ return CursorLoader(this, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, sortQuery)
+ }
+
+ override fun onLoadFinished(loader: Loader<Cursor>?, data: Cursor?) {
+ reset()
+ if (data == null || !data.moveToFirst()) {
+ toast(R.string.kau_no_images_found)
+ onStatusChange(false)
+ return
+ }
+ val items = mutableListOf<T>()
+ do {
+ val model = ImageModel(data)
+ if (!shouldLoad(model)) continue
+ items.add(converter(model))
+ } while (data.moveToNext())
+ addItems(items)
+ }
+
+ abstract fun converter(model: ImageModel): T
+
+ override fun onLoaderReset(loader: Loader<Cursor>?) = reset()
+
+ /**
+ * Called at the end of [onLoadFinished]
+ * when the adapter should add the items
+ */
+ open fun addItems(items: List<T>) {
+ imageAdapter.add(items)
+ }
+
+ /**
+ * Clears the adapter to prepare for a new load
+ */
+ open fun reset() {
+ imageAdapter.clear()
+ }
+
+ /**
+ * Optional filter to decide which images get displayed
+ * Defaults to checking their sizes to filter out
+ * very small images such as lurking drawables/icons
+ *
+ * Returns true if model should be displayed, false otherwise
+ */
+ open fun shouldLoad(model: ImageModel): Boolean = model.size > 10000L
+
+ open fun onStatusChange(loaded: Boolean) {}
+
+} \ No newline at end of file
diff --git a/imagepicker/src/main/res-public/values-v21/styles.xml b/imagepicker/src/main/res-public/values-v21/styles.xml
new file mode 100644
index 0000000..bae68da
--- /dev/null
+++ b/imagepicker/src/main/res-public/values-v21/styles.xml
@@ -0,0 +1,9 @@
+<resources>
+
+ <style name="Kau.ImagePicker.Overlay" parent="Kau.Translucent">
+ <item name="android:statusBarColor">@android:color/transparent</item>
+ <item name="android:windowEnterTransition">@transition/kau_image_enter</item>
+ <item name="android:windowReturnTransition">@transition/kau_image_exit_bottom</item>
+ </style>
+
+</resources>
diff --git a/imagepicker/src/main/res-public/values/public.xml b/imagepicker/src/main/res-public/values/public.xml
index 3a1d9c5..a892651 100644
--- a/imagepicker/src/main/res-public/values/public.xml
+++ b/imagepicker/src/main/res-public/values/public.xml
@@ -3,4 +3,5 @@
<public name='kau_blurred_image_selection_overlay' type='color' />
<public name='kau_image_minimum_size' type='dimen' />
<public name='Kau.ImagePicker' type='style' />
+ <public name='Kau.ImagePicker.Overlay' type='style' />
</resources> \ No newline at end of file
diff --git a/imagepicker/src/main/res-public/values/styles.xml b/imagepicker/src/main/res-public/values/styles.xml
index 4d4a135..99f294a 100644
--- a/imagepicker/src/main/res-public/values/styles.xml
+++ b/imagepicker/src/main/res-public/values/styles.xml
@@ -1,7 +1,12 @@
- <resources>
+<resources>
<style name="Kau.ImagePicker">
<item name="android:windowAnimationStyle">@style/KauSlideInSlideOutBottom</item>
</style>
+ <!--Just as a placeholder for public.xml-->
+ <style name="Kau.ImagePicker.Overlay" parent="Kau.Translucent">
+ <item name="android:windowAnimationStyle">@null</item>
+ </style>
+
</resources>
diff --git a/imagepicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml b/imagepicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml
new file mode 100644
index 0000000..a0ce301
--- /dev/null
+++ b/imagepicker/src/main/res/layout-v21/kau_activity_image_picker_overlay.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/kau_draggable"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:dragDismissDistance="@dimen/kau_drag_dismiss_distance_large"
+ app:dragDismissScale="0.95">
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/kau_recyclerview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="@dimen/kau_drag_dismiss_distance"
+ android:background="?android:colorBackground" />
+
+</ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout> \ No newline at end of file
diff --git a/imagepicker/src/main/res/layout/kau_activity_image_picker.xml b/imagepicker/src/main/res/layout/kau_activity_image_picker.xml
index 5b0300d..6d991b0 100644
--- a/imagepicker/src/main/res/layout/kau_activity_image_picker.xml
+++ b/imagepicker/src/main/res/layout/kau_activity_image_picker.xml
@@ -4,6 +4,7 @@
android:id="@+id/kau_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="?android:colorBackground"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
diff --git a/imagepicker/src/main/res/layout/kau_iitem_image_basic.xml b/imagepicker/src/main/res/layout/kau_iitem_image_basic.xml
new file mode 100644
index 0000000..b89e41d
--- /dev/null
+++ b/imagepicker/src/main/res/layout/kau_iitem_image_basic.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ca.allanwang.kau.ui.views.MeasuredImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/kau_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="2dp"
+ android:foreground="@drawable/kau_selectable_white"
+ android:scaleType="centerCrop"
+ app:relativeHeight="1" /> \ No newline at end of file
diff --git a/imagepicker/src/main/res/transition-v21/kau_image_enter.xml b/imagepicker/src/main/res/transition-v21/kau_image_enter.xml
new file mode 100644
index 0000000..447c0c9
--- /dev/null
+++ b/imagepicker/src/main/res/transition-v21/kau_image_enter.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/fast_out_linear_in"
+ android:transitionOrdering="together">
+
+ <slide
+ android:duration="400"
+ android:slideEdge="bottom">
+ <targets android:targetId="@id/kau_draggable" />
+ </slide>
+
+ <fade
+ android:duration="200"
+ android:startDelay="200" />
+
+</transitionSet>
diff --git a/imagepicker/src/main/res/transition-v21/kau_image_exit_bottom.xml b/imagepicker/src/main/res/transition-v21/kau_image_exit_bottom.xml
new file mode 100644
index 0000000..447c0c9
--- /dev/null
+++ b/imagepicker/src/main/res/transition-v21/kau_image_exit_bottom.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/fast_out_linear_in"
+ android:transitionOrdering="together">
+
+ <slide
+ android:duration="400"
+ android:slideEdge="bottom">
+ <targets android:targetId="@id/kau_draggable" />
+ </slide>
+
+ <fade
+ android:duration="200"
+ android:startDelay="200" />
+
+</transitionSet>
diff --git a/imagepicker/src/main/res/transition-v21/kau_image_exit_top.xml b/imagepicker/src/main/res/transition-v21/kau_image_exit_top.xml
new file mode 100644
index 0000000..8d64f48
--- /dev/null
+++ b/imagepicker/src/main/res/transition-v21/kau_image_exit_top.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/fast_out_linear_in"
+ android:transitionOrdering="together">
+
+ <slide
+ android:duration="400"
+ android:slideEdge="top">
+ <targets android:targetId="@id/kau_draggable" />
+ </slide>
+
+ <fade
+ android:duration="200"
+ android:startDelay="200" />
+
+</transitionSet>
diff --git a/imagepicker/src/main/res/values/strings.xml b/imagepicker/src/main/res/values/strings.xml
index 7aa7f3e..17af1d8 100644
--- a/imagepicker/src/main/res/values/strings.xml
+++ b/imagepicker/src/main/res/values/strings.xml
@@ -3,4 +3,5 @@
<string name="kau_no_images_found">No images found</string>
<string name="kau_no_images_selected">No images have been selected</string>
<string name="kau_blurrable_imageview">Blurrable ImageView</string>
+ <string name="kau_no_images_loaded">No images loaded</string>
</resources> \ No newline at end of file
diff --git a/sample/build.gradle b/sample/build.gradle
index b318174..f1a0f10 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -3,6 +3,7 @@ plugins {
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
+apply plugin: 'com.github.triplet.play'
repositories {
jcenter()
@@ -11,6 +12,14 @@ repositories {
maven { url "https://maven.google.com" }
}
+play {
+ jsonFile = file('../files/gplay-keys.json')
+ track = 'beta'
+ errorOnSizeLimit = true
+ uploadImages = false
+ untrackOld = true
+}
+
android {
compileSdkVersion Integer.parseInt(project.TARGET_SDK)
buildToolsVersion project.BUILD_TOOLS
@@ -28,9 +37,24 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
+ signingConfigs {
+
+ def releaseProps = new Properties()
+ file("../files/kau.properties").withInputStream { releaseProps.load(it) }
+
+ release {
+ storeFile file("../files/kau.keystore")
+ storePassword releaseProps.getProperty('storePassword')
+ keyAlias releaseProps.getProperty('keyAlias')
+ keyPassword releaseProps.getProperty('keyPassword')
+ }
+
+ }
+
buildTypes {
release {
minifyEnabled true
+ signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml
index da26bdf..85fb199 100644
--- a/sample/src/main/AndroidManifest.xml
+++ b/sample/src/main/AndroidManifest.xml
@@ -10,12 +10,12 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
+ android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
- android:label="@string/title_activity_main"
+ android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar.Transparent">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -32,6 +32,9 @@
android:name=".ImagePickerActivity"
android:theme="@style/Kau.ImagePicker" />
<activity
+ android:name=".ImagePickerActivityOverlay"
+ android:theme="@style/Kau.ImagePicker.Overlay" />
+ <activity
android:name=".AdapterActivity"
android:theme="@style/Kau.Translucent.SlideBottom" />
</application>
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 abc65b9..abf44d8 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/AnimActivity.kt
@@ -7,13 +7,14 @@ import ca.allanwang.kau.permissions.PERMISSION_ACCESS_COARSE_LOCATION
import ca.allanwang.kau.permissions.PERMISSION_ACCESS_FINE_LOCATION
import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
import ca.allanwang.kau.permissions.kauRequestPermissions
-import ca.allanwang.kau.swipe.SWIPE_EDGE_BOTTOM
+import ca.allanwang.kau.swipe.SWIPE_EDGE_LEFT
import ca.allanwang.kau.swipe.kauSwipeOnCreate
import ca.allanwang.kau.swipe.kauSwipeOnDestroy
import ca.allanwang.kau.swipe.kauSwipeOnPostCreate
import ca.allanwang.kau.utils.fullLinearRecycler
import ca.allanwang.kau.utils.startActivitySlideOut
import ca.allanwang.kau.utils.toast
+import ca.allanwang.kau.utils.withAlpha
import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter
/**
@@ -27,63 +28,10 @@ class AnimActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val adapter = FastItemAdapter<PermissionCheckbox>()
- setContentView(fullLinearRecycler(adapter))
+ setContentView(fullLinearRecycler(adapter).apply { setBackgroundColor(KPrefSample.bgColor.withAlpha(255)) })
+
adapter.add(listOf(
PERMISSION_ACCESS_COARSE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
- PERMISSION_ACCESS_FINE_LOCATION,
PERMISSION_ACCESS_FINE_LOCATION
).map { PermissionCheckbox(it) })
adapter.withOnClickListener { _, _, item, _ ->
@@ -96,7 +44,7 @@ class AnimActivity : AppCompatActivity() {
true
}
kauSwipeOnCreate {
- edgeFlag = SWIPE_EDGE_BOTTOM
+ edgeFlag = SWIPE_EDGE_LEFT
}
}
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePicker.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePicker.kt
new file mode 100644
index 0000000..c7f28bc
--- /dev/null
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePicker.kt
@@ -0,0 +1,11 @@
+package ca.allanwang.kau.sample
+
+import ca.allanwang.kau.imagepicker.ImagePickerActivityBase
+import ca.allanwang.kau.imagepicker.ImagePickerActivityOverlayBase
+
+/**
+ * Created by Allan Wang on 2017-07-23.
+ */
+class ImagePickerActivity : ImagePickerActivityBase()
+
+class ImagePickerActivityOverlay : ImagePickerActivityOverlayBase() \ No newline at end of file
diff --git a/sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePickerActivity.kt b/sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePickerActivity.kt
deleted file mode 100644
index 8a23192..0000000
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/ImagePickerActivity.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package ca.allanwang.kau.sample
-
-import ca.allanwang.kau.imagepicker.ImagePickerActivityBase
-
-/**
- * Created by Allan Wang on 2017-07-23.
- */
-class ImagePickerActivity : ImagePickerActivityBase() \ 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 ecfef04..7ce10af 100644
--- a/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
+++ b/sample/src/main/kotlin/ca/allanwang/kau/sample/MainActivity.kt
@@ -168,6 +168,10 @@ class MainActivity : KPrefActivity() {
onClick = { _, _, _ -> kauLaunchImagePicker(ImagePickerActivity::class.java, REQUEST_IMAGE); false }
}
+ plainText(R.string.gallery_overlay_showcase) {
+ onClick = { _, _, _ -> kauLaunchImagePicker(ImagePickerActivityOverlay::class.java, REQUEST_IMAGE); false }
+ }
+
plainText(R.string.adapter_showcase) {
onClick = { _, _, _ -> startActivity(AdapterActivity::class.java, transition = true); false }
}
diff --git a/sample/src/main/play/contactEmail b/sample/src/main/play/contactEmail
new file mode 100644
index 0000000..3e03392
--- /dev/null
+++ b/sample/src/main/play/contactEmail
@@ -0,0 +1 @@
+pitchedapps@gmail.com \ No newline at end of file
diff --git a/sample/src/main/play/defaultLanguage b/sample/src/main/play/defaultLanguage
new file mode 100644
index 0000000..ffdd217
--- /dev/null
+++ b/sample/src/main/play/defaultLanguage
@@ -0,0 +1 @@
+en-CA \ No newline at end of file
diff --git a/sample/src/main/play/en-CA/listing/fulldescription b/sample/src/main/play/en-CA/listing/fulldescription
new file mode 100644
index 0000000..2d9fe89
--- /dev/null
+++ b/sample/src/main/play/en-CA/listing/fulldescription
@@ -0,0 +1,3 @@
+This app aims to demonstrate the features available in <a href="https://allanwang.github.io/KAU/">KAU</a>, or Kotlin Android Utils.
+
+The project is open sourced on <a href="https://github.com/AllanWang/KAU">github</a> \ No newline at end of file
diff --git a/sample/src/main/play/en-CA/listing/shortdescription b/sample/src/main/play/en-CA/listing/shortdescription
new file mode 100644
index 0000000..9424ee8
--- /dev/null
+++ b/sample/src/main/play/en-CA/listing/shortdescription
@@ -0,0 +1 @@
+A simple showcase for Kotlin Android Utils \ No newline at end of file
diff --git a/sample/src/main/play/en-CA/listing/title b/sample/src/main/play/en-CA/listing/title
new file mode 100644
index 0000000..c3c5422
--- /dev/null
+++ b/sample/src/main/play/en-CA/listing/title
@@ -0,0 +1 @@
+KAU - Library Showcase \ No newline at end of file
diff --git a/sample/src/main/play/en-CA/whatsnew b/sample/src/main/play/en-CA/whatsnew
new file mode 100644
index 0000000..1d15ce2
--- /dev/null
+++ b/sample/src/main/play/en-CA/whatsnew
@@ -0,0 +1 @@
+A full changelog is available in the app \ No newline at end of file
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/src/main/res/mipmap-hdpi/ic_launcher.png
index cde69bc..9b9a9ef 100644
--- a/sample/src/main/res/mipmap-hdpi/ic_launcher.png
+++ b/sample/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 9a078e3..0000000
--- a/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png
+++ /dev/null
Binary files differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher.png b/sample/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index c133a0c..0000000
--- a/sample/src/main/res/mipmap-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index efc028a..0000000
--- a/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png
+++ /dev/null
Binary files differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
index bfa42f0..18b65ef 100644
--- a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
+++ b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 3af2608..0000000
--- a/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png
+++ /dev/null
Binary files differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 324e72c..14f2082 100644
--- a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
+++ b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index 9bec2e6..0000000
--- a/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
+++ /dev/null
Binary files differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index aee44e1..fe0aa98 100644
--- a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
+++ b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index 34947cd..0000000
--- a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
+++ /dev/null
Binary files differ
diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml
index f3880b2..c64b623 100644
--- a/sample/src/main/res/values/strings.xml
+++ b/sample/src/main/res/values/strings.xml
@@ -1,6 +1,5 @@
<resources>
- <string name="app_name">KPrefs</string>
- <string name="title_activity_main">MainActivity</string>
+ <string name="app_name">KAU</string>
<string name="header">This is a header</string>
<string name="desc">This is a description</string>
<string name="checkbox_1">Checkbox 1</string>
@@ -21,6 +20,7 @@
<string name="your_email">your.email@here.com</string>
<string name="your_subject">Your subject</string>
<string name="gallery_showcase">Gallery Showcase</string>
+ <string name="gallery_overlay_showcase">Gallery Overlay Showcase</string>
<string name="adapter_showcase">Adapter Showcase</string>
<string name="about_kau">KAU (Kotlin Android Utils) is a collection of common extension functions and complex UIs that can be used in almost all apps. It is meant to implement the shared components, so you can focus on what makes your app unique.</string>
</resources>
diff --git a/sample/src/main/res/xml/kau_changelog.xml b/sample/src/main/res/xml/kau_changelog.xml
index 76aee36..7ed2073 100644
--- a/sample/src/main/res/xml/kau_changelog.xml
+++ b/sample/src/main/res/xml/kau_changelog.xml
@@ -6,15 +6,22 @@
<item text="" />
-->
- <version title="v3.1"/>
- <item text=":core: Allow for nullable throwables when logging" />
- <item text="" />
- <item text="" />
+ <version title="v3.1.1"/>
+ <item text=":imagepicker: Add uri val to ImageModel" />
+ <item text=":imagepicker: Create bindings and overlay activity" />
+ <item text="Add showcase app to play store" />
<item text="" />
<item text="" />
<item text="" />
<item text="" />
+ <version title="v3.1.0"/>
+ <item text=":core: Allow for nullable throwables when logging" />
+ <item text=":core: Remove some extra DSL annotations" />
+ <item text=":kpref-activity: Bring down to minSdk 19 and fix compatibility" />
+ <item text=":adapter: Update readme for iitems and animators" />
+ <item text=":about: Move strings to private" />
+
<version title="v3.0"/>
<item text=":core: Add setPadding[x]" />
<item text=":core: [breaking] Replace update[x]Margin to setMargin[x]" />