<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mynor Meza</title>
    <description>The latest articles on DEV Community by Mynor Meza (@mynormeza).</description>
    <link>https://dev.to/mynormeza</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F300408%2F4ff23fc8-714b-428b-ad61-98f6fbcfa5a7.png</url>
      <title>DEV Community: Mynor Meza</title>
      <link>https://dev.to/mynormeza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mynormeza"/>
    <language>en</language>
    <item>
      <title>How to get Darker shadows on Android</title>
      <dc:creator>Mynor Meza</dc:creator>
      <pubDate>Thu, 20 Jan 2022 17:15:31 +0000</pubDate>
      <link>https://dev.to/mynormeza/how-to-get-darker-shadows-on-android-2ij6</link>
      <guid>https://dev.to/mynormeza/how-to-get-darker-shadows-on-android-2ij6</guid>
      <description>&lt;p&gt;A blog post about shadows might be an old topic but it never hurts to revisit it and put it out there, especially for newcomers to Android development.&lt;/p&gt;

&lt;p&gt;I am sure you know you can get Android components to have a shadow by using the &lt;code&gt;elevation&lt;/code&gt; property, this one works on components that have backgrounds such as buttons (if the component doesn't have background there will be no shadow), this shadow is provided to components by the system, that is why there are things that you can't modify from it but others can be changed such as the transparency of the shadow, you can achieve this with the theme attributes called &lt;code&gt;ambientShadowAlpha&lt;/code&gt; and &lt;code&gt;spotShadowAlpha&lt;/code&gt; these ones are float numbers that are normally below 0.25, which makes the shadow a bit hard to see on light backgrounds. These are theme attributes so you can set them in your theme like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;style name="Theme.Shadows" parent="Theme.MaterialComponents.DayNight.DarkActionBar"&amp;gt;
    ....
    &amp;lt;!-- Customize your theme here. --&amp;gt;
    &amp;lt;item name="android:ambientShadowAlpha"&amp;gt;1&amp;lt;/item&amp;gt;
    &amp;lt;item name="android:spotShadowAlpha"&amp;gt;1&amp;lt;/item&amp;gt;
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an example of how it looks when modifying theses attributes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsht9z0xvutmdjqpnmi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsht9z0xvutmdjqpnmi0.png" alt="Both attributes to 1"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dsy9u8ebbd36yg45yfv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5dsy9u8ebbd36yg45yfv.png" alt="Only ambientShadowAlpha"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95xmronp52h4xim9zx7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95xmronp52h4xim9zx7l.png" alt="Only spotShadowAlpha"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;First image: Both attributes to 1, Second image: only &lt;code&gt;ambientShadowAlpha&lt;/code&gt; to 1, Third image: only &lt;code&gt;spotShadowAlpha&lt;/code&gt; to 1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can play around with these two attributes and use them as best suits your case, keep in mind that if you apply this to the app theme, it will affect all shadows that are set through &lt;code&gt;elevation&lt;/code&gt; in your app/activity, depending on how you are using your themes, and &lt;strong&gt;you can't apply this through widgets styles&lt;/strong&gt; such as &lt;code&gt;buttonStyles&lt;/code&gt; or &lt;code&gt;materialButtonStyles&lt;/code&gt; in the theme or directly through the style attribute.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to know more about these attributes I'll leave some references at the end of this post.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Changing alpha shadow for specific components
&lt;/h2&gt;

&lt;p&gt;Since you cannot apply these attributes to a layout to affect small part of a screen, there are other 2 attributes that might help you change the shadow transparency of a specific component these are &lt;code&gt;outlineSpotShadowColor&lt;/code&gt; and &lt;code&gt;outlineAmbientShadowColor&lt;/code&gt; but keep in mind that &lt;strong&gt;they only work on API level 28 or higher&lt;/strong&gt;, with the help of these 2 and setting both &lt;code&gt;ambientShadowAlpha&lt;/code&gt; and &lt;code&gt;spotShadowAlpha&lt;/code&gt; to 1 you can change the transparency of the shadow for single components by setting a color that already includes transparency.&lt;/p&gt;

&lt;p&gt;You can get it like this, by using a helper function to make the color have opacity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;button.outlineAmbientShadowColor = getColorWithAlpha(ContextCompat.getColor(this, R.color.black), 50f)

button.outlineSpotShadowColor = getColorWithAlpha(ContextCompat.getColor(this, R.color.black), 50f)
And of course with this attribute you can change the color of the shadow:
val button2 = findViewById&amp;lt;Button&amp;gt;(R.id.button_test_2)
button2.outlineAmbientShadowColor = getColorWithAlpha(Color.GREEN, 50f)

button2.outlineSpotShadowColor = getColorWithAlpha(Color.GREEN, 50f)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c09gkivb18z3apnlb8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c09gkivb18z3apnlb8t.png" alt="Colored shadow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always remember that there is an attribute called &lt;code&gt;stateListAnimator&lt;/code&gt; that controls the shadow of the component, if you ever tried to change the &lt;code&gt;elevation&lt;/code&gt; of a button and it doesn't work, check the &lt;code&gt;stateListAnimator&lt;/code&gt; of that button. For example, the definition of &lt;code&gt;stateListAnimator&lt;/code&gt; for buttons that comes with MaterialTheme (at the the moment of writing this post) sets the enable/base state like this:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Base state (enabled, not pressed) --&amp;gt;
&amp;lt;item android:state_enabled="true"&amp;gt;
  &amp;lt;set&amp;gt;
    &amp;lt;objectAnimator
        android:duration="@integer/mtrl_btn_anim_duration_ms"
        android:propertyName="translationZ"
        android:startDelay="@integer/mtrl_btn_anim_delay_ms"
        android:valueTo="@dimen/mtrl_btn_z"
        android:valueType="floatType"
        tools:ignore="UnusedAttribute"/&amp;gt;
    &amp;lt;objectAnimator
        android:duration="0"
        android:propertyName="elevation"
        android:valueTo="@dimen/mtrl_btn_elevation"
        android:valueType="floatType"/&amp;gt;
  &amp;lt;/set&amp;gt;
&amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The main reason for this attribute is to control the animation based on state, like press, hover, enable state. This sets the &lt;code&gt;elevation&lt;/code&gt; to be &lt;code&gt;2dp&lt;/code&gt; and &lt;code&gt;translationZ&lt;/code&gt; to be &lt;code&gt;0dp&lt;/code&gt;, you can create your own custom state list animator, and can set it to your &lt;code&gt;buttonStyles&lt;/code&gt;, &lt;code&gt;materialButtonStyles&lt;/code&gt;, through the app theme or individually to single components. This is not only for buttons there are many components where you can use this attribute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Custom shadows
&lt;/h2&gt;

&lt;p&gt;If you really need to change shadows for one specific component only, please take a look at this blog post:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/mynormeza/simple-custom-shadow-on-android-2eh2"&gt;Simple custom shadow on Android&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources &amp;amp; Credits
&lt;/h2&gt;

&lt;p&gt;Shadows seem like a simple subject but there is actually a lot behind it, I'm not going to give deeper explanations but if you want to dig further you can take a look a these blog posts:&lt;br&gt;
&lt;a href="https://seebrock3r.medium.com/playing-with-elevation-in-android-91af4f3be596" rel="noopener noreferrer"&gt;Playing with elevation in Android&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/android-news/mastering-shadows-in-android-e883ad2c9d5b" rel="noopener noreferrer"&gt;Mastering Shadows in Android&lt;/a&gt;&lt;br&gt;
&lt;a href="https://magdamiu.com/2017/03/27/android-transparent-colors/" rel="noopener noreferrer"&gt;Colors with Alpha&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>programming</category>
      <category>mobile</category>
      <category>design</category>
    </item>
    <item>
      <title>Simple custom shadow on Android</title>
      <dc:creator>Mynor Meza</dc:creator>
      <pubDate>Thu, 20 Jan 2022 17:07:21 +0000</pubDate>
      <link>https://dev.to/mynormeza/simple-custom-shadow-on-android-2eh2</link>
      <guid>https://dev.to/mynormeza/simple-custom-shadow-on-android-2eh2</guid>
      <description>&lt;p&gt;There might be some rare specific cases when &lt;code&gt;elevation&lt;/code&gt; is not enough. In this post we are going to see how to create a custom shadow wrapper in a fast-easy way, using Drawables. At the end of this post you will be able to set a custom shadow for a single component such as an image, I will leave a link to the GitHub repo at the end.&lt;/p&gt;

&lt;p&gt;The first thing we will need is a wrapper layout that will represent and eventually draw the shadow, sticking to an image example, we want to put the &lt;code&gt;ImageView&lt;/code&gt; inside the wrapper layout like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;FrameLayout
    android:id="@+id/wrapper"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="30dp"
    android:padding="14dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"&amp;gt;

    &amp;lt;ImageView
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:src="@drawable/test" /&amp;gt;
&amp;lt;/FrameLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this is set we can start working on the shadow itself, on the fragment or activity we’ll get a reference to the wrapper view and add the shadow using Kotlin code. The main class that provides the shadow is a &lt;code&gt;ShapeDrawable&lt;/code&gt;, we are going to create an object of this class and later we will later set it as &lt;code&gt;background&lt;/code&gt; for the wrapper view. This class has a function called &lt;code&gt;setShadowLayer&lt;/code&gt;, this allows us to set &lt;strong&gt;blur, offsets and color&lt;/strong&gt; of the shadow. The blur option is the one that controls how “big” or how much the shadow spreads around the child view, ideally &lt;strong&gt;this should be a bit smaller than the padding we set to the wrapper view&lt;/strong&gt; so that the shadow does not cut off. So in this case we’ll take the padding and subtract &lt;code&gt;4dp&lt;/code&gt; to get the shadow’s blur value like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val shadowColorValue = ContextCompat.getColor(context, R.color.teal)
val shapeDrawable = ShapeDrawable()
shapeDrawable.setTint(shadowColorValue)

val shadowBlur = view.paddingBottom - 4.toDp(resources)

shapeDrawable.paint.setShadowLayer(
    shadowBlur.toFloat(), //blur
    0f, //dx
    0f, //dy
    getColorWithAlpha(shadowColorValue, 0.8f) //color
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Here we set a color with 80% opacity for the shadow, and set the same color but with no opacity to the shape itself using the &lt;code&gt;setTint&lt;/code&gt; function. If we don’t set color for the shape to be the same as the shadow we might get a black color around the image when using &lt;code&gt;dy&lt;/code&gt; or &lt;code&gt;dx&lt;/code&gt; options.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we want the shadow to have shape, we can use a &lt;code&gt;RoundRectShape&lt;/code&gt; to mold the shadow, this &lt;code&gt;RoundRectShape&lt;/code&gt; takes an array with 8 float values that represent the corners of a rect, each corner takes 2 values, you can play around with each corner values in case you want to get a particular shape. If you don’t want the shadow to have a shape or rounded corners you can omit this part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val radius = 4.toDp(view.context.resources)
val outerRadius = floatArrayOf(
    radius, radius, //top-left
    radius, radius, //top-right
    radius, radius, //bottom-right
    radius, radius  //bottom-left
)
shapeDrawable.shape = RoundRectShape(outerRadius, null, null)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, if we set the &lt;code&gt;shapeDrawable&lt;/code&gt; as &lt;code&gt;background&lt;/code&gt; to the wrapper layout, the shadow won’t be visible, we need to add inset with the help of a &lt;code&gt;LayerDrawable&lt;/code&gt;, ideally the inset will be the same as the padding of the wrapper view, &lt;strong&gt;this can’t be smaller than padding of the wrapper view&lt;/strong&gt;, so that the &lt;code&gt;shapeDrawable&lt;/code&gt; itself stays behind the ImageView and only the shadow is visible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val drawable = LayerDrawable(arrayOf&amp;lt;Drawable&amp;gt;(shapeDrawable))
val inset = view.paddingBottom 
drawable.setLayerInset(
    0,
    inset,
    inset,
    inset,
    inset
)
view.background = drawable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is the final result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhut29irp65wzhvs3sjhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhut29irp65wzhvs3sjhd.png" alt="Shadow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we’d like, we can set padding for the wrapper layout to the sides where we’d like the shadow to be visible, for example if we only want the shadow to be at the bottom and right, we could only set &lt;code&gt;paddingBottom&lt;/code&gt; and &lt;code&gt;paddingRight&lt;/code&gt; on the wrapper layout, but that is not the best solution, lets see a better option.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using the offsets options in the &lt;code&gt;setShadowLayer&lt;/code&gt; we can control placement of the shadow, but we’ll need to make a few adjustments like reducing the blur and making use of a &lt;code&gt;BlurMaskFilter&lt;/code&gt; on the &lt;code&gt;shapeDrawable&lt;/code&gt;. This is the code for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;val shadowBlur = view.paddingBottom - 4.toDp(resources)
val offset = 4.toDp(resources)
shapeDrawable.paint.setShadowLayer(
    shadowBlur - offset, //blur
    offset, //dx
    offset, //dy
    getColorWithAlpha(shadowColorValue, 0.8f) //color
)
val filter = BlurMaskFilter(offset, BlurMaskFilter.Blur.OUTER)
view.setLayerType(View.LAYER_TYPE_SOFTWARE, shapeDrawable.paint)
shapeDrawable.paint.maskFilter = filter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These adjustments are needed so that the shadow doesn’t get cut off and draws nicely below the image, all the rest of the code stays the same and the results look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2pbis7rxe042cj929kt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2pbis7rxe042cj929kt8.png" alt="Shadow with offsets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is one easy option to create a custom shadow, if you are in the need of a quick solution this can be of help, specially if you only need to apply it in one specific place/view. Although this example is not reusable and might not be the best solution for you, you can play around with it to see if it can suit your needs, there are also other options to create custom shadows that you can find browsing the web. You can explore and use the best for your case!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mynormeza/custom-shadow" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>programming</category>
      <category>mobile</category>
      <category>design</category>
    </item>
  </channel>
</rss>
