android 自定义View与Attr风格Style风格样式

一.自定义View的主题和风格样式

前言:

android开发中,不可避免的要设定某一类按钮的按压,点击,聚焦等状态,通常对于这一类问题而言,最原始的方式就是在布局文件中亲自设定,然而对于一个比较大型的项目而言,这种方式造成的可维护性不是很好,因此要尽量做到代码重用。对于一个控件而言,如ToggleButton,RadioButton,CheckBox,滚动条颜色,Button,当点击时状态切换前后样式是不一样的。


介绍:

android项目中通常有3个设置样式的资源文件夹

values

values-11

values-14

这三个对应不同平台的sdk版本的样式,对于android开发中兼容问题而言,要做到“让最新的api运行在最新的android sdk中”,这是非常好的一种行为。

values文件主要用来设置主题样式,权限依据平台细分,也就是说android4.x会最先找values-14再去找values-11最后找values,android2.x最先找values-11最后找values

以上是values的设置问题,通常来说,style.xml一般被使用来设置 window和activity主题与样式,但实际上,style.xml也可以用来设定控件的全局样式。


下面有句名言:

尽量让主题样式和页面风格保持统一,花花绿绿是最丑的风格。


举例子

style.xml-1

    <style name="text_red_20_blod">
        <item name="android:textStyle">bold</item>
        <item name="android:textSize">20.0sp</item>
        <item name="android:textColor">@color/red_text_color</item>
    </style>

这种的局限性和亲自到布局文件设置的一样,只不过少了许多代码,提高了重用性,可以说只做到了部分全局化。

style.xml-2

<style name="AppTheme" parent="android:Theme.Holo.Light">
        <item name="android:textStyle">bold</item>
        <item name="android:textSize">20.0sp</item>
        <item name="android:textColor">@color/red_text_color</item>
</style>

这种事最全局的,提高了重用性,当然也有他的缺点,这点不可避免,那么在开发中,我们如何选择呢?


  1. style.xml-1 中样式变化最为频繁的View风格,这样做可以避免layout文件中过多的代码累计,就像css样式一样

  2. style.xml-2适用于全局较为统一的View风格,也就是说是一些View的共性的统一,一般来说如ToggleButton,CheckBox,Button等View的状态切换样式在同一项目中总是保持着一直的变化效果。也就是说,当我们使用自定义放入ToggleButton切换状态之后,下次再次使用ToggleButton风格应该和上次风格保持一致才对。

  3. 冲突问题,如果在style.xml-2下使用style.xml-1的内容将如何显示,这个问题一句话可以描述:”全局性越低,控制权限越高“,也就是说,style.xml-1控制权限高于style.xml-2,因此如果同时影响某一控件的view风格的样式被设置,那么也就是直接使用 style="@style/xxxx"的权限高于主题权限。


二.自定义Attr风格样式以及读取

获取自定义属性通常是在自定义View内部获取,但在某种方式下,无论自定义View的属性还是主题中样式的属性,均可在外部style中获取。


由于非自定义View的外部获取方式比较复杂,这里暂时略过,后续补充。

1.自定义attr
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <attr name="theme_name" format="string|reference"/>
</resources>
2.设置attr,注意,该Attr必须在是Activity主题中而不是普通的Style中
<resources>
    <!-- Activity themes -->
    <style name="Theme.Base" parent="android:Theme.Holo.Light" >
    <item name="theme_name" >@string/theme_name_1</item>    
    </style>
</resources>
3.获取,通过xml
 <TextView
        android:id="@+id/show_tv"
        android:layout_width="match_parent"
        android:layout_height="200dip"
        android:text="?attr/theme_name"
        android:background="@android:color/darker_gray" />
4.获取,通过代码
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,outValue, true);
textView.setBackgroundResource(outValue.resourceId);

注意,如果我直接设置数据,则resourceId为0

<resources>
    <!-- Activity themes -->
    <style name="Theme.Base" parent="android:Theme.Holo.Light" >
    <item name="theme_name" >我的主题</item>    
    </style>

</resources>

这时候我们的数据可以使用TypeValue.string读取

TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,outValue, true);
if(outValue.data==TypeValue.TYPE_STRING)
{
textView.setBackgroundResource(outValue.string);
}
5.当然,有时候我们的属性可能是个集合

  这时候不能用TypedValue获取,TypeValued只能判断类型,因此我们选择如下方式

  5.1在xml中,我们使用 style="?attr/MyStyle"或者style="?android:attr/ActionBarStyle"方式获取集合Style的

  5.2在代码中获取,举个栗子,如下:

public int getTabContainerHeight()
    {
        TypedArray a = mContext.obtainStyledAttributes(null, android.support.v7.appcompat.R.styleable.ActionBar, android.support.v7.appcompat.R.attr.actionBarStyle, 0);
        int height = a.getLayoutDimension(android.support.v7.appcompat.R.styleable.ActionBar_height, 0);
        Resources r = mContext.getResources();
        if(!hasEmbeddedTabs())
            height = Math.min(height, r.getDimensionPixelSize(android.support.v7.appcompat.R.dimen.abc_action_bar_stacked_max_height));
        a.recycle();
        return height;
    }


对于View内部获取方式如下

  private static Context themifyContext(Context context, AttributeSet attrs, int defStyleAttr)
    {
        TypedArray a = context.obtainStyledAttributes(attrs, android.support.v7.appcompat.R.styleable.Toolbar, android.support.v7.appcompat.R.attr.ActionBarStyle, 0);
        int themeId = a.getResourceId(android.support.v7.appcompat.R.styleable.Toolbar_theme, 0);
        if(themeId != 0)
            context = new ContextThemeWrapper(context, themeId);
        a.recycle();
        return context;
    }


转载于:https://my.oschina.net/ososchina/blog/353346

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值