Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add shadow to TextView on selection/focus

Tags:

android

My question is how to add a shadow to text when TextView is selected or View that TextView is in gets selected. For example I have a CheckedTextView which changes background according to type of selection. I also made a text selector which changes color on differents states. Now I would like to add a shadow when for example View gets selected. So it changes background color, text color and creates a shadow. This is my text selector:

<selector 
xmlns:android="http://schemas.android.com/apk/res/android">

<item 
    android:state_focused="true" 
    android:state_pressed="false"       
    android:color="@android:color/white"
    style="@style/DarkShadow"/>

<item 
    android:state_focused="true" 
    android:state_pressed="true"            
    android:color="@android:color/white"
    style="@style/DarkShadow"/>

<item 
    android:state_focused="false" 
    android:state_pressed="true" 
    android:color="@android:color/white"
    style="@style/DarkShadow"/>

<item 
    android:color="@color/primary_text_light_disable_only"/>

and style:

<style name="DarkShadow">   
    <item name="android:shadowColor">#BB000000</item>
    <item name="android:shadowRadius">2.75</item>
</style>

Now text gets properly highlighted but no shadows appear. Does anyone know how to solve this?

like image 268
klemzy Avatar asked Jan 20 '11 22:01

klemzy


People also ask

How to apply shadow to TextView in android?

You can apply shadow to TextView in two ways: either pragmatically or in the xml layout. android:shadowDx specifies the X-axis offset of shadow. You can give -/+ values, where -Dx draws a shadow on the left of text and +Dx on the right. android:shadowDy specifies the Y-axis offset of shadow.

How to give elevation to shape in android?

To set the default (resting) elevation of a view, use the android:elevation attribute in the XML layout. To set the elevation of a view in the code of an activity, use the View. setElevation() method.

How do you add a space in TextView?

Just we need to add an attribute with your TextView that give the spacing with lines. These are –android:lineSpacingExtra, android:lineSpacingMultiplier – use these two attributes with your TextView in XML file. or Programatically call setter method of that attribute textView. setLineSpacing().


1 Answers

This is a current limitation of the Android SDK. I extended TextView for it to work, you can use it freely:

CustomTextView.java:

import android.widget.TextView;
import android.util.AttributeSet;
import android.content.res.TypedArray;
import android.content.Context;

import com.client.R;


public class CustomTextView extends TextView
{

    private static String TAG = "CustomTextView";

    private ColorStateList mShadowColors;
    private float mShadowDx;
    private float mShadowDy;
    private float mShadowRadius;


    public CustomTextView(Context context)
    {
        super(context);
    }


    public CustomTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init(context, attrs);
    }


    public CustomTextView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        init(context, attrs);
    }


    /**
     * Initialization process
     * 
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void init(Context context, AttributeSet attrs, int defStyle)
    {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView, defStyle, 0);

        final int attributeCount = a.getIndexCount();
        for (int i = 0; i < attributeCount; i++) {
            int curAttr = a.getIndex(i);

            switch (curAttr) {                  
                case R.styleable.CustomTextView_shadowColors:
                    mShadowColors = a.getColorStateList(curAttr);
                    break;

                case R.styleable.CustomTextView_android_shadowDx:
                    mShadowDx = a.getFloat(curAttr, 0);
                    break;

                case R.styleable.CustomTextView_android_shadowDy:
                    mShadowDy = a.getFloat(curAttr, 0);
                    break;

                case R.styleable.CustomTextView_android_shadowRadius:
                    mShadowRadius = a.getFloat(curAttr, 0);
                    break;  

                default:
                break;
        }
    }

        a.recycle();

        updateShadowColor();
    }

    private void updateShadowColor()
    {
        if (mShadowColors != null) {
            setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColors.getColorForState(getDrawableState(), 0));
            invalidate();
        }
    }

    @Override
    protected void drawableStateChanged()
    {
        super.drawableStateChanged();
        updateShadowColor();
    }
}

You also need to add this to your attr.xml (or create one): attr.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="Theme">
        <attr format="reference" name="CustomTextView"/>
    </declare-styleable>

    <declare-styleable name="CustomTextView">
        <attr name="shadowColors" format="color|reference"/>
        <attr name="android:shadowDx"/>
        <attr name="android:shadowDy"/>
        <attr name="android:shadowRadius"/>

    </declare-styleable>
</resources>

So finally you'll be able to use it in your xmls, like this:

<com.client.ui.textviews.CustomTextView
 xmlns:client="http://schemas.android.com/apk/res/com.client"
        android:id="@+id/join_text"
        android:shadowDx="1"
        android:shadowDy="1"
        android:shadowRadius="1"
        client:shadowColors="@color/btn_green_shadow_color"/>

Where @color/btn_green_shadow_color points to a selector such a this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_enabled="false" android:color="@android:color/white"/>
    <item android:state_pressed="true" android:color="@color/BzDarkGray"/>
    <item android:color="@android:color/black"/>

</selector>

If you are not familiar with how to use custom attributes (with the custom xml namespace I used), please refer to this good StackOverFlow question.

like image 180
Gilbert Avatar answered Oct 05 '22 06:10

Gilbert