自定义视图最重要的部分是它的外观.你可以根据应用的需求简单或复杂的实现它. 这个教程包含了最常见的操作.
重写onDraw()
绘制自定义视图里最重要的一步是重写onDraw())方法. onDraw())的参数是视图可以用来绘制自己的Canvas对象. Canvas定义用来绘制文本、线条、位图和其他图像单元. 你可以在onDraw())里使用这些方法创建你的自定义用户界面(UI).
不过, 在你调用任何绘画的方法之前, 你必须创建Paint对象. 下一章节将会探讨Paint的更多细节.
创建绘画对象
android.graphics框架把绘图分成了两部分:
例如, Canvas提供画线条的方法, 而Paint提供定义线条颜色的方法. Canvas提供画矩形的方法, 而Paint定义是否用颜色填充矩形或让它为空. 简而言之, Canvas定义你可以在屏幕上画的形状, 而Paint为你画的每个形状定义颜色、样式、字体等等.
所以, 在你画任何东西之前, 你需要创建一个或多个Paint对象. * PieChart_'(饼图)例子的'_init()* 方法里有这样的实现, 这个方法在构造函数里调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private void init() {
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(mTextColor);
if (mTextHeight == 0) {
mTextHeight = mTextPaint.getTextSize();
} else {
mTextPaint.setTextSize(mTextHeight);
}
mPiePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPiePaint.setStyle(Paint.Style.FILL);
mPiePaint.setTextSize(mTextHeight);
mShadowPaint = new Paint(0);
mShadowPaint.setColor(0xff101010);
mShadowPaint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));
...
|
提前创建对象是一个很重要的优化. 视图频繁的被重画, 并且许多绘图对象初始化需要消耗大量的资源. 在onDraw())方法里创建绘图对象会严重降低性能, 并可以让你的UI显得有些迟钝.
处理布局事件
为了正确的绘制你的自定义视图, 你需要知道它的大小. 复杂的自定义视图经常需要根据它的大小和在屏幕上的图形区域执行多次布局计算. 你永远不应该假设视图在屏上的大小. 即使只有一个应用使用你的视图, 应用也需要处理不同的屏幕尺寸, 多种屏幕分辨率, 以及在横屏和竖屏模式下的各种高宽比.
虽然View有很多处理尺寸大小的方法, 但是大部分的需要重写. 如果你的视图不需要特别控制它的大小, 你只需要重写方法: onSizeChanged() .
onSizeChanged()在你的视图第一次分配大小的时候调用, 如果你的视图因为任何原因改变了大小也会再次调用. 在该方法里计算位置、大小和其他一些与视图大小相关的值, 而不是你每次绘制的时候重新计算. 在PieChart(饼图)例子里, PieChar视图在onSizeChanged()里计算饼图的图形边界、文本标签的相对位置和其他视觉元素.
当你的视图分配了一个大小, 布局管理器会假设这个大小包含了所有视图的padding值. 你必须在计算你视图的大小的时候处理padding值. 下面是PieChart.onSizeChanged()中处理这个的代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 |
// 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);
|
如果你需要出色的控制你视图的布局参数, 实现int) onMeasure()方法. 这个方法的参数是View.MeasureSpec值, 这个会告诉你你的视图的父元素想让你的视图有多大, 并且告诉你这个大小是否是最大值或只是一个建议. 作为优化, 这些值保存为整数的封装类型, 你可以用View.MeasureSpec里的静态方法解析每个整数里面的信息.
下面是实现int) onMeasure()的例子. 在这个实现里面, PieChart尝试让它的面积大小足以让饼图可以标签一样大:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Try for a width based on our minimum
int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
int w = resolveSizeAndState(minw, widthMeasureSpec, 1);
// Whatever the width ends up being, ask for a height that would let the pie
// get as big as it can
int minh = MeasureSpec.getSize(w) - (int)mTextWidth + getPaddingBottom() + getPaddingTop();
int h = resolveSizeAndState(MeasureSpec.getSize(w) - (int)mTextWidth, heightMeasureSpec, 0);
setMeasuredDimension(w, h);
}
|
在这段代码中有三个重点需要注意:
-
- 计算需要考虑视图的padding. 如上所述, 这个是视图的职责.
-
- 方法resolveSizeAndState()用来创建最终的宽和高. 这个方法通过比较视图的期望大小返回一个合适的View.MeasureSpec值传入int) onMeasure()
-
- onMeasure()方法没有返回值. 相反, 这个方法通过调用int) setMeasureDismension()方法传递结果. 调用这个方法是强制的. 如果你省略这个, View类会抛出runtime exception
绘图
一旦你有了创建的对象和定义了测绘布局的代码, 你可以实现方法onDraw()) . 每个视图实现不同的onDraw()) , 但是这里有些大多数视图常用的操作:
-
使用drawText()画文本, setTypeface())指定字体, setColor())指定文本颜色
-
画基本的形状用drawRect()) 、drawOval()) 、drawArc()) . 不论改变图形的填充样式还是边框样式还是都修改, 都是调用setStyle())
-
绘制复杂的形状用Path类. 通过给Path对象增加线条和曲线定义形状, 然后使用drawPath())绘制形状. 就像基本的形状一样, Path可以设置填充样式、边框样式、或者都设置, 都依靠setStyle())
-
定义渐变的填充样式通过创建LinearGradient对象. 在要填充的形状上通过调用setShader())使用LinearGradient对象
-
绘制位图使用drawBitmap()) .
例如, 这是是画PieChart的代码. 它混合使用了文本、线条、图形.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 = 0; i < mData.size(); ++i) {
Item it = mData.get(i);
mPiePaint.setShader(it.mShader);
canvas.drawArc(mBounds,
360 - it.mEndAngle,
it.mEndAngle - it.mStartAngle,
true, mPiePaint);
}
// Draw the pointer
canvas.drawLine(mTextX, mPointerY, mPointerX, mPointerY, mTextPaint);
canvas.drawCircle(mPointerX, mPointerY, mPointerSize, mTextPaint);
}
|
相关推荐
5. **响应触摸事件**:如果需要,我们还可以覆盖`onTouchEvent(MotionEvent event)`方法,使自定义视图能够处理触摸事件。例如,当用户旋转罗盘时,可以更新指针的方向。 6. **属性解析**:为了在XML布局文件中设置...
总的来说,"android surfaceview自定义拍照 绘制头像轮廓"是一个结合了Android视图系统、摄像头API、图像处理技术的项目。通过理解并实践这个项目,开发者可以深入学习Android的底层图形处理以及如何利用第三方库...
3. **绘制逻辑**:在自定义视图中,你需要覆盖`onDraw()`方法。这是你添加图形绘制代码的地方,使用`Canvas`对象来绘制你的视图。例如,`DrawPathDemo`可能使用`canvas.drawPath()`方法绘制路径。 ```java @...
本示例中的"android自定义视图 比例图"着重讲解如何创建一个由三部分组成的视图:中间的文字、文字周围的圆圈以及最外层的圆环。这种视图常用于展示数据的比例或进度,例如健康应用中的步数完成度、电量指示等。 ...
通过分析和研究`DrawingView-master`中的代码,我们可以深入了解Android自定义视图的工作原理,同时也可以学习到如何处理触摸事件、图形绘制、性能优化等方面的知识。这对于提升Android开发技能,尤其是进行高度定制...
综上所述,这个"Android-自定义View绘制一个太极旋转图片demo"涵盖了Android开发中的自定义视图绘制、动画效果以及资源管理等多个核心知识点。通过实践这个项目,开发者不仅可以提升Android图形绘制的能力,还能掌握...
总结来说,为Android自定义视图添加单击事件主要涉及以下几个步骤: 1. 创建自定义视图类,继承自`View`或其子类。 2. 实现`onDraw()`方法,绘制视图内容。 3. 重写`onTouchEvent()`方法,处理触摸事件,特别是`...
在Android开发中,自定义组件是一项重要的技能,它允许开发者根据特定需求创建独特且功能丰富的视图。本示例——"Android:自定义组件绘制饼状统计图",旨在教你如何构建一个能够显示数据比例的饼状图。下面将详细...
这是一个示例应用程序,它使用 Android 旋转传感器并使用自定义视图(姿态指示器,又名“人工...绘制自定义视图,包括使用 Porter-Duff 传输模式创建抗锯齿圆形切口。 更多详情、使用方法,请下载后细读README.md文件
本项目“Android自定义视图实现水波从中心扩散效果”是针对IT计算机专业的毕业设计,旨在教授学生如何通过编程实现一个视觉效果酷炫的水波扩散动画。下面将详细介绍这个项目的重点知识点。 1. **自定义视图基础**:...
在Android开发中,自定义视图是实现独特用户体验和界面设计的关键技术。"安卓视图效果相关-Android自定义图片视图.rar"这个压缩包很可能包含了一系列用于展示自定义图片视图的源代码示例。自定义视图允许开发者超越...
在Android开发中,自定义视图是提升应用独特性和用户体验的重要手段。自定义视图允许开发者根据需求创建具有特殊功能或独特设计的组件,而不仅仅局限于Android SDK提供的默认视图。本教程将深入探讨如何在Android中...
在Android开发中,自定义视图是提升应用界面独特性和功能扩展性的重要手段。自定义视图允许开发者根据特定需求创建独特的UI元素,这既包括视觉样式也包括交互逻辑。以下将详细介绍自定义视图的基本步骤、自定义属性...
在Android开发中,自定义视图(Custom View)是一项重要的技能,它允许开发者根据特定需求创建独特的用户界面组件。本文将深入探讨如何在Android中实现自定义视图,包括其核心概念、步骤以及最佳实践。 首先,理解...
在Android开发中,自定义日历视图是一个常见的需求,特别是在构建日程管理或时间规划类应用时。本文将深入探讨如何实现一个自定义的Android日历周视图,并结合ViewPager实现无限滑动功能。 首先,我们需要理解...
总结来说,这个压缩包中的代码示例涵盖了Android自定义视图、动画实现、图形绘制以及用户交互处理等多个关键知识点。通过学习和理解这个示例,开发者可以更好地掌握Android视图定制的技巧,为自己的应用添加更具吸引...
总之,创建一个卡片堆叠显示效果的Android自定义视图涉及到动画处理、布局管理、事件监听等多个方面,需要对Android UI框架有深入理解。通过学习和实践,开发者可以创造出更加富有创新和吸引力的用户界面。
在Android开发中,自定义组件是一项重要的技能,它允许开发者根据特定需求创建具有独特功能和视觉效果的视图。本文将深入探讨如何利用Android的Canvas API来实现一个自定义组件,用于绘制柱状统计图。柱状统计图是一...
在Android开发中,自定义画布Canvas是实现图形绘制的核心工具。Canvas提供了丰富的API,允许开发者在屏幕上绘制各种形状、图像以及文字等。本教程将深入探讨如何利用Canvas实现绘制和清空画布的功能。 首先,我们...