Android自定义View
2015-11-14 17:10
387 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/songlin0859/article/details/49836727
2、编写自定义属性文件
3、在类的构造方法中获取自定义的属性值
获取属性值
最后打印输出一下各个数据
注意:获取完属性后调用TypedArray 的recycle方法!!!!!!!!
4、复写onMeasure方法测量自 3ff7 定义view的宽高
千万记住最后调用setMeasuredDimension(width, height);方式设置尺寸
6、定义好View后View的使用方法
Android自定义View的步骤:
1、编写一个类(class)继承自View(貌似还可以继承自Drawable);
2、编写自定义属性文件(不是必须)
3、在类的构造方法中获取自定义的属性值(不是必须)
4、复写onMeasure方法测量自定义view的宽高、如果复写了就必须调用setMeasuredDimension方法设置自定义view的宽高(不是必须)
5、复习onDraw方法,绘制想要的界面/结果
1、编写一个类(class)继承自View
public class MyView extends View
2、编写自定义属性文件
在android工程res->values文件夹下建立attrs.xml文件
属性有下面这些类型:
<attr name="colorValue" format="color" /> <attr name="floatValue" format="float" /> <attr name="integerValue" format="integer" /> <attr name="booleanValue" format="boolean" /> <attr name="dimensionValue" format="dimension" /> <attr name="stringValue" format="string" /> <attr name="referenceValue" format="color|reference" /> <attr name="imageValue" format="reference"/> <attr name="Visibility"> <enum name="invisible" value="0" /> <enum name="visible" value="1" /> <enum name="gone" value="2" /> </attr>有颜色、浮点型、整型、布尔、尺寸(dp、sp)、字符串、引用、enum
定义的属性文件如下
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- <attr name="TextColor" format="color"/> <attr name="float" format="color"/> <attr name="int" format="integer"/> <attr name="bool" format="boolean"/> <attr name="dimens" format="dimension"/> <attr name="text" format="string"/> <attr name="background" format="color"/> <attr name="image" format="reference"/> <attr name="Visibility"> <enum name="VISIBLE" value="0" /> <enum name="INVISIBLE" value="1" /> <enum name="GONE" value="2" /> </attr> --> <declare-styleable name="MyView"> <attr name="TextColor" format="color"/> <attr name="f" format="float"/> <attr name="i" format="integer"/> <attr name="bool" format="boolean"/> <attr name="dimens" format="dimension"/> <attr name="text" format="string"/> <attr name="background" format="color|reference"/> <attr name="image" format="reference"/> <attr name="Visibility"> <enum name="VISIBLE" value="0" /> <enum name="INVISIBLE" value="1" /> <enum name="GONE" value="2" /> </attr> </declare-styleable> </resources>
上面的定义和下面的定义的效果貌似是一样的
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="TextColor" format="color"/> <attr name="f" format="color"/> <attr name="i" format="integer"/> <attr name="bool" format="boolean"/> <attr name="dimens" format="dimension"/> <attr name="text" format="string"/> <attr name="background" format="color"/> <attr name="image" format="reference"/> <attr name="Visibility"> <enum name="VISIBLE" value="0" /> <enum name="INVISIBLE" value="1" /> <enum name="GONE" value="2" /> </attr> <declare-styleable name="MyView"> <attr name="TextColor"/> <attr name="f"/> <attr name="i"/> <attr name="bool"/> <attr name="dimens"/> <attr name="text"/> <attr name="background"/> <attr name="image"/> <attr name="Visibility"/> </declare-styleable> </resources>
3、在类的构造方法中获取自定义的属性值
自定义view中的field如下:
private Paint mPaint; private float mTitleTextSize = 150.0f; private Rect mBounds; private int textcolor; private float f; private int integer; private boolean b; private int dimens; private int background; private Drawable backgroundDrawable; private int visiblity; private Drawable image; private Bitmap bitmap; private int drawablwID; private String mTitle;
获取属性值
由一个特殊的
String attributeValue = attrs.getAttributeValue(null, "textsize"); if (attributeValue!=null) { try { mTitleTextSize=Integer.parseInt(attributeValue); } catch (Exception e) { } }
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int index = a.getIndex(i); switch (index) { case R.styleable.MyView_TextColor: textcolor = a.getColor(index,Color.BLACK); break; case R.styleable.MyView_f: f = a.getFloat(index, 0.0f); break; case R.styleable.MyView_i: integer = a.getInt(index, 0); break; case R.styleable.MyView_bool: b = a.getBoolean(index, false); break; case R.styleable.MyView_dimens: dimens = a.getDimensionPixelSize(index, 0); break; case R.styleable.MyView_text: mTitle=a.getString(index); break; case R.styleable.MyView_background: // try { // background = a.getColor(index,Color.BLACK); // } catch (Exception e) { // System.out.println("------getColor Exception-----"); // backgroundDrawable=a.getDrawable(index); // } backgroundDrawable=a.getDrawable(index); break; case R.styleable.MyView_image: image = a.getDrawable(index); break; case R.styleable.MyView_Visibility: visiblity = a.getInt(index, 0); break; } }
最后打印输出一下各个数据
StringBuilder sb=new StringBuilder() .append("textcolor="+textcolor) .append("\nf="+f) .append("\ninteger="+integer) .append("\nb="+b) .append("\ndimens="+dimens) .append("\nmTitle="+mTitle) .append("\nbackground="+background) .append("\nbackgroundDrawable="+backgroundDrawable) .append("\nimage="+image) .append("\nvisiblity="+visiblity) ; System.out.println(sb.toString());
注意:获取完属性后调用TypedArray 的recycle方法!!!!!!!!
a.recycle();
4、复写onMeasure方法测量自 3ff7 定义view的宽高
虽然这个方法不是必须复写的、但是不复写可能或显示不正常,比如wrap_content时是全屏等
代码如下,是会在一段文字,注释掉的部分是绘制图片时测试宽高的方法
int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { mPaint.setTextSize(mTitleTextSize); mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds); float textWidth = mBounds.width(); int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight()); width = desired; //width=bitmap.getWidth()+getPaddingLeft()+getPaddingRight(); } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { mPaint.setTextSize(mTitleTextSize); mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds); float textHeight = mBounds.height(); int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom()); height = desired; //height=bitmap.getHeight()+getPaddingTop()+getPaddingBottom(); } <strong></strong><pre name="code" class="html"> setMeasuredDimension(width, height);
千万记住最后调用setMeasuredDimension(width, height);方式设置尺寸
5、复习onDraw方法,绘制想要的界面
注释掉部分为画图片的代码
FontMetrics fontMetrics = mPaint.getFontMetrics(); canvas.drawText(mTitle, getWidth() / 2 - mBounds.width() / 2, //getHeight() / 2 + mBounds.height() / 2, //-fontMetrics.top, getHeight()/2-(fontMetrics.ascent+fontMetrics.descent)/2, mPaint); System.out.println("----------------------------------"); System.out.println("getw="+getWidth()+",getH="+getHeight()); System.out.println("canvas.getw="+canvas.getWidth()+",canvas.geth="+canvas.getHeight()); System.out.println("mBounds.w="+mBounds.width()+",mBounds.h="+mBounds.height()); System.out.println("getpaddingl="+getPaddingLeft()+",getpaddingr="+getPaddingRight()); mPaint.setColor(Color.RED); canvas.drawLine(0, getHeight()/2, getWidth(), getHeight()/2, mPaint);//画中心线看文字是否画得垂直居中 // canvas.drawBitmap(bitmap, // getWidth()/2-bitmap.getWidth()/2, // getHeight()/2-bitmap.getHeight()/2, // mPaint);
6、定义好View后View的使用方法
6.1 在代码中使用的话、(应该在自定义view中实现相关属性field的get、set方法)直接new出实例后addView到ViewGroup中
6.2在布局文件中使用
<com.example.myview.MyView android:id="@+id/myview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:padding="15dip" csl:TextColor="#00f" csl:f="123.0" csl:i="36" csl:bool="true" csl:dimens="20dp" csl:text="songlin_2015" csl:background="#0f0" csl:image="@drawable/ic_launcher" csl:Visibility="GONE" textsize="150" />
有问题请多多指教
代码下载
最后来一张效果图压压惊:
------end----- 关于测量文字和绘制文字单独记录一篇
相关文章推荐
- android自定义View及事件
- [AndroidUI]自定义view(四):实现圆形圆角图片
- Android自定义View底部连续圆环效果
- Android 自定义View 饼图
- Android自定义view-文本自动换行
- Android自定义View - QQ小红点
- Android自定义View实现圆弧进度效果
- Android 自定义 View 之处理 TouchEvent
- 自定义View的时候,报错android.view.InflateException: Binary XML file line #0: Binary XML file line #0:
- 安卓主activity引用自定义的View——Android LayoutInflater原理分析
- Android-自定义View
- Android自定义View
- Android自定义view(圆形进度条)
- Android -- 自定义view
- Android 自定义View (二)
- Android 自定义View 总结
- Android自定义View实现左右滑动选择出生年份
- Android 仪表进度条 自定义View
- Android 自定义View系列之PathMeasure+Loading效果+小车跑道移动效果
- Android 自定义View之中国地图热点区域分布