Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ buildscript {

ext {
organization = 'twocoders'
projectWebsite = 'https://github.com/Two-Coders/android-dynamic-componets/'
projectWebsite = 'https://github.com/Two-Coders/android-dynamic-components/'
projectDescription = 'Project containing useful Dynamic components.'
projectLicences = ['MIT']

Expand All @@ -11,14 +11,21 @@ buildscript {
androidTargerSdkVersion = androidCompileSdkVersion

libDynamicColorVersion = '1.0.0'
libDynamicImageCoilVersion = '1.0.0'
libDynamicImageGlideVersion = '1.0.0'
libDynamicImagePicassoVersion = '1.0.0'
libDynamicTextVersion = '3.0.0'

kotlinVersion = '1.4.21'
androidXCoreVersion = '1.3.2'
annotationVersion = '1.1.0'
commonExtensionsVersion = '1.0.0'
coilVersion = '1.1.0'
glideVersion = '4.11.0'
picassoVersion = '2.71828'

junitVersion = '4.13.1'
mockitoVersion = '3.7.0'
androidTestRunnerVersion = '1.3.0'
androidJunitVersion = '1.1.2'
}
Expand Down
6 changes: 0 additions & 6 deletions dynamic/color/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ android {
consumerProguardFiles 'consumer-rules.pro'
}

buildTypes {
release {
minifyEnabled false
}
}

buildFeatures {
dataBinding = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ open class DynamicColor : Parcelable {
parcel.writeInt(attrRes ?: NO_ID)
}

override fun describeContents(): Int {
return 0
}
override fun describeContents() = 0

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
3 changes: 0 additions & 3 deletions dynamic/color/src/main/res/values/strings.xml

This file was deleted.

1 change: 1 addition & 0 deletions dynamic/image-base/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
26 changes: 26 additions & 0 deletions dynamic/image-base/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

android {
compileSdkVersion androidCompileSdkVersion

defaultConfig {
minSdkVersion androidMinSdkVersion
targetSdkVersion androidTargerSdkVersion

consumerProguardFiles 'consumer-rules.pro'
}

buildFeatures {
dataBinding = true
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
implementation "androidx.annotation:annotation:$annotationVersion"
implementation "com.twocoders.extensions:common:$commonExtensionsVersion"
}
Empty file.
1 change: 1 addition & 0 deletions dynamic/image-base/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<manifest package="com.twocoders.dynamic.image.base" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package com.twocoders.dynamic.image.base

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Parcel
import android.os.Parcelable
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import com.twocoders.dynamic.image.base.component.UriComponent
import com.twocoders.extensions.common.NO_ID
import com.twocoders.extensions.common.getDrawable
import com.twocoders.extensions.common.logd

/**
*
* Handy class which can be used to bind image data to views.
* Data can be in [DrawableRes], [Drawable], or [UriComponent] format.
*/
@Suppress("unused", "MemberVisibilityCanBePrivate")
abstract class BaseDynamicImage : Parcelable {

@DrawableRes protected val imageRes: Int?
protected val imageDrawable: Drawable?
protected val imageUri: UriComponent?

protected constructor(
@ColorInt imageRes: Int? = null,
imageDrawable: Drawable? = null,
imageUri: UriComponent? = null
) {
this.imageRes = imageRes
this.imageDrawable = imageDrawable
this.imageUri = imageUri
}

protected constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readDrawable(),
parcel.readParcelable(UriComponent::class.java.classLoader)
)

protected abstract suspend fun getDrawableFromUri(
context: Context,
imageUriComponent: UriComponent
): Drawable?

protected abstract fun getDrawableFromUri(
context: Context,
imageUriComponent: UriComponent,
callback: (drawable: Drawable) -> Unit
)

open suspend fun getDrawable(context: Context): Drawable? {
imageUri?.let { imageUriComponent ->
return getDrawableFromUri(context, imageUriComponent)
}

imageDrawable?.let { drawable ->
return drawable
}

imageRes?.let { res ->
return context.getDrawable(drawableResId = res)
}

return null
}

open fun getDrawable(context: Context, callback: (drawable: Drawable?) -> Unit) {
if (isEmpty()) {
callback(null)
return
}

imageUri?.let { imageUriComponent ->
getDrawableFromUri(context, imageUriComponent, callback)
}

imageDrawable?.let { drawable ->
callback(drawable)
}

imageRes?.let { res ->
context.getDrawable(drawableResId = res)?.let { callback(it) }
}
}

abstract fun loadDrawableInto(imageView: ImageView, withCrossFade: Boolean = false)

fun isEmpty() = imageRes == null && imageDrawable == null && imageUri == null

fun isNotEmpty() = !isEmpty()

override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(imageRes ?: NO_ID)
parcel.writeParcelable(imageDrawable.getParcelable(), flags)
parcel.writeParcelable(imageUri, flags)
}

override fun describeContents() = 0

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as BaseDynamicImage

if (imageRes != other.imageRes) return false
if (imageDrawable != other.imageDrawable) return false
if (imageUri != other.imageUri) return false

return true
}

override fun hashCode(): Int {
var result = imageRes ?: NO_ID
result = 31 * result + imageDrawable.hashCode()
result = 31 * result + imageUri.hashCode()
return result
}
}

private fun Parcel.readDrawable(): Drawable? =
when (val parcelDrawable = readParcelable<Parcelable>(BaseDynamicImage::class.java.classLoader)) {
is Bitmap -> @Suppress("DEPRECATION") BitmapDrawable(parcelDrawable)
else -> null
}

private fun Drawable?.getParcelable(): Parcelable? = when (this) {
is BitmapDrawable -> bitmap
is Drawable -> {
logd("Unsupported $this in imageDrawable for parcel, only BitmapDrawable is supported now.")
null
}
else -> null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.twocoders.dynamic.image.base

import android.widget.ImageView
import androidx.databinding.BindingAdapter

@BindingAdapter(value = ["android:src", "loadWithCrossFade"], requireAll = false)
fun ImageView.loadDynamicImage(image: BaseDynamicImage, withCrossFade: Boolean = false) =
image.loadDrawableInto(this, withCrossFade)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.twocoders.dynamic.image.base.component

import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import androidx.annotation.DrawableRes
import com.twocoders.extensions.common.NO_ID

data class UriComponent(
val image: Uri,
@DrawableRes val errorImage: Int? = null,
@DrawableRes val placeholderImage: Int? = null
) : Parcelable {

constructor(parcel: Parcel) : this(
parcel.readParcelable(Uri::class.java.classLoader)!!,
parcel.readInt(),
parcel.readInt()
)

companion object CREATOR : Parcelable.Creator<UriComponent> {
override fun createFromParcel(parcel: Parcel) = UriComponent(parcel)
override fun newArray(size: Int): Array<UriComponent?> = arrayOfNulls(size)
}

override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeParcelable(image, flags)
parcel.writeInt(errorImage ?: NO_ID)
parcel.writeInt(placeholderImage ?: NO_ID)
}

override fun describeContents() = 0
}
1 change: 1 addition & 0 deletions dynamic/image-coil/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
58 changes: 58 additions & 0 deletions dynamic/image-coil/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

ext.bintrayPublishVersion = libDynamicImageCoilVersion
apply from: '../../bintray-publish-config.gradle'

android {
compileSdkVersion androidCompileSdkVersion

defaultConfig {
minSdkVersion androidMinSdkVersion
targetSdkVersion androidTargerSdkVersion
versionName libDynamicImageCoilVersion

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}

buildFeatures {
dataBinding = true
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}

testOptions {
unitTests {
returnDefaultValues = true
includeAndroidResources = true
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

api project(':dynamic:image-base')

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
implementation "androidx.annotation:annotation:$annotationVersion"
implementation "androidx.core:core-ktx:$androidXCoreVersion"
implementation "com.twocoders.extensions:common:$commonExtensionsVersion"

implementation "io.coil-kt:coil:$coilVersion"

androidTestImplementation "androidx.test:runner:$androidTestRunnerVersion"
androidTestImplementation "androidx.test.ext:junit:$androidJunitVersion"
androidTestImplementation "org.mockito:mockito-android:$mockitoVersion"

testImplementation "junit:junit:$junitVersion"
}
Empty file.
Loading