自定义View(10)*onSizeChanged,onMeasure,onDraw的注意事项及正确写法
2024-08-30 21:47:53
1,onSizeChanged
触发:
当view的第一次分配大小或以后大小改变时的产生的事件。
工作:
计算绘制内容的位置,面积等相关值。避免每次在onDraw中计算了。
注意:
计算时不要忘记padding。这是个责任。
示范:
// Account for padding
float xpad = (float)(getPaddingLeft() + getPaddingRight());
float ypad = (float)(getPaddingTop() + getPaddingBottom()); // Account for the label
if (mShowText) xpad += mTextWidth; float ww = (float)w - xpad;
float hh = (float)h - ypad; // Figure out how big we can make the pie.
float diameter = Math.min(ww, hh);
2,onMeasure
触发:
当父控件布局时,要测量子控件的大小,当调用子控件measure要求强制测量或实在无法确定其大小时(先是上次MeasureSpec值不同,再是缓存中找不到对应值),触发子控件onMeasure,子控件在其中确定和部分绘制内容的大小。
见: http://www.cnblogs.com/sjjg/p/5193909.html
工作:
解析传来的参数,设置各绘制内容大小。
注意:
a,传来的参数是长宽的压缩值,要解析后只是最大或建议的大小,可以在onMeasure中指定最大范围内的值。
b,并且必需调用 setMeasuredDimension方法。
c,不要忘记padding。这是个责任。
示范:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Try for a width based on our minimum
//最小宽度
int w = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth(); //如果给出的建议是0,可以手动设置一个期望值。单位是像素。同时这步一定要在resolveSizeAndState前,
// 因为它可能大于widthMeasureSpec的最大值。
if (w == ) w = ; //计算最佳值,在其中解析了 widthMeasureSpec
w = resolveSizeAndState(w, widthMeasureSpec, ); // Whatever the width ends up being, ask for a height that would let the pie
// get as big as it can
//最小高度
int h = getSuggestedMinimumHeight() + getPaddingBottom() + getPaddingTop(); //如果给出的建议是0,可以手动设置一个期望值。单位是像素。同时这步一定要在resolveSizeAndState前,
// 因为它可能大于heightMeasureSpec的最大值。
if (h == ) h = ; //计算最佳值,在其中解析了 heightMeasureSpec
h = resolveSizeAndState(h, heightMeasureSpec, ); //将量算的结果保存到View的成员变量mMeasuredWidth 和mMeasuredHeight中。
setMeasuredDimension(w, h); // 量算完成之后,View的父控件就可以通过调用
// getMeasuredWidth、getMeasuredState、getMeasuredWidthAndState
// 这三个方法获取View的量算结果。 }
3,onDraw
触发:
绘制事件,绝大多数时是由于调用invalidate()触发。
工作:
绘制点,线,图形,路径,图片等。
注意:
这个方法调用频度非常高,不要在里面申请内存,不要绘制时间过长,不要重复计算等。少调用invalidate()。
示范:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // Draw the shadow
canvas.drawOval(
mShadowBounds,
mShadowPaint
); // Draw the label text
canvas.drawText(mData.get(mCurrentItem).mLabel, mTextX, mTextY, mTextPaint); // Draw the pie slices
for (int i = ; i < mData.size(); ++i) {
Item it = mData.get(i);
mPiePaint.setShader(it.mShader);
canvas.drawArc(mBounds,
- it.mEndAngle,
it.mEndAngle - it.mStartAngle,
true, mPiePaint);
} // Draw the pointer
canvas.drawLine(mTextX, mPointerY, mPointerX, mPointerY, mTextPaint);
canvas.drawCircle(mPointerX, mPointerY, mPointerSize, mTextPaint);
}
最新文章
- C#在函数内部获取函数的参数
- win7下安装和使用Windows XP Mode
- js 实现动态的图片时钟
- spring security 控制用户信息用户加密 缓存用户信息
- DELETE与TRUNCATE的区别
- JAVA 边界布局管理器
- 通过jstack定位在线执行java系统故障_案例1
- spring boot -Properties &; configuration
- PyJWT 使用
- 服务器性能调优(netstat监控大量ESTABLISHED连接与Time_Wait连接问题)
- pta7-18奥运排行榜(模拟)
- object &; over-write
- voith项目配置服务程序
- BestCoder Round #41 记。
- Django+Nginx+uwsgi搭建自己的博客(三)
- matlab 常用集合相关的函数
- 【bzoj4491】我也不知道题目名字是什么 离线扫描线+线段树
- Linux rsync数据定时增量备份
- flink学习笔记-flink实战
- symbol访问法及symbor注册表