当你还不能写出自己满意的程序时,你就不要去睡觉
好久没写博客了,最近项目实在太紧了,所以在博客这里花的时间就少了很多。不过以后的每周末都会更新一篇文章,不管时间多么
紧张,都会去找时间学习一些知识拿出来分享。以后的每次博客都会写上一句话来激励这个不怎么优秀的自己。下面进入正文。
今天主要讲的是我们 Android 中的资源文件,其实主要是我们的自定义的一些 Drawable 文件,还有我们的自定义属性。那我们下面开始说。
一、自定义属性
自定义属性基本大部分用到的地方是我们的自定义控件,在我们自定义控件的时候,我们可以在 xml 中设置自定义控件的自定义属性,然后在自定义控件中获取这个设置的属性值去设置控件的大小、展示等。
那这个自定义属性要怎么定义和使用呢?分为以下几个步骤:
1、在我们的 values 下面新建一个 attrs.xml 文件,然后在这个文件中去定义我们的属性。
2、我们新建一个属性的名字通过 attr 这个标签
3、在我们的 xml 中定义一个类似于xmlns:android="http://schemas.android.com/apk/res/android"
4、在我们的 xml 去使用这个属性
5、最后我们在自定义控件中获取这个属性并使用下面看代码
<resources>
<declare-styleable name="image">
<attr name="imageDurction" format="integer"/>
<attr name="durction" format="integer"/>
<attr name="traslate" format="integer"/>
</declare-styleable>
<declare-styleable name="LeftScrolling">
<attr name="aFew" format="integer" />
</declare-styleable>
</resources>
这段代码中我们定义了四个属性,分别是 image 下面的 imageDurction,durction,traslate,还有 LeftScrolling 下面的 aFew属性,我们可以看到定义属性的时候我们需要先写一个 declare-styleable 属性,其实这个属性不是必须的,单是如果不写这个属性的话,在我们获取的时候需要写很多的代码,然后这个 declare-styleable 的定义一般是我们的控件的名字,这样的话也比较好区分我们定义的属性使用在哪个控件上面。这样我们就完成了 1 、2 步的工作。
这个 formagt 是设置属性的类型,那这个类型可以使很多种看下面的列表:
format取值 | format说明 | format读取 |
reference | 资源ID | attrs.getResourceId(R.styleable.View名称_attr名称, 默认值); |
color | 颜色值 | attrs.getColor(R.styleable.View名称_attr名称, 默认值); |
boolean | 布尔值 | attrs.getBoolean(R.styleable.View名称_attr名称, 默认值); |
dimension | 尺寸值 | attrs.getDimension(R.styleable.View名称_attr名称, 默认值); |
float | 浮点值 | attrs.getFloat(R.styleable.View名称_attr名称, 默认值); |
integer | 整型值 | attrs.getInteger(R.styleable.View名称_attr名称, 默认值); |
string | 字符串 | attrs.getString(R.styleable.View名称_attr名称); |
fraction | 百分比(%) | attrs.getString(R.styleable.View名称_attr名称); |
enum | 枚举值 | attrs.getInt(R.styleable.View名称_attr名称, 默认值); |
flag | 位或运算 | attrs.getInt(R.styleable.View名称_attr名称, 默认值); |
下面我们看 3、4 步的代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:andya="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.andya.resourcetest.MyImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center"
andya:durction="1000"
andya:imageDurction="1000"
andya:traslate="1000"/>
</LinearLayout>
从这段代码中我们可以看到我们首先定义了一个 andya ,然后又使用了 andya 属性设置了 durction 等属性的值,这样我们也就完成了我们 3、4 步的工作。
最后我们看一下获取的代码:
TypedArray typedArray = context.obtainStyledAttributes(R.styleable.image);
int imageDurction = typedArray.getInt(R.styleable.image_imageDurction,0);
int durction = typedArray.getInteger(R.styleable.image_durction,0);
int traslate = typedArray.getInteger(R.styleable.image_traslate,0);
这就是获取的代码,其实获取的方式不仅这种方式,这种方式只是获取了我们指定的属性,还有一种方法是获取我们控件设置的全部属性的方法,下面看代码:
public MyImageView(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 的值,那么这个值也就是包含了这个控件设置的全部属性,通过这个属性我们可以得到我们设置的属性名和值,我们可以看到我们打印出来的值是:
MyImageView(4136): attrName = layout_width , attrVal = 150.0dp
MyImageView(4136): attrName = layout_height , attrVal = 150.0dip
MyImageView(4136): attrName = layout_gravity, attrVal = center
MyImageView(4136): attrName = durction, attrVal = 1000
MyImageView(4136): attrName = imageDurction, attrVal = 1000
MyImageView(4136): attrName = traslate, attrVal = 1000
属性的定义基本上差不多就这样,具体的内部实现可以看一下源码,源码真的是清晰无比。
二、stateListDrawable
这个属性主要作用是设置我们的 View 的点击背景或者不同状态的不同展示。
它主要的标签是 selector 我们看一下代码:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/colorAccent"/>
<item android:state_pressed="false" android:drawable="@color/colorPrimary"/>
</selector>
从这段代码中我们可以看到两个 item ,那么这两个 item 的状态分别是按下为 true 和按下为 false。
那当我们给 view 设置这个 xml 为背景的时候,当点击和正常的时候回呈现不同的效果。
其实 item 中可以设置的状态有很多,例如:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:bottomLeftRadius="1dp"
android:bottomRightRadius="1dp"
android:topRightRadius="1dp"
android:topLeftRadius="1dp"/>
<gradient
android:angle="1dp"
android:centerColor="@color/colorAccent"
android:centerX="1dp"
android:centerY="1dp"
android:endColor="@color/colorPrimary"
android:gradientRadius="1dp"
android:startColor="@color/colorPrimaryDark"
android:type="radial"/>
<stroke android:color="@color/colorPrimaryDark"/>
<solid android:color="@color/colorPrimaryDark"/>
</shape>
可以看到这里面有四个子属性,其实还有几个我这里面列举了几个比较重要的,作用分别是圆角、渐变色、边框颜色、和填充颜色。那这个 android:shape 这个属性也就是指定了我们画的形状是什么,可以是线,矩形等。
这个 stroke 我要说一下,这个属性里面有一个 dashGap 和 dashWidth 属性,通过这两个属性可以设置虚线。
四、ClipDrawable
主要就是截取位图,通常就是做一点一点展开的图片等
下面看代码:
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/back_home"
android:clipOrientation="vertical"
android:gravity="clip_horizontal">
</clip>
final ClipDrawable drawable = (ClipDrawable)imageView.getDrawable();
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
drawable.setLevel(drawable.getLevel()+200);
}
};
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Message message = new Message();
handler.sendMessage(message);
if(drawable.getLevel() >= 10000){
timer.cancel();
}
}
},0,300);
<layer-list xmlns **********************>
//定义背景图片
<item android:id="@android:id/background"
android:drawable="@drawable/grow">
<item android:id="@android:id/process"
android:drawable="@drawable/ok">
</layer-list>
六、几个特殊的资源文件