-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #123 from natura-cosmeticos/app-bar-top
DSY-1202 - App Bar Top
- Loading branch information
Showing
13 changed files
with
226 additions
and
189 deletions.
There are no files selected for viewing
149 changes: 86 additions & 63 deletions
149
designsystem/src/main/kotlin/com/natura/android/appbar/AppBar.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,124 @@ | ||
package com.natura.android.appbar | ||
|
||
import android.app.Activity | ||
import android.content.Context | ||
import android.graphics.Color | ||
import android.os.Build | ||
import android.graphics.drawable.Drawable | ||
import android.util.AttributeSet | ||
import android.util.DisplayMetrics | ||
import android.util.TypedValue | ||
import android.view.Gravity | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.view.WindowManager | ||
import android.widget.ImageView | ||
import androidx.appcompat.widget.Toolbar | ||
import com.natura.android.R | ||
import kotlin.math.sqrt | ||
import com.natura.android.ext.setVisibilityFromBoolean | ||
import com.natura.android.badge.BadgeDrawable | ||
|
||
// WIP | ||
class AppBar(context: Context, attrs: AttributeSet) : Toolbar(context, attrs) { | ||
var color: Int | ||
|
||
private lateinit var badgeDrawable: BadgeDrawable | ||
private var showLogo: Boolean | ||
private val logo: ImageView | ||
|
||
init { | ||
context | ||
.theme | ||
.obtainStyledAttributes(attrs, R.styleable.AppBar, 0, 0) | ||
.apply { | ||
try { | ||
color = this.getInt(R.styleable.AppBar_appBarType, 0) | ||
} finally { | ||
recycle() | ||
} | ||
} | ||
} | ||
logo = createLogo(context, attrs) | ||
|
||
override fun onAttachedToWindow() { | ||
super.onAttachedToWindow() | ||
setStatusBarStyle() | ||
val typedValue = context.obtainStyledAttributes(attrs, R.styleable.AppBar) | ||
showLogo = typedValue.getBoolean(R.styleable.AppBar_showLogo, false) | ||
setLogoVisibility() | ||
|
||
this.setBackgroundColor(getThemeColor(getMainColorFromAttrs())) | ||
this.setTitleTextColor(getThemeColor(getMainOnColorFromAttrs())) | ||
addView(logo) | ||
|
||
if (isOnColorTooLight(getThemeColor(getMainOnColorFromAttrs()))) { | ||
setStatusBarIconsLighter() | ||
} else { | ||
setStatusBarIconsDarker() | ||
contentInsetStartWithNavigation = 0 | ||
elevation = getElevationFromTheme(context) | ||
|
||
typedValue.recycle() | ||
} | ||
|
||
private fun setLogoVisibility() { | ||
logo.setVisibilityFromBoolean(showLogo) | ||
|
||
if (showLogo) { | ||
title = "" | ||
} | ||
} | ||
|
||
private fun isOnColorTooLight(color: Int): Boolean { | ||
val rgb = intArrayOf(Color.red(color), Color.green(color), Color.blue(color)) | ||
val brightness = sqrt(rgb[0] * rgb[0] * .241 + (rgb[1] * rgb[1] * .691) + rgb[2] * rgb[2] * .068).toInt() | ||
return brightness >= 200 | ||
fun showLogo() { | ||
showLogo = true | ||
setLogoVisibility() | ||
} | ||
|
||
private fun setStatusBarStyle() { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||
fun hideLogo() { | ||
showLogo = false | ||
setLogoVisibility() | ||
} | ||
|
||
fun addMenuIconBadge(menuIcon: Drawable, initBadgeValue: Int) { | ||
badgeDrawable = BadgeDrawable(context, initBadgeValue, menuIcon) | ||
} | ||
|
||
val context = context as Activity | ||
val window = context.window | ||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) | ||
window.statusBarColor = getThemeColor(getMainColorFromAttrs()) | ||
fun updateBadgeValue(value: Int) { | ||
if (this::badgeDrawable.isInitialized) { | ||
badgeDrawable.updateBadgeDrawable(value) | ||
} | ||
} | ||
|
||
private fun getMainColorFromAttrs(): Int { | ||
return when (color) { | ||
1 -> R.attr.colorPrimary | ||
2 -> R.attr.colorSecondary | ||
3 -> android.R.color.transparent | ||
else -> R.attr.colorSurface | ||
} | ||
private fun createLogo(context: Context, attrs: AttributeSet): ImageView { | ||
val imageView = ImageView(context) | ||
imageView.setImageResource(getLogoResId(context, attrs)) | ||
val logoWidth = getLogoWidthFromTheme(context) | ||
imageView.layoutParams = | ||
LayoutParams(logoWidth, ViewGroup.LayoutParams.WRAP_CONTENT, getLogoAlign(context)) | ||
imageView.visibility = View.GONE | ||
return imageView | ||
} | ||
|
||
private fun getMainOnColorFromAttrs(): Int { | ||
return when (color) { | ||
1 -> R.attr.colorOnPrimary | ||
2 -> R.attr.colorOnSecondary | ||
3 -> R.attr.colorOnSurface | ||
else -> R.attr.colorOnSurface | ||
private fun getLogoAlign(context: Context): Int { | ||
return if (getWindowWidthInPx(context) < MINIMUM_SCREEN_SIZE_FOR_CENTRALIZED_LOGO) { | ||
Gravity.START | ||
} else { | ||
Gravity.CENTER | ||
} | ||
} | ||
|
||
private fun getThemeColor(colorAttr: Int): Int { | ||
val outValue = TypedValue() | ||
context.theme.resolveAttribute(colorAttr, outValue, true) | ||
return outValue.data | ||
private fun getLogoWidthFromTheme(context: Context): Int { | ||
val typedValue = TypedValue() | ||
if (context.theme.resolveAttribute(R.attr.sizeHugeX, typedValue, true)) { | ||
return TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics) | ||
} | ||
|
||
return ViewGroup.LayoutParams.WRAP_CONTENT | ||
} | ||
|
||
private fun setStatusBarIconsDarker() { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
val context = context as Activity | ||
val window = context.window | ||
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | ||
private fun getElevationFromTheme(context: Context): Float { | ||
val typedValue = TypedValue() | ||
if (context.theme.resolveAttribute(R.attr.elevation02, typedValue, true)) { | ||
return TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics).toFloat() | ||
} | ||
|
||
return 0f | ||
} | ||
|
||
private fun setStatusBarIconsLighter() { | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
val context = context as Activity | ||
val window = context.window | ||
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | ||
private fun getLogoResId(context: Context, attrs: AttributeSet): Int { | ||
val typedValue = context.theme | ||
.obtainStyledAttributes(attrs, intArrayOf(R.attr.logoHorizontal), 0, 0) | ||
return typedValue.getResourceId(0, 0) | ||
} | ||
|
||
private fun getWindowWidthInPx(context: Context): Int { | ||
return try { | ||
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager | ||
val metrics = DisplayMetrics() | ||
windowManager.defaultDisplay.getMetrics(metrics) | ||
|
||
metrics.widthPixels | ||
} catch (ex: Exception) { | ||
MINIMUM_SCREEN_SIZE_FOR_CENTRALIZED_LOGO | ||
} | ||
} | ||
|
||
companion object { | ||
private const val MINIMUM_SCREEN_SIZE_FOR_CENTRALIZED_LOGO = 361 | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,4 +13,5 @@ | |
android:icon="@drawable/icon_base_badge" | ||
android:title="notification" | ||
app:showAsAction="always" /> | ||
|
||
</menu> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
...c/androidTest/kotlin/com/natura/android/sample/components/AppBarActivityFunctionalTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.natura.android.sample.components | ||
|
||
import androidx.test.core.app.ActivityScenario | ||
import androidx.test.espresso.Espresso.onView | ||
import androidx.test.espresso.action.ViewActions.click | ||
import androidx.test.espresso.assertion.ViewAssertions.matches | ||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed | ||
import androidx.test.espresso.matcher.ViewMatchers.withId | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import com.natura.android.sample.R | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class AppBarActivityFunctionalTest { | ||
|
||
private lateinit var appBarActivityTest: ActivityScenario<AppBarActivity> | ||
|
||
@Before | ||
fun setup() { | ||
appBarActivityTest = ActivityScenario.launch(AppBarActivity::class.java) | ||
} | ||
|
||
@Test | ||
fun addAndIncrementBadge() { | ||
onView(withId(R.id.btnIncrement)).perform(click()) | ||
onView(withId(R.id.btnIncrement)).perform(click()) | ||
|
||
onView(withId(R.id.appBar)).check(matches(isDisplayed())) | ||
} | ||
|
||
@Test | ||
fun showSearchBar() { | ||
onView(withId(R.id.searchMenuBtn)).perform(click()) | ||
|
||
onView(withId(R.id.appBar)).check(matches(isDisplayed())) | ||
} | ||
} |
Oops, something went wrong.