美文网首页
attr和style和theme

attr和style和theme

作者: 咸鱼佬 | 来源:发表于2018-10-14 08:49 被阅读4次

    attr

    attribute,属性,风格样式style的最小单元。

    步骤

    1. 创建新的.xml文件,自定义属性

       <?xml version="1.0" encoding="utf-8"?>
       <resources>
      
       <declare-styleable name="test">
      
       <attr name="custom_attr1" format="string"></attr>
       <attr name="custom_attr2" format="integer"></attr>
      
       </declare-styleable>
       </resources>
      
    2. 自定义View

       package com.example.jinxiong.test.attr;
      
       import android.content.Context;
       import android.content.res.TypedArray;
       import android.os.Build;
       import android.support.annotation.Nullable;
       import android.support.annotation.RequiresApi;
       import android.util.AttributeSet;
       import android.util.Log;
       import android.widget.TextView;
       
       import com.example.jinxiong.test.R;
       
       /**
        * Created by jinxiong on 2017/3/7.
        */
       
       public class MyTextView extends TextView {
      
       private static final String TAG = "MyTextView";
      
       public MyTextView(Context context) {
           super(context);
       }
      
       public MyTextView(Context context, @Nullable AttributeSet attrs) {
           this(context, attrs, 0);
           init(context, attrs);
       }
      
       public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
           super(context, attrs, defStyleAttr);
           init(context, attrs);
      
       }
      
       @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
       public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
           super(context, attrs, defStyleAttr, defStyleRes);
           init(context, attrs);
       }
      
       private void init(Context context, @Nullable AttributeSet attrs) {
           TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.test);
      
           Log.d(TAG, "test_custom_attr1: " + typedArray.getString(R.styleable.test_custom_attr1));
           Log.d(TAG, "test_custom_attr2: " + typedArray.getInteger(R.styleable.test_custom_attr2, -1));
      
       }
       }
      

    xml布局:

        <?xml version="1.0" encoding="utf-8"?>
        <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.jinxiong.test.attr.Main2Activity">
    
    
        <com.example.jinxiong.test.attr.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            app:custom_attr1="i am custom_attr1"
            app:custom_attr2="12"
            />
    
        </android.support.constraint.ConstraintLayout>
    

    log:
    [图片上传失败...(image-271773-1539478158639)]

    attr注意项

    attr 和 styleable的关系

    attr不依赖styleable,放在styleable 中只是为了方便使用attr,

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
    <declare-styleable name="adfsfsdff">
    
        <attr name="custom_attr1" format="string"></attr>
        <attr name="custom_attr2" format="integer"></attr>
    
    </declare-styleable>
    <attr name="custom_attr3" format="string"/>
    
    </resources>
    

    获取

    private void init(Context context, @Nullable AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.adfsfsdff);
    
        Log.d(TAG, "attr1  " + typedArray.getString(R.styleable.adfsfsdff_custom_attr1));
        Log.d(TAG, "attr2  " + typedArray.getInteger(R.styleable.adfsfsdff_custom_attr2, -1));
        typedArray.recycle();
    
        TypedArray attr3 = context.obtainStyledAttributes(attrs, new int[]{R.attr.custom_attr3});
        Log.d(TAG, "attr3 " + attr3.getString(0));
        attr3.recycle();
    
    }
    

    为什么是这样子,我们可以查看R文件
    [图片上传失败...(image-ec2594-1539478158639)]
    [图片上传失败...(image-b00656-1539478158639)]
    可以看到所有的attr在R文件中都生成一个id,所以说,attr的name在整个的project中是唯一的(自定义的,可以跟系统中的相同,比如定义一个textColor的attr,是可以跟系统定义的一样的name,但是不能再定义一个textColor的attr了),而放在styleable的attr1和attr2只是被放在了一个叫做adfsfsdff(styleable name)数组中,R.styleable.adfsfsdff_custom_attr2和attr1 就是对应的下标值,对应着0和1.所以我么使用attr3的时候,也是先定义一个数组,然后再通过下标0来获取它

    styleable的name规范

    官方的推荐做法是一般为View的名字,不会像我上面那样为了测试随意打几个英文。

    其他

        <attr name="numeric">
            <!-- Input is numeric. -->
            <flag name="integer" value="0x01" />
            <!-- Input is numeric, with sign allowed. -->
            <flag name="signed" value="0x03" />
            <!-- Input is numeric, with decimals allowed. -->
            <flag name="decimal" value="0x05" />
        </attr>
           
        <attr name="bufferType">
            <!-- Can return any CharSequence, possibly a
             Spanned one if the source text was Spanned. -->
            <enum name="normal" value="0" />
            <!-- Can only return Spannable. -->
            <enum name="spannable" value="1" />
            <!-- Can only return Spannable and Editable. -->
            <enum name="editable" value="2" />
        </attr>
    

    这是系统的TextView的attr属性定义的一部分,可以看到,一个在attr之间一个用了enum,一个是flag,之间有什么不一样。
    [图片上传失败...(image-33661a-1539478158639)]
    [图片上传失败...(image-aef467-1539478158639)]
    enum只能选其中的一个,而flag是可以多选的,falg的值可以做或运算

    style

    样式是指为 View 或窗口指定外观和格式的属性集合。样式可以指定高度、填充、字体颜色、字号、背景色等许多属性。 样式是在与指定布局的 XML 不同的 XML 资源中进行定义。

    Android 中的样式与网页设计中层叠样式表的原理类似 — 您可以通过它将设计与内容分离

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.jinxiong.test.style.Main3Activity">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/holo_red_dark"
            android:textSize="16sp"
    
            />
    
    </android.support.constraint.ConstraintLayout>  
    

    和这样是一样的效果的

        <TextView
        style="@style/textView"
        />
    <style name="textView">
        <item name="android:text">test</item>
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@android:color/holo_red_dark</item>
    </style>
    

    定义样式

    要创建一组样式,在res/values/目录想保存一个xml文件,该XML文件的根节点必须是< resources>.因为resource元素的每一额子元素在编译时都会被转换成一个资源对象,该对象可由< style >元素的name属性中的name值引用。可以在布局的xml中以@style/textView形式引用该样式。

    对于你想创建的每一个样式,向该文件中添加一个< style>元素,该元素带有对样式进行唯一标识的name属性(没了这个属性你定义的style就没法进行引用,name属性为必须属性),然后为该样式的每一个属性添加一个< item>元素,该元素带有声明样式属性和属性值的,属性名(name)为必须属性,属性值可以是string,其他资源的引用或者其他,根据对应的attr设定的format(attr上面有介绍)
    而style中的parent属性是可选的,他可以指定当前定义的style继承另外style

    继承

    <style name="textView2" parent="textView">
    
    </style>
    
    <style name="textView.textView3">
    
    </style>
    

    两种继承的方式,但是你继承android内建的style的话,只能通过parent的方式。

    其他

    如果你当前View应用样式中,有某些attr是不属于这个view的话,也就是说,当前view不能应用style中的某些属性,那么当前view就会忽略掉他,只应用他能应用的属性

    主题Theme

    主题是指对整个 Activity 或应用而不是对单个 View(如上例所示)应用的样式。 以主题形式应用样式时,Activity 或应用中的每个视图都将应用其支持的每个样式属性。比如application应用了上面的textView的style,那么整个app中的文本都会红色字体,16sp大小(属性没有再一次被覆盖)

    在 XML 中定义您想用作 Activity 或应用主题的样式与定义视图样式的方法完全相同。 诸如上文所定义的样式可作为单个视图的样式加以应用,也可作为整个 Activity 或应用的主题加以应用。

    对 Activity 或应用应用主题

    要为您的应用的所有 Activity 设置主题,请打开 AndroidManifest.xml 文件并编辑 < application> 标记,在其中加入带样式名称的 android:theme 属性。 例如:

    < application android:theme="@style/CustomTheme">
    

    如果您只想对应用中的一个 Activity 应用主题,则改为给 <activity> 标记添加 android:theme 属性。

    正如 Android 提供了其他内建资源一样,有许多预定义主题可供您使用,可免于自行编写。 例如,您可以使用 Dialog 主题,为您的 Activity 赋予类似对话框的外观:

    < activity android:theme="@android:style/Theme.Dialog">
    

    或者,如果您希望背景是透明的,则可使用 Translucent 主题:

    < activity android:theme="@android:style/Theme.Translucent">
    

    多看attrs.xml styles.xml themes.xml

    https://developer.android.com/guide/topics/ui/themes.html?hl=zh-cn#DefiningStyles

    相关文章

      网友评论

          本文标题:attr和style和theme

          本文链接:https://www.haomeiwen.com/subject/sqczaftx.html