android 自定义View 之自定义属性

1:新建 attrs文件 目录 res/value/attrs.xml 

 属性类型一共有8种:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;

   

   

   

   

   

       

       

   

   

       

       

       

       

       

   


2:布局中使用:

一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"我们的命名空间,后面的包路径指的是项目的package  或者  xmlns:custom="http://schemas.android.com/apk/res-auto"

xmlns的作用

xml布局中使用最多的是android:id、andorid:layout_width等形式,在我们自定义的xml中,添加了app:Text、app:TextAllow等这样的写法,其实冒号前面的单词并不重要,重要的是后面引号中的内容,前面的单词可以任意取名,我们在最开始指定了这样一句代码:

    xmlns:app="http://schemas.android.com/apk/res-auto"

包括系统自动为我们添加的这一句代码:

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

正是这两句代码的存在,才使得我们能够使用android、app这样的标签,为什么呢?


    xmlns:tools="http://schemas.android.com/tools"

    xmlns:custom="http://schemas.android.com/apk/res/com.zhy.customview02"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

<--或者声明这个-->

<-- xmlns:custom="http://schemas.android.com/apk/res-auto"-->

   

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_margin="10dp"

        android:padding="10dp"

        custom:image="@drawable/ic_launcher"

        custom:imageScaleType="center"

        custom:titleText="hello andorid ! "

        custom:titleTextColor="#ff0000"

        custom:titleTextSize="30sp" />


3:自定义view中使用

public class CustomView extends View {

    public CustomView(Context context, AttributeSet attrs) {

        super(context, attrs);

        TypedArray ta = context.obtainStyledAttributes(attrs,

                      R.styleable.CustomView);

        String text = ta.getString(R.styleable.CustomeView_titletext);

        Bitmap mImage = BitmapFactory.decodeResource(getResources(),

                    ta.getResourceId(R.styleable.CustomeView_image, 0));

        int  mTextSize =

              ta.getDimensionPixelSize(R.styleable.CustomeView_titleTextSize, (int)

              TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,

16, getResources().getDisplayMetrics()));

        ta.recycle();

    }

    public CustomView(Context context,AttributeSet attrs,int defStyleAttr){

        super(context, attrs,defStyleAttr);

    TypedArray typedArray =context.getTheme().obtainStyledAttributes(attrs,

                            R.styleable.CustomView,defStyleAttr,0);

  }

}

4:TypedArray和AttributeSet的不同

AttributeSet中的确保存的是该View声明的所有的属性,并且外面的确可以通过它去获取属性自定义和原有的属性

public CustomView(Context context, AttributeSet attrs) {

        super(context, attrs);

        int count = attrs.getAttributeCount();

        for (int i = 0; i < count; i++) {

            String attrName = attrs.getAttributeName(i);

            String attrVal = attrs.getAttributeValue(i);

            Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal);

        }

    }


通过AttributeSet可以获得布局文件中定义的所有属性的key和value,但通过AttributeSet获取的值,如果是值是@的资源,那么引用都变成了@+数字的字符串。

ypedArray其实是用来简化我们的工作的,比如上例,如果布局中的属性的值是引用类型(比如:@dimen/dp100),如果使用AttributeSet去获得最终的像素值,那么需要第一步拿到id,第二步再去解析id。而TypedArray正是帮我们简化了这个过程。

贴一下:如果通过AttributeSet获取最终的像素值的过程:

int widthDimensionId =  attrs.getAttributeResourceValue(0, -1);

        Log.e(TAG, "layout_width= "+getResources().getDimension(widthDimensionId));

5:declare-styleable

直接在attrs.xml中使用android:text属性。


 

       

       

   

注意,这里我们是使用已经定义好的属性,不需要去添加format属性(注意声明和使用的区别,差别就是有没有format)。 

然后在类中这么获取:ta.getString(R.styleable.test_android_text);布局文件中直接android:text="@string/hello_world"即可。

declare-styleable的标签也可以不写

   

   


public class MyTextView extends View {

    private static final String TAG = MyTextView.class.getSimpleName();

    private static final int[] mAttr = { android.R.attr.text, R.attr.testAttr };

    private static final int ATTR_ANDROID_TEXT = 0;

    private static final int ATTR_TESTATTR = 1;

    public MyTextView(Context context, AttributeSet attrs) {

        super(context, attrs);

        // ==>use typedarray

        TypedArray ta = context.obtainStyledAttributes(attrs, mAttr);

        String text = ta.getString(ATTR_ANDROID_TEXT);

        int textAttr = ta.getInteger(ATTR_TESTATTR, -1);

        //输出 text = Hello world! , textAttr = 520

        Log.e(TAG, "text = " + text + " , textAttr = " + textAttr);

        ta.recycle();

    }

}


可以看到我们声明了一个int数组,数组中的元素就是我们想要获取的attr的id。并且我们根据元素的在数组中的位置,定义了一些整形的常量代表其下标,然后通过TypedArray进行获取。

https://blog.csdn.net/lmj623565791/article/details/45022631

你可能感兴趣的:(android 自定义View 之自定义属性)