2011-01-20 53 views
17

我的问题是如何选择TextView或View中的TextView时选中阴影添加到文本。例如,我有一个CheckedTextView根据选择的类型改变背景。我还制作了一个文本选择器,可以在不同的状态下改变颜色。现在我想添加一个阴影,例如View被选中。所以它会改变背景颜色,文字颜色并创建阴影。这是我的文本选择:如何将阴影添加到选择/焦点上的TextView

<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"/> 

和风格:

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

现在的文字才能正确突出,但没有阴影出现。有谁知道如何解决这个问题?

+0

我知道颜色列表和状态列表可绘制,但阴影似乎是TextView中的特定属性。可能影子属性会被忽略。我会用一些onStateChange方法来查看视图,然后设置这个影子,但我只是在寻找它,而且令人惊讶的是它只存在于drawable中!然后我会问:是否有可能获得视图状态更改? – bigstones 2011-01-20 23:54:57

回答

3

是的,我遇到了同样的问题,您可以使用xml中的选择器来更改文本颜色,但不能使用shadowcolor。 因此,为了解决这个问题,你可能有根据查看 的状态,延长CheckedTextView或任何你需要的视图,然后覆盖onDraw(Canvas canvas)因此,你需要使用 public void setShadowLayer (float radius, float dx, float dy, int color)here

例如定义:

@Override 
protected void onDraw(Canvas canvas) { 
    if(isPressed()){ 
     setShadowLayer(1, 0, 1, Color.RED); 
    }else{ 
     if(isFocused()){ 
      setShadowLayer(1, 0, 1, Color.WHITE); 
     }else{ 
      setShadowLayer(1, 0, 1, Color.BLACK); 
     } 
    } 
    super.onDraw(canvas); 
} 

我希望工作

+1

这段写的代码不起作用,setShadowLayer最终会重绘,所以最终会出现无限循环。但是你可以把它放在onFocusChanged上,或者在一个实例上设置一个OnFocusChangeListener。 – miguel 2011-06-10 09:12:17

+0

@miguel同意。 setShadowLayer调用invalidate。 – nmw 2012-10-03 09:45:52

21

这是Android SDK的电流限制。 我延长TextView为它工作,你可以自由地使用它:

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(); 
    } 
} 

您还需要添加到您的attr.xml(或创建一个): 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> 

所以最后你就可以使用它在你的个XML,像这样:

<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"/> 

@color/btn_green_shadow_color点,选择这样一个这样的:

<?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> 

如果您不熟悉如何使用自定义属性(与我使用的自定义XML命名空间),请参阅this good StackOverFlow question

2

这是我落得这样做:

@Override 
protected void drawableStateChanged() { 
    super.drawableStateChanged(); 
    if(isPressed()) { 
     setShadowLayer(15, 0, 0, getTextColors().getDefaultColor()); 
    } else { 
     setShadowLayer(0, 0, 0, Color.TRANSPARENT); 
    } 
}