首选感谢这位博主的分享,让我等新生有很好的范例学习
http://blog.csdn.net/qq_31715429/article/details/54668668点击打开链接 点击打开链接 点击打开链接 点击打开链接
一开始我是在做一个多功能时钟类的APP,做到一半觉得界面实在是丑,而我当时用的又是小米手机,难免会参考小米的时钟,结果一种强烈的羞耻感就出来了。。。于是我开始 想学动画和ps,想找张有刻度的表盘图片和几个指针图片拼起来,凑成一个闹钟。。。结果ps装不成。。。。很气。。。很绝望。就在这时候,我无意在GitHub上搜索了时钟两个字,打开了新世界大门。。。
刚看代码的时候,第一眼我就发现我不会。我不知道为什么要有个 attrs 。其实很简单,它是为了简化我们的调试,方便修改一些属性值。
例如本例中
定义了这些属性,那么我们在布局文件中需要去给他们赋值,
然后在自定义view类中用
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MiClockView, defStyleAttr, 0);
mBackgroundColor = ta.getColor(R.styleable.MiClockView_backgroundColor, Color.parseColor("#237EAD"));
setBackgroundColor(mBackgroundColor);
mLightColor = ta.getColor(R.styleable.MiClockView_lightColor, Color.parseColor("#ffffff"));
mDarkColor = ta.getColor(R.styleable.MiClockView_darkColor, Color.parseColor("#80ffffff"));
mTextSize = ta.getDimension(R.styleable.MiClockView_textSize, DensityUtils.sp2px(context, 14));
ta.recycle();
来获取我们自定义属性的属性值,这些ta.getXXX()方法的第二个参数都是如果没有第一个参数的情况下的默认值。
TypeArray这一行好像都是标准格式,通常情况下只要把第二个参数改成自己在attrs中定义的declare_styleable name=“XXX”就好了,还有在写attrs文件定义属性时
declare-styleable name="MiClockView"
这一行记得写,不然TypedArray ta = .....的时候怎么知道是要从哪来获取你的自定义属性呢。
然后,回到这段文章的开始。。。定义attrs这些文件的作用:比如当你需要修改你的自定义view内的一个lightColor属性时,有很多组件都使用了这个属性,你直接去代码中一个个改就很麻烦了,这时你定义好这些attrs文件后,就只需在布局文件那像修改其他Android系统提供的组件一样修改lightColor值,这时在TypedArray这段代码内mLightColor的值就改变了,也就是后面的所有用到了它的组件都修改了。就是这么简单,但是我当初却想了很久。。。最后通过动手才了解了。。。
在构造方法中使用
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MiClockView, defStyleAttr, 0);
来获取到attrs中定义的各个属性值并赋值,在后面,这些属性值可用以设置画笔颜色、线条宽度等。
通常也在构造方法中初始化各个参数(如把上面获取的属性值赋值给一些需要的paint、path等)。
至于为什么是三个构造方法:
也就是说,系统默认只会调用Custom View的前两个构造函数,至于第三个构造函数的调用,通常是我们自己在构造函数中主动调用的(例如,在第二个构造函数中调用第三个构造函数).
各个参数的含义其实我也不太清楚。。。。
所以推荐一下这篇博客,我也是从在学习到的
http://blog.csdn.net/wzy_1988/article/details/49619773#生成custom-view的自定义属性点击打开链接
通常在onMeasure中为自定义view设置大小
而且onMeasure中只需要一个方法
setMeasuredDimension(measureDimension(widthMeasureSpec), measureDimension(heightMeasureSpec))
而其中的measureDimension是自己写的一个测量方法
private int measureDimension(int measureSpec) {
int result;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 800;
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
这主要是对自定义的layout_width/heigh的值进行判断
具体的晚点再补。。。不过推荐一篇我认为关于这个onMeasure写得很好的博客
http://www.jianshu.com/p/5a71014e7b1b点击打开链接
再下来就是onDraw了
把所有画图的方法都放到这里面来运行。。就能都显示出来。。。大概就是这样
记得给canvas赋值。。。
还有就是最后如果是动画需要有一个
invalidate();
方法,作用好像是重复绘制?不是很懂。。。这是个遗留问题,现在太晚了没时
间了,以后补上
最后,其实在写代码的时候有很多的基本的东西都记得不牢,比如一些画形状的方法、贝塞尔曲线什么的,初学者还是需要多练啊!光看是不行的,今天实在是太晚了,明天还有一天课,不,是一周课。。。超级课设培训。。可怕。剩下的遗留问题一定要解决!
最后的最后,第一次写博客,很多东西还不会,请大家见谅。
因为本人水平不够,分享的也只是心得,也是我走过的困难的路,希望能对一些初学者能有帮助,不过难免会有错误,各位大神看到了一定麻烦帮我指出啊。。。谢!