Skip to content

Commit

Permalink
Merge pull request #109 from natura-cosmeticos/short-cut
Browse files Browse the repository at this point in the history
[DSY-864] Shortcut
  • Loading branch information
gsleonel authored Jul 24, 2020
2 parents f5441e7 + 53f1437 commit 5c653b8
Show file tree
Hide file tree
Showing 28 changed files with 851 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,4 @@ And:
- Menu
- Navigation View
- Text Field
- [Shortcut](doc/shortcut.md)
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ ext {
materialVersion = '1.1.0'
espressoIntentsVersion = '3.1.0'
mockKVersion = '1.10.0'
coreKTXVersion = '1.3.0'
}
3 changes: 2 additions & 1 deletion designsystem/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.android.material:material:$rootProject.materialVersion"
implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayout"

implementation "androidx.core:core-ktx:$rootProject.coreKTXVersion"
testImplementation "junit:junit:$rootProject.junitVersion"
testImplementation "androidx.test.ext:truth:$rootProject.truthVersion"
testImplementation "androidx.test:runner:$rootProject.androidXTestVersion"
testImplementation "androidx.test:core-ktx:$rootProject.testCoreKtxVersion"
testImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
testImplementation "org.robolectric:robolectric:$rootProject.robolectricVersion"
testImplementation "io.mockk:mockk:$rootProject.mockKVersion"
}

androidExtensions {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.natura.android.exceptions

import java.lang.IllegalArgumentException

class MissingThemeException :
IllegalArgumentException("⚠️ ⚠️ Missing DS Theme. You are using a DS component without setting a DS Theme. You MUST set a DS theme at the component or in a parent view")
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.natura.android.extensions

import android.os.Build
import android.widget.TextView

fun TextView.setAppearance(textAppearance: Int) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
this.setTextAppearance(context, textAppearance)
} else {
this.setTextAppearance(textAppearance)
}
}
179 changes: 179 additions & 0 deletions designsystem/src/main/kotlin/com/natura/android/shortcut/Shortcut.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package com.natura.android.shortcut

import android.content.Context
import android.content.res.TypedArray
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.content.res.getIntOrThrow
import androidx.core.content.res.getResourceIdOrThrow
import androidx.core.content.res.getStringOrThrow
import androidx.core.graphics.drawable.DrawableCompat
import com.natura.android.R
import com.natura.android.exceptions.MissingThemeException
import com.natura.android.extensions.setAppearance

class Shortcut @JvmOverloads constructor(
context: Context,
private val attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

private var labelAttribute: String? = null
private var typeAttribute: Int? = null
private var backgroundColorResourceAttribute = 0
private var iconColorResourceAttribute = 0
private var labelTextAppearanceResourceAttribute = 0
private var iconAttribute: Int? = null
private var shortcutAttributesArray: TypedArray

private val labelContainer by lazy { findViewById<TextView>(R.id.shortCutLabel) }
private val backgroundContainer by lazy { findViewById<LinearLayout>(R.id.shortcutBackground) }
private val iconContainer by lazy { findViewById<ImageView>(R.id.shortCutIcon) }

init {
try {
View.inflate(context, R.layout.shortcut, this)
} catch (e: Exception) {
throw (MissingThemeException())
}

shortcutAttributesArray = context.obtainStyledAttributes(attrs, R.styleable.Shortcut)

getShortcutAttributes()
getAttributesFromTheme()
configureShortCutByType(typeAttribute)

shortcutAttributesArray.recycle()
}

fun setLabel(text: String?) {
labelContainer.text = text
labelContainer.setAppearance(labelTextAppearanceResourceAttribute)
}

fun getLabel(): CharSequence? {
return labelContainer.text
}

fun getType(): Int? = typeAttribute

fun setIcon(icon: Int?) {
icon?.apply {
iconContainer.setImageResource(icon)
iconContainer.setColorFilter(ContextCompat.getColor(context, iconColorResourceAttribute), android.graphics.PorterDuff.Mode.SRC_IN)
}
}

fun getIcon(): ImageView {
return iconContainer
}

private fun getAttributesFromTheme() {
try {
if (typeAttribute == CONTAINED) {
setContainedTypeAttributes()
} else {
setOutlinedTypeAttributes()
}
} catch (e: Exception) {
throw (MissingThemeException())
}
}

private fun setContainedTypeAttributes() {
context
.theme
.obtainStyledAttributes(
attrs,
R.styleable.Shortcut,
R.attr.shortcutContained,
0
)
.apply {
backgroundColorResourceAttribute = this.getResourceIdOrThrow(R.styleable.Shortcut_colorBackground)
iconColorResourceAttribute = this.getResourceIdOrThrow(R.styleable.Shortcut_colorIcon)
labelTextAppearanceResourceAttribute = this.getResourceIdOrThrow(R.styleable.Shortcut_labelAppearance)
}
}

private fun setOutlinedTypeAttributes() {
context
.theme
.obtainStyledAttributes(attrs, R.styleable.Shortcut, R.attr.shortcutOutlined, 0)
.apply {
backgroundColorResourceAttribute = this.getResourceIdOrThrow(R.styleable.Shortcut_colorBackground)
iconColorResourceAttribute = this.getResourceIdOrThrow(R.styleable.Shortcut_colorIcon)
labelTextAppearanceResourceAttribute = this.getResourceIdOrThrow(R.styleable.Shortcut_labelAppearance)
}
}

private fun getShortcutAttributes() {
getLabelAttribute()
getIconAttribute()
getTypeAttribute()
}

private fun getTypeAttribute() {
try {
typeAttribute = shortcutAttributesArray.getIntOrThrow(R.styleable.Shortcut_type)
} catch (e: Exception) {
throw (IllegalArgumentException("⚠️ ⚠️ Missing shortcut required argument. You MUST set the shortcut type(contained or outlined).", e))
}
}

private fun getIconAttribute() {
try {
iconAttribute = shortcutAttributesArray.getResourceIdOrThrow(R.styleable.Shortcut_icon)
} catch (e: Exception) {
throw (IllegalArgumentException("⚠️ ⚠️ Missing shortcut required argument. You MUST set the shortcut icon(drawable).", e))
}
}

private fun getLabelAttribute() {
try {
labelAttribute = shortcutAttributesArray.getStringOrThrow(R.styleable.Shortcut_textLabel)
} catch (e: Exception) {
throw (IllegalArgumentException("⚠️ ⚠️ Missing shortcut required argument. You MUST set the shortcut label(string).", e))
}
}

private fun configureShortCutByType(type: Int?) {
type?.apply {
setLabel(labelAttribute)
setIcon(iconAttribute)

when (this) {
CONTAINED -> setBackgroundContained()
OUTLINED -> setBackgroundOutlined()
}
}
}

private fun setBackgroundContained() {
val background = resources.getDrawable(R.drawable.shortcut_background, null)
val backgroundWrap = DrawableCompat.wrap(background).mutate()
DrawableCompat.setTint(backgroundWrap, ContextCompat.getColor(context, backgroundColorResourceAttribute))

backgroundContainer.background = background
}

private fun setBackgroundOutlined() {
val background = resources.getDrawable(R.drawable.shortcut_background, null) as GradientDrawable
background.setColor(ContextCompat.getColor(context, backgroundColorResourceAttribute))
background.setStroke(1, ContextCompat.getColor(context, iconColorResourceAttribute))

backgroundContainer.background = background
backgroundContainer.elevation = 0F
}

companion object {
const val OUTLINED = 0
const val CONTAINED = 1
}
}
6 changes: 6 additions & 0 deletions designsystem/src/main/res/drawable/shortcut_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FFFFFF"/>
<stroke android:color="#333333" android:width="1dp"/>
</shape>
12 changes: 12 additions & 0 deletions designsystem/src/main/res/drawable/shortcut_ripple_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorHighlightOpacity05">
<item
android:id="@android:id/mask"
android:gravity="center">
<shape android:shape="oval">
<solid android:color="@android:color/white"/>
</shape>
</item>
</ripple>
61 changes: 61 additions & 0 deletions designsystem/src/main/res/layout/shortcut.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<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/shortcutMainContainer"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:layout_marginStart="?spacingSmall"
android:layout_marginEnd="?spacingSmall"
tools:theme="@style/Theme.Natura">

<LinearLayout
android:id="@+id/shortcutRippleBackground"
android:layout_width="?sizeMediumX"
android:layout_height="?sizeMediumX"
android:background="@drawable/shortcut_ripple_background"
android:orientation="horizontal"
android:elevation="?elevation04"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/shortcutBackground" />

<LinearLayout
android:id="@+id/shortcutBackground"
android:layout_width="?sizeMediumX"
android:layout_height="?sizeMediumX"
android:background="@drawable/shortcut_background"
android:gravity="center"
android:orientation="vertical"
android:elevation="?elevation02"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:backgroundTint="?colorPrimary">

<ImageView
android:id="@+id/shortCutIcon"
android:layout_width="?sizeSemi"
android:layout_height="?sizeSemi"
tools:srcCompat="@drawable/ds_ic_filled_brand_naturarosacea" />
</LinearLayout>

<TextView
android:id="@+id/shortCutLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="?spacingTiny"
android:textAlignment="center"
tools:text="Shortcut big label to check the behavior"
android:textAppearance="?textAppearanceCaption"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintTop_toBottomOf="@+id/shortcutBackground"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
11 changes: 11 additions & 0 deletions designsystem/src/main/res/values/ds_attrs.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Shortcut" >
<attr name="type" format="enum">
<enum name="outlined" value="0"/>
<enum name="contained" value="1"/>
</attr>
<attr name="colorBackground" format="color"/>
<attr name="colorIcon" format="color"/>
<attr name="labelAppearance" format="reference"/>
<attr name="textLabel" format="string"/>
<attr name="icon" format="reference"/>
</declare-styleable>

<declare-styleable name="AppBar" >
<attr name="appBarType" format="enum">
Expand Down
5 changes: 5 additions & 0 deletions designsystem/src/main/res/values/ds_base_attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

<attr name="colorHighEmphasisOpacity06" format="color"/>
<attr name="colorMediumEmphasisOpacity06" format="color"/>
<attr name="colorHighlightOpacity05" format="color"/>

<!-- spacing tokens attributes -->
<attr name="spacingNone" format="dimension"/>
Expand Down Expand Up @@ -108,4 +109,8 @@

<!-- Dialog references -->
<attr name="dialogStandardTheme" format="reference"/>

<!-- Shortcut references -->
<attr name="shortcutOutlined" format="reference"/>
<attr name="shortcutContained" format="reference"/>
</resources>
8 changes: 8 additions & 0 deletions designsystem/src/main/res/values/ds_base_themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

<item name="colorHighEmphasisOpacity06">#51333333</item>
<item name="colorMediumEmphasisOpacity06">#51777777</item>
<item name="colorHighlightOpacity05">#3D000000</item>

<item name="spacingNone">@dimen/ds_spacing_none</item>
<item name="spacingMicro">@dimen/ds_spacing_micro</item>
Expand Down Expand Up @@ -116,6 +117,9 @@
<item name="toolbarDefaultTheme">@style/Theme.DS.Toolbar</item>

<item name="dialogStandardTheme">@style/Theme.DS.Dialog.Standard</item>

<item name="shortcutContained">@style/Widget.DS.Shortcut.Contained</item>
<item name="shortcutOutlined">@style/Widget.DS.Shortcut.Outlined</item>
</style>

<style name="Theme.DsBaseDark" parent="Theme.MaterialComponents.DayNight">
Expand Down Expand Up @@ -146,6 +150,7 @@

<item name="colorHighEmphasisOpacity06">#51FAFAFA</item>
<item name="colorMediumEmphasisOpacity06">#51BBBBBB</item>
<item name="colorHighlightOpacity05">#3DFFFFFF</item>

<item name="spacingNone">@dimen/ds_spacing_none</item>
<item name="spacingMicro">@dimen/ds_spacing_micro</item>
Expand Down Expand Up @@ -233,5 +238,8 @@
<item name="toolbarHeight">@dimen/ds_toolbar_height</item>

<item name="dialogStandardTheme">@style/Theme.DS.Dialog.Standard</item>

<item name="shortcutContained">@style/Widget.DS.Shortcut.Contained</item>
<item name="shortcutOutlined">@style/Widget.DS.Shortcut.Outlined</item>
</style>
</resources>
Loading

0 comments on commit 5c653b8

Please sign in to comment.