Skip to content

Commit

Permalink
Move some utility functions to another file
Browse files Browse the repository at this point in the history
Signed-off-by: Mahdi Hosseinzadeh <mdihosseinzadeh@gmail.com>
  • Loading branch information
mahozad committed Aug 1, 2021
1 parent dcbb9c3 commit ce0df1d
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ir.mahozad.android.util

import androidx.test.platform.app.InstrumentationRegistry
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.TestInstance
Expand Down Expand Up @@ -59,4 +60,28 @@ class UtilitiesTest {
arguments(arrayOf("a", "b"), 2, "a"),
arguments(arrayOf("a", "b"), 3, "b"),
)

@DisplayName("Get color array")
@ParameterizedTest(name = "Test #{index} with attr: {0}")
@MethodSource("argumentProvider3")
fun getColorArray(themeId: Int, expectedColorArray: IntArray?) {
val resources = InstrumentationRegistry.getInstrumentation().targetContext.resources
val context = InstrumentationRegistry.getInstrumentation().targetContext
context.setTheme(themeId)
val testTheme = context.theme
val typedArray = testTheme.obtainStyledAttributes(ir.mahozad.android.test.R.styleable.TestStyleable)

val array = getColorArray(typedArray, resources, ir.mahozad.android.test.R.styleable.TestStyleable_testAttr1)

assertThat(array).isEqualTo(expectedColorArray)
}

private fun argumentProvider3() = listOf(
arguments(ir.mahozad.android.test.R.style.TestStyleNotDefined, null),
arguments(ir.mahozad.android.test.R.style.TestStyleEmptyAttribute, null),
arguments(ir.mahozad.android.test.R.style.TestStyleAtNullAttribute, null),
arguments(ir.mahozad.android.test.R.style.TestStyleColorLiteral, intArrayOf(-256)),
arguments(ir.mahozad.android.test.R.style.TestStyleColorReference, intArrayOf(-65281)),
arguments(ir.mahozad.android.test.R.style.TestStyleColorArrayReference, intArrayOf(-16732632, 1593880136, -5363457, -15628033))
)
}
6 changes: 6 additions & 0 deletions piechart/src/androidTest/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TestStyleable">
<attr name="testAttr1" format="reference|color"/>
</declare-styleable>
</resources>
9 changes: 9 additions & 0 deletions piechart/src/androidTest/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<resources>
<color name="testColor">#f0f</color>
<array name="testColorArray">
<item>#ff00AE28</item>
<item>#5F00aE48</item>
<item>#AE28ff</item>
<item>#18f</item>
</array>
</resources>
26 changes: 26 additions & 0 deletions piechart/src/androidTest/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<resources>

<style name="TestStyleNotDefined">
</style>

<style name="TestStyleEmptyAttribute">
<item name="testAttr1"/>
</style>

<style name="TestStyleAtNullAttribute">
<item name="testAttr1">@null</item>
</style>

<style name="TestStyleColorLiteral">
<item name="testAttr1">#ff0</item>
</style>

<style name="TestStyleColorReference">
<item name="testAttr1">@color/testColor</item>
</style>

<style name="TestStyleColorArrayReference">
<item name="testAttr1">@array/testColorArray</item>
</style>

</resources>
43 changes: 3 additions & 40 deletions piechart/src/main/kotlin/ir/mahozad/android/PieChart.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ir.mahozad.android

import android.content.Context
import android.content.res.Resources
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
Expand Down Expand Up @@ -29,6 +28,8 @@ import ir.mahozad.android.component.*
import ir.mahozad.android.component.DrawDirection.LTR
import ir.mahozad.android.component.Icon
import ir.mahozad.android.util.calculatePieDimensions
import ir.mahozad.android.util.getColorArray
import ir.mahozad.android.util.getIconTint
import ir.mahozad.android.util.parseBorderDashArray
import java.text.NumberFormat

Expand Down Expand Up @@ -642,7 +643,7 @@ class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs) {
legendsPercentageSize = it.getDimension(R.styleable.PieChart_legendsPercentageSize, spToPx(DEFAULT_LEGENDS_PERCENTAGE_SIZE))
legendsPercentageColor = it.getColor(R.styleable.PieChart_legendsPercentageColor, DEFAULT_LEGENDS_PERCENTAGE_COLOR)
centerLabelIconTint = getIconTint(it, R.styleable.PieChart_centerLabelIconTint)
legendIconsTintArray = getColorArray(it, R.styleable.PieChart_legendIconsTint)
legendIconsTintArray = getColorArray(it, resources, R.styleable.PieChart_legendIconsTint)
legendsMargin = it.getDimension(R.styleable.PieChart_legendsMargin, dpToPx(DEFAULT_LEGENDS_MARGIN))
legendsColor = it.getColor(R.styleable.PieChart_legendsColor, DEFAULT_LEGENDS_COLOR)
legendBoxBackgroundColor = it.getColor(R.styleable.PieChart_legendBoxBackgroundColor, DEFAULT_LEGEND_BOX_BACKGROUND_COLOR)
Expand Down Expand Up @@ -714,44 +715,6 @@ class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs) {
return if (fontId == -1) defaultFont else ResourcesCompat.getFont(context, fontId)!!
}

private fun getIconTint(typedArray: TypedArray, @StyleableRes attrName: Int): Int? {
// Do not use -1 as no color; -1 is white: https://stackoverflow.com/a/30430194
val tint = typedArray.getColor(attrName, /* if user specified no value or @null */ Int.MAX_VALUE)
return if (tint == Int.MAX_VALUE) null else tint
}

/**
* Test cases: "", "@null", "#ff0", "@color/sampleColor", "@array/sampleColorArray", attribute omitted from xml
*/
@ColorInt
private fun getColorArray(typedArray: TypedArray, @StyleableRes attrName: Int): IntArray? {
val arrayId = typedArray.getResourceId(attrName, -1)
if (arrayId != -1) {
// If the attribute value is a reference to a resource...
try {
return resources.getIntArray(arrayId)
} catch (e: Resources.NotFoundException) {
// if it was not reference to a color array, it is a reference to a color
/*val color = resources.getColor(arrayId)
return intArrayOf(color)*/
val color = getIconTint(typedArray, attrName)
if (color != null) {
return intArrayOf(color)
} else {
return null
}
}
} else {
// If the attribute value is a literal color value...
val color = getIconTint(typedArray, attrName)
if (color != null) {
return intArrayOf(color)
} else {
return null
}
}
}

/**
* This method is called when your view is first assigned a size, and again
* if the size of your view changes for any reason.
Expand Down
35 changes: 35 additions & 0 deletions piechart/src/main/kotlin/ir/mahozad/android/util/Utilities.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package ir.mahozad.android.util

import android.content.res.Resources
import android.content.res.TypedArray
import androidx.annotation.ColorInt
import androidx.annotation.StyleableRes
import ir.mahozad.android.PieChart
import ir.mahozad.android.PieChart.LegendPosition.*
import ir.mahozad.android.component.Paddings
Expand Down Expand Up @@ -42,3 +46,34 @@ internal fun <T> Array<T>?.getElementCircular(index: Int) = when {
this == null || isEmpty() -> null
else -> this[index % size]
}

internal fun getIconTint(typedArray: TypedArray, @StyleableRes attrName: Int): Int? {
// Do not use -1 as no color; -1 is white: https://stackoverflow.com/a/30430194
val tint = typedArray.getColor(attrName, /* if user specified no value or @null */ Int.MAX_VALUE)
return if (tint == Int.MAX_VALUE) null else tint
}

@ColorInt
internal fun getColorArray(typedArray: TypedArray, resources: Resources, @StyleableRes attrName: Int): IntArray? {
val arrayId = typedArray.getResourceId(attrName, -1)
if (arrayId != -1) {
// If the attribute value is a reference to a resource...
try {
return resources.getIntArray(arrayId)
} catch (e: Resources.NotFoundException) {
// If it didn't reference a color array, it is a reference to a color
val color = getIconTint(typedArray, attrName)
return when {
color != null -> intArrayOf(color)
else -> null
}
}
} else {
// If the attribute value is a literal color value...
val color = getIconTint(typedArray, attrName)
return when {
color != null -> intArrayOf(color)
else -> null
}
}
}

0 comments on commit ce0df1d

Please sign in to comment.