美文网首页
android 自定义View 之自定义属性

android 自定义View 之自定义属性

作者: 萝卜6 | 来源:发表于2019-04-16 18:08 被阅读0次

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

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

    <?xml version="1.0" encoding="utf-8"?>

    <resources>

        <attr name="titleText" format="string" />

        <attr name="titleTextSize" format="dimension" />

        <attr name="titleTextColor" format="color" />

        <attr name="image" format="reference" />

        <attr name="imageScaleType">

            <enum name="fillXY" value="0" />

            <enum name="center" value="1" />

        </attr>

        <declare-styleable name="CustomView">

            <attr name="titleText" />

            <attr name="titleTextSize" />

            <attr name="titleTextColor" />

            <attr name="image" />

            <attr name="imageScaleType" />

        </declare-styleable>

    </resources>

    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这样的标签,为什么呢?

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

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

        <com.zhy.customview02.view.CustomImageView

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

    </LinearLayout>

    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属性。

      <declare-styleable name="test">

            <attr name="android:text" />

            <attr name="testAttr" format="integer" />

        </declare-styleable>

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

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

    declare-styleable的标签也可以不写

    <?xml version="1.0" encoding="utf-8"?>

    <resources>

        <attr name="testAttr" format="integer" />

    </resources>

    <?xml version="1.0" encoding="utf-8"?>

    <resources>

        <attr name="testAttr" format="integer" />

    </resources>

    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 之自定义属性

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