文章标题

Style array解析

<integer-array name="my_array">
 <item>@drawable/pencil</item>
 <item>@drawable/pencil2</item>
 <item>@drawable/pencil3</item>
 <item>@drawable/pencil4</item>
 <item>@drawable/pencil5</item>
 <item>@drawable/pencil6</item>
</integer-array>

或者

<array name="my_array">
 <item>@drawable/car_01</item>
 <item>@drawable/balloon_random_02</item>
 <item>@drawable/dog_03</item>
</array>

或者

<string-array name="my_array">
 <item>@drawable/car_01</item>
 <item>@drawable/balloon_random_02</item>
 <item>@drawable/dog_03</item>
</string-array>

解析

 TypedArray ar = context.getResources().obtainTypedArray(R.array.my_array);
 int len = ar.length();
 int[] resIds = new int[len];
 for (int i = 0; i < len; i++)
 resIds[i] = ar.getResourceId(i, 0);

res-auto

res-auto是一个很聪明的做法,这样就不用写packagename了。support-v7-demo

<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
      <item android:id="@+id/simple_item" android:title="@string/display_options_menu_item" app:showAsAction="ifRoom" />
  </menu>


<android.support.v7.widget.GridLayout  xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/blue" android:padding="10dip" app:columnCount="4" >
    <TextView  android:text="@string/grid_layout_1_instructions" />
    <EditText  app:layout_gravity="fill_horizontal" app:layout_column="0" app:layout_columnSpan="4" />
    <Button  android:text="@string/grid_layout_1_cancel" app:layout_column="2" />
    <Button  android:text="@string/grid_layout_1_ok" android:layout_marginLeft="10dip" />
</android.support.v7.widget.GridLayout>

自定义命名空间


   <!-- <com.rcplatform.rcad.RcAd
     android:id="@+id/adlayout"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentBottom="true"
     android:gravity="center_horizontal"
     rcplatform:ad_debug="true"
     rcplatform:ad_type="banner"
     rcplatform:label="1002002" />

其中:xmlns:rcplatform="http://rcplatform.com/apk/res/android"

解析

      private void parseParams(AttributeSet attrs) {
        String namespace = "http://rcplatform.com/apk/res/android";
        // String sdkKey = attrs.getAttributeValue(namespace, "sdk_key");
        String typeString = attrs.getAttributeValue(namespace, "ad_type");

      AdType adType = null;
      if (typeString == null || AdType.BANNER.toString().equalsIgnoreCase(typeString)) {
          adType = AdType.BANNER;
      } else if (AdType.POPUP.toString().equalsIgnoreCase(typeString)) {
          adType = AdType.POPUP;
      } else if (AdType.ICON.toString().equalsIgnoreCase(typeString)) {
          adType = AdType.ICON;
      } else if (AdType.FULLSCREEN.toString().equalsIgnoreCase(typeString)) {
          adType = AdType.FULLSCREEN;
      } else if(AdType.INTERSTITIAL_COMPOSE.toString().equalsIgnoreCase(typeString)){
          adType = AdType.INTERSTITIAL_COMPOSE;
      }
      this.adType = adType;
      this.isDebugMode = attrs.getAttributeBooleanValue(namespace, "ad_debug", false);
      this.label = attrs.getAttributeValue(namespace, "label");

        // if(isDebugMode)Logger.d(this.getClass().getSimpleName(),"sdk_key:"+sdkKey
        // +";ad_type:"+adType+";ad_debug:"+isDebugMode, null);
    }
  ```

###解析xml文件的自定义属性

// xmlId ==> R.xml.scene_filter_list

private List parseList(Context context, int xmlId) {
List list = new ArrayList();
// 开始解析
XmlResourceParser parser = null;
try {
// 从XML中获取到相应的属性列表
parser = context.getResources().getXml(xmlId);
AttributeSet attrs = Xml.asAttributeSet(parser);

      // 检查根元素
      beginDocument(parser, ROOT_ELEMENT);

      final int depth = parser.getDepth();
      // 遍历XML
      int type;
      while (((type = parser.next()) != XmlPullParser.END_TAG || parser
              .getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
          if (type != XmlPullParser.START_TAG) {
              continue;
          }
          // 按照thumb item类型解析出相应的数据
          // ThumbItem包含了自定义属性
          TypedArray a = context.obtainStyledAttributes(attrs,
                  R.styleable.ThumbItem);

          // parser.getAttributeValue(null, name);
          int id = a.getInt(R.styleable.ThumbItem_id, 0);
          String desc = a.getString(R.styleable.ThumbItem_desc);
          int iconRes = a.getResourceId(R.styleable.ThumbItem_icon, 0);
          //Drawable icon = a.getDrawable(R.styleable.ThumbItem_icon);

          // 生成Item并且加入列表
          EffectItem item = new EffectItem(id, desc, iconRes);
          list.add(item);

          // 回收属性列表
          a.recycle();
      }
  } catch (XmlPullParserException e) {
  } catch (IOException e) {
  } finally {
      try {
          parser.close();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  return list;

}


###测试例子

资源






测试方法:
private void testAttribute(AttributeSet attrs) {
    Resources res = getContext().getResources();

    //16842964:android.R.attr.background(属性名对应的资源id)
    int attributeNameResource = attrs.getAttributeNameResource(0);
    //background(属性名)
    String attributeName = attrs.getAttributeName(0);
    //100(属性值)
    int attributeResourceValue = attrs.getAttributeResourceValue(0,  100);

    //2130771969:R.attr.exampleDimension(属性名对应的资源id)
    int attributeNameResource2 = attrs.getAttributeNameResource(4);
    //exampleDimension
    String attributeName2 = attrs.getAttributeName(4);
    //100
    int attributeResourceValue2 = attrs.getAttributeResourceValue(4, 100);

    // 2130771971:R.attr.exampleDrawable
    int attributeNameResource3 = attrs.getAttributeNameResource(6);
    // exampleDrawable
    String attributeName3 = attrs.getAttributeName(6);
    //17301555:android.R.drawable.ic_menu_add
    int attributeResourceValue3 = attrs.getAttributeResourceValue(6, 100);


    Log.d(TAG, "getAttributeValue attributeNameResource3 "+attributeNameResource3+" attributeName3 "+attributeName3+":attributeResourceValue3 "+attributeResourceValue3);

    //1

// getAttributeValue 0 nameResId 16842964 name background:value #ff888899 //(16842964=>android.R.attr.background)
// getAttributeValue 1 nameResId 16842996 name layout_width:value -1 //(16842996=>android.R.attr.layout_width, -1=>wrap_content)
// getAttributeValue 2 nameResId 16842997 name layout_height:value -1
// getAttributeValue 3 nameResId 2130771968 name exampleString:value Hello, PazzleView
// getAttributeValue 4 nameResId 2130771969 name exampleDimension:value 24.0sp
// getAttributeValue 5 nameResId 2130771970 name exampleColor:value #ff33b5e5
// getAttributeValue 6 nameResId 2130771971 name exampleDrawable:value @17301555 //(2130771971=>R.attr.exampleDrawable, 17301555=>android.R.drawable.ic_menu_add,@表示引用)
// getAttributeValue idAttribute null classAttribute null
int attributeCount = attrs.getAttributeCount();
for (int i = 0; i < attributeCount; i++) {
attributeName3 = attrs.getAttributeName(i);
int nameResId = attrs.getAttributeNameResource(i);
String attributeValue = attrs.getAttributeValue(i);
Log.d(TAG, “getAttributeValue “+i+” nameResId “+nameResId+” name “+attributeName3+”:value “+attributeValue);
}

    String classAttribute = attrs.getClassAttribute();
    String idAttribute = attrs.getIdAttribute();
    Log.d(TAG, "getAttributeValue idAttribute "+idAttribute+" classAttribute "+classAttribute);

    //2

    //OK
    //int identifier = getResources().getIdentifier("dialog_style_push_up", "style", getContext().getPackageName());
    //2130771968 static final int exampleString=0x7f010000
    int identifier1 = res.getIdentifier("exampleString", "attr", getContext().getPackageName());
    //0
    int identifier2 = res.getIdentifier("PazzleView", "styleable", getContext().getPackageName());
    ////0
    int identifier3 = res.getIdentifier("PazzleView_exampleColor", "styleable", getContext().getPackageName());
    ////2131034112 R.xml.scene_filter_list
    int identifier4 = res.getIdentifier("scene_filter_list", "xml", getContext().getPackageName());
    //16842996 android.R.attr.layout_width
    int identifier5 = res.getIdentifier("android:layout_width", "attr", null);
    //16842996 android.R.attr.layout_width
    int identifier6 = res.getIdentifier("layout_width", "attr","android");
    //0
    int identifier7 = res.getIdentifier("layout_width", "attr",null);

    Log.d(TAG, "getAttributeValue identifier6 "+identifier6+" identifier7 "+identifier7);
    //null
    CharSequence themeResourceId = getThemeResourceString(getContext(), android.R.attr.layout_width);
    //null
    CharSequence themeResourceId2 = getThemeResourceString(getContext(), android.R.attr.textSize);
    //0x1060003 17170435 R.color.primary_text_light
    int themeResourceId3 = getThemeResourceId(getContext(), android.R.attr.textColorPrimary);
    //res/color/primary_text_light.xml
    CharSequence themeResourceIdString3 = getThemeResourceString(getContext(), android.R.attr.textColorPrimary);

    Log.d(TAG, "getAttributeValue themeResourceId "+themeResourceId+" themeResourceId2 "+themeResourceId2);
    Log.d(TAG, "getAttributeValue themeResourceId3 "+themeResourceId3+" themeResourceIdString3 "+themeResourceIdString3);

    //0 TypedValue.TYPE_NULL
    int themeResourceType1 = getThemeResourceType(getContext(), android.R.attr.layout_width);
    //0 TypedValue.TYPE_NULL
    int themeResourceType2 = getThemeResourceType(getContext(), android.R.attr.textSize);
    //3 TypedValue.TYPE_STRING
    int themeResourceType3 = getThemeResourceType(getContext(), android.R.attr.textColorPrimary);
    Log.d(TAG, "getAttributeValue themeResourceType1 "+themeResourceType1+" themeResourceType2 "+themeResourceType2+" themeResourceType3 "+themeResourceType3);

    //getThemeSize(getContext(), -1);

    String ns1 = "http://schemas.android.com/apk/res/android";
    String ns2 = "http://schemas.android.com/apk/res/com.powerapps.image";
    //#ff888899
    String a1 = attrs.getAttributeValue(ns1, "background");
    //24.0sp
    String a2 = attrs.getAttributeValue(ns2, "exampleDimension");
    Log.d(TAG, "getAttributeValue a1 "+a1+" a2 "+a2);


    //com.powerapps.image
    String resourcePackageName = res.getResourcePackageName(R.layout.activity_chartlet);
    //layout
    String resourceTypeName = res.getResourceTypeName(R.layout.activity_chartlet);
    //com.powerapps.image:layout/activity_chartlet
    String resourceName = res.getResourceName(R.layout.activity_chartlet);
    //activity_chartlet
    String resourceEntryName = res.getResourceEntryName(R.layout.activity_chartlet);


    //com.powerapps.image
    resourcePackageName = res.getResourcePackageName(R.attr.exampleDrawable);
    //attr
    resourceTypeName = res.getResourceTypeName(R.attr.exampleDrawable);
    //com.powerapps.image:attr/exampleDrawable
    resourceName = res.getResourceName(R.attr.exampleDrawable);
    //exampleDrawable
    resourceEntryName = res.getResourceEntryName(R.attr.exampleDrawable);

    Log.d(TAG, "getAttributeValue resourcePackageName "+resourcePackageName);
    Log.d(TAG, "getAttributeValue resourceTypeName "+resourceTypeName);
    Log.d(TAG, "getAttributeValue resourceName "+resourceName);
    Log.d(TAG, "getAttributeValue resourceEntryName "+resourceEntryName);
}


/**
 * //android.content.res.Resources$NotFoundException:
 * //tv.setTextColor(getResources().getColor(android.R.attr.textColorPrimary));
 * 
 * tv.setTextColor(getThemeColors(context,android.R.attr.textColorPrimary));
 * 
 * R.attr.textColorPrimary本身是一个属性名,?android.R.attr.textColorPrimary是引用它对应的属性值
 * 
 * 
 * Just like you use the @ reference syntax @android:drawable/foo when referring to a system resource, you can use the syntax 
 * ?android:attr/foo when you want to use the value stored in the system theme attribute foo.
 * 
 * In your case, if you want to change the primary text color across your app, apply a custom theme that sets the attribute textColorPrimary. 
 * If you just want to be sure that an element of your app is using the primary text color as defined by the device your app is running on, 
 * you can set android:textColor="?android:attr/textColorPrimary". The same principles apply elsewhere as well.
 * 
 * 
 * http://stackoverflow.com/questions/5850597/consistent-ui-color-in-all-android-devices
 * 
 * @param context
 * @param attr
 * @return
 */
public static int getThemeColors(Context context, int attr) {
    return context.getResources().getColor(
            getThemeResourceId(context, attr));
}

public static int getThemeResourceId(Context context, int attr) {
    TypedValue typedvalueattr = new TypedValue();
    context.getTheme().resolveAttribute(attr, typedvalueattr, true);

    /*在自定义view中,下面等价
    TypedArray a = context.obtainStyledAttributes
    TypedArray a = context.getTheme().obtainStyledAttributes
    */
    //什么意思?
    //Resources r = Resources.getSystem();
    return typedvalueattr.resourceId;
}

public static CharSequence getThemeResourceString(Context context, int attr) {
    TypedValue typedvalueattr = new TypedValue();
    context.getTheme().resolveAttribute(attr, typedvalueattr, true);

    /*在自定义view中,下面等价
    TypedArray a = context.obtainStyledAttributes
    TypedArray a = context.getTheme().obtainStyledAttributes
     */
    //什么意思?
    //Resources r = Resources.getSystem();
    return typedvalueattr.coerceToString();
}

public static int getThemeResourceType(Context context, int attr) {
    TypedValue typedvalueattr = new TypedValue();
    context.getTheme().resolveAttribute(attr, typedvalueattr, true);

    /*在自定义view中,下面等价
    TypedArray a = context.obtainStyledAttributes
    TypedArray a = context.getTheme().obtainStyledAttributes
     */
    //什么意思?
    //Resources r = Resources.getSystem();
    return typedvalueattr.type;
}

###自定义属性



生成R.attr.custom_attr/R.styleable.MyStyleable/R.styleable.MyStyleable_custom_attr,所以以下代码报错:



 因为R.attr.custom_attr已经存在。

 如果没有<declare-styleable>,比如
    <attr name="my_color" format="color" />

 那么生成R.attr.my_color。


###自定义属性的例子:

定义:  





#ff0000ff



@drawable/ic_launcher
@color/theme_color_blue
#ff00ff


这种方式引用theme color/drawable是没有问题的:



在<selector>使用theme color报错,换成正常的color OK. If you change the colour value in res/drawbale/shape.xml to a regular colour value, everything works. Setting it as a theme attribute throws java.lang.UnsupportedOperationException. 
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <!-- Referencing the theme attribute here causes a problem. Changing to a regular color value works ok. -->
            <!-- Error: <solid android:color="?attr/colorPrimary" /> -->
            <solid android:color="#8f8" />
        </shape>
    </item>
</selector>


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

<item android:state_pressed="true">
    <!-- Error:  <color android:color="?android:attr/colorPressedHighlight" /> -->
    <!-- Error: <color android:color="?attr/my_color2"/> -->
    <color android:color="@color/green" />
</item>
<item>
    <color android:color="@color/red" />
</item>


“`

但是貌似在5.0版本上没有问题(https://code.google.com/p/android/issues/detail?id=26251)

I just tested this quickly in a project I’m working on and it seems to be working.
This is my drawable xml:




It doesn’t throw an error and my shape gets the assigned color.
Note: this is tested on a physical Nexus 5 with L preview and compiledSdkVersion set to ‘android-L’.

你可能感兴趣的:(文章标题)