How can we specify a TextView's shadowDx/Dy/Radius values in dip? Right now I have:
<style name="foo">
<item name="android:shadowDx">-1</item>
<item name="android:shadowDy">-1</item>
<item name="android:shadowRadius">1</item>
</style>
I can't seem to specify "1dip" in these places. Is there a way to do it other than setting them in code and doing the device density multiplication ourselves?
Thanks
I made an overridden TextView with custom xml attributes to handle this in a convenient way.
Which is also available as a library: https://github.com/rongi/text-view-shadow-dips
public class TextViewShadowDips extends TextView {
public TextViewShadowDips(Context context, AttributeSet attrs) {
super(context, attrs);
final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.TextViewShadowDips);
// App can crash on some devices if shadow radius is more than 25 pixels
// On Samsung Galaxy S6 this crash happens when you copy a text from an input field
// https://stackoverflow.com/questions/4866928/ranges-for-radius-in-shadowradius-and-visiblity-in-textview?lq=1
final float shadowRadius = Math.min(
attributes.getDimension(R.styleable.TextViewShadowDips_shadowRadius, 0f),
25f
);
final float shadowDx = attributes.getDimension(R.styleable.TextViewShadowDips_shadowDx, 0f);
final float shadowDy = attributes.getDimension(R.styleable.TextViewShadowDips_shadowDy, 0f);
final int shadowColor = attributes.getColor(R.styleable.TextViewShadowDips_shadowColor, 0);
if (shadowColor != 0) {
setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
} else {
getPaint().clearShadowLayer();
}
attributes.recycle();
}
attrs.xml inside "values" resource folder
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TextViewShadowDips">
<attr name="shadowRadius" format="dimension"/>
<attr name="shadowDx" format="dimension"/>
<attr name="shadowDy" format="dimension"/>
<attr name="shadowColor" format="color"/>
</declare-styleable>
</resources>
Usage example:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<my.package.name.TextViewShadowDips
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:shadowColor="#000000"
app:shadowRadius="2dp"
app:shadowDx="2dp"
app:shadowDy="2dp"
/>
</RelativeLayout>
Unfortunately that's the only way, sorry :(
As Romain says, you can't set dip values directly in XML. You can still do it in XML, though, without having to do messy scaling calculations in your code.
The trick is to have separate values-hdpi
, values-mdpi
and values-ldpi
folders, in addition to your normal values
folder. Inside each, create a separate styles.xml
containing a style for your text with the shadow applied.
For example, you might have this in values-mdpi/styles.xml
:
<style name="my_shadow">
<item name="android:shadowDx">0.0</item>
<item name="android:shadowDy">-1.0</item>
<item name="android:shadowRadius">1.0</item>
</style>
And in values-hdpi/styles.xml
, you have the same style but with the values scaled for the higher density:
<style name="my_shadow">
<item name="android:shadowDx">0.0</item>
<item name="android:shadowDy">-1.5</item>
<item name="android:shadowRadius">1.5</item>
</style>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With