新手自定义view练习实例之(二) 波浪view
本系列是为新手准备的自定义view练习项目(大牛请无视),相信在学习过程中,想学自定义view又无从下手,不知道做什么。本系列为新手提供了一系列自定义view的简单实例。看过理解之后,自己实现,相信会有很大提高。
转载请注明本篇出处:http://blog.csdn.net/wingichoy/article/details/50460213
继续来本系列的第二篇,启发是吃口香糖看到了包装纸,觉得挺好看,就想画一个出来#职业病#,本次的目标是做一个波浪形状的view,可以是尖角,也可以是圆角。
那么老规矩,上效果图:
聪明的你一眼就看出来了,不就是个矩形加好多三角嘛。答对了,就是这么简单,事不宜迟,快拿起武器动手练一练。毕竟程序员的秘诀就是“无他,唯手熟尔”。
首先,新建一个类 起名为WaveView 继承自View,重写他的构造方法,在第三个构造方法里获取自定义属性。
public WaveView(Context context) {
this(context, null);
}
public WaveView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.WaveView,defStyleAttr,0);
mWaveCount = a.getInt(R.styleable.WaveView_waveCount,10);
mWaveWidth = a.getInt(R.styleable.WaveView_waveWidth,20);
mMode = a.getInteger(R.styleable.WaveView_mode,-2);
mColor = a.getColor(R.styleable.WaveView_android_color,Color.parseColor("#2C97DE"));
}
自定义属性如下 attr.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="WaveView">
<attr name="waveCount" format="integer"/>
<attr name="waveWidth" format="integer"/>
<attr name="android:color"/>
<attr name="mode" >
<enum name = "circle" value="-1"/>
<enum name = "triangle" value = "-2"/>
</attr>
</declare-styleable>
</resources>
这些都没有什么好说的,你一定已经轻车熟路。
然后重写他的onMeasure() 来告诉系统这个view有多大。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//矩形宽度为view的80%
if (widthMode == MeasureSpec.EXACTLY) {
mWidth = widthSize; mRectWidth = (float) (mWidth * 0.8); //如果是wrap_content 直接给一个定值
}else if(widthMode == MeasureSpec.AT_MOST){
mWidth = PxUtils.dpToPx(300,mContext); mRectWidth = (float) (mWidth * 0.8); } //矩形高度为view的80%
if (heightMode == MeasureSpec.EXACTLY) {
mHeight = heightSize;
mRectHeight = (float) (mHeight * 0.8);
//如果是wrap_content 直接给一个定值
}else if(heightMode == MeasureSpec.AT_MOST){ mHeight = PxUtils.dpToPx(200,mContext); mRectHeight = (float) (mHeight * 0.8);
} setMeasuredDimension(mWidth, mHeight);
}
准备工作大致已经完成,接下来开始绘图。首先 画一个矩形。
这个矩形让他处于view的中间,看图:
由图可知, 矩形的左上坐标为 padding ,padding 矩形的右下坐标为padding +mRectWidth, padding + mRectHeight
其中padding 为 (mWidth - mRectWidth)/2 注意这里只是左右padding 为了简易 就不计算上下padding了。
所以我们先将矩形绘制出来,如下图: 可以看到左右padding是相等的,上下不等,这是因为上面只计算了左右padding
protected void onDraw(Canvas canvas) {
Paint p = new Paint();
p.setColor(mColor);
//计算每个三角形的高
mWaveHeight = mRectHeight / mWaveCount;
//绘制矩形
//计算padding
float padding = ((mWidth - mRectWidth) / 2);
canvas.drawRect(padding, padding, mRectWidth + padding, mRectHeight + padding, p);
绘制矩形完毕,需要来一个判断,判断当前模式是圆角还是尖角
if(mMode == MODE_TRIANGLE) {}else{}
我们首先来绘制尖角,还记得上一篇泡泡窗的那个三角吗,我们只要画多次不就形成波浪了吗,所以用循环就可以搞定。坐标计算如下:
矩形的右上角暂定为 StartX,StartY 三角形的宽度为 mWaveWidth 高度为 mWaveHeight 那么还是用path来画,首先将path MoveTo startX,startY 然后计算得出各个坐标,在用一个i来代表第几个三角形来做循环,代码如下:
if(mMode == MODE_TRIANGLE) {
//绘制右边的波浪
float startX = padding + mRectWidth;
float startY = padding;
Path path = new Path();
path.moveTo(startX, startY);
for (int i = 0; i < mWaveCount; i++) {
path.lineTo(startX + mWaveWidth, startY + i * mWaveHeight + (mWaveHeight / 2));
path.lineTo(startX, startY + mWaveHeight * (i + 1));
}
path.close();
canvas.drawPath(path, p);
只要把上面的坐标带入进去即可,那么左边的波浪只是改变了一个x坐标的加减值,也很简单。
//绘制左边的波浪
startX = padding;
startY = padding;
path.moveTo(startX, startY);
for (int i = 0; i < mWaveCount; i++) {
path.lineTo(startX - mWaveWidth, startY + i * mWaveHeight + (mWaveHeight / 2));
path.lineTo(startX, startY + mWaveHeight * (i + 1));
} path.close();
canvas.drawPath(path, p);
这样便完成了整个波浪view的绘制。本篇就到此结束了。
别急,我没忘圆形模式,这里给大家留个家庭作业,大家下去根据这个思路自己把圆形波浪画出来吧~ 毕竟只有多练,才能提高
本项目github地址:点击打开链接 ,求关注,求评论,求star
新手自定义view练习实例之(二) 波浪view的更多相关文章
- Android View框架总结(二)View焦点
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52263256 前言:View框架写到第六篇,发现前面第二篇竟然没有, ...
- 【朝花夕拾】Android自定义View篇之(一)View绘制流程
前言 转载请申明转自[https://www.cnblogs.com/andy-songwei/p/10955062.html]谢谢! 自定义View.多线程.网络,被认为是Android开发者必须牢 ...
- Autodesk View and Data API二次开发学习指南
什么是View and Data API? 使用View and Data API,你可以轻松的在网页上显示大型三维模型或者二维图纸而不需要安装任何插件.通过View and Data API,你可以 ...
- python学习_数据处理编程实例(二)
在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...
- C语言库函数大全及应用实例十二
原文:C语言库函数大全及应用实例十二 [编程资料]C语言库函数大全及应用实例十二 函数名: setrgbpalette ...
- java学习--自定义类的实例的大小比较和排序
我们知道Object类有一个equals方法,用于比较两个对象是否相等 我们只要在自定义类中重写了equals方法(若不重写就是比较两个实例的地址,相当于==)就可以用来比较该类的两个实例是否相等 问 ...
- 【微信小程序】自定义模态框实例
原文链接:https://mp.weixin.qq.com/s/23wPVFUGY-lsTiQBtUdhXA 1 概述 由于官方API提供的显示模态弹窗,只能简单地显示文字内容,不能对对话框内容进行自 ...
- Qt5MV自定义模型与实例浅析
1. Model/View结构 这种结构,其实就是将界面组件与所编辑的数据分离开来,又通过数据源的方式连接起来,相当于解耦,视图层只关心显示和与用户交互,而数据层负责与实际的数据进行通信,并为视图组件 ...
- SQL Server 2008 数据库镜像部署实例之二 配置镜像,实施手动故障转移
SQL Server 2008 数据库镜像部署实例之二 配置镜像,实施手动故障转移 上一篇文章已经为配置镜像数据库做好了准备,接下来就要进入真正的配置阶段 一.在镜像数据库服务器上设置安全性并启动数据 ...
随机推荐
- Python 字符串字典内置函数&方法
Python字典包含了以下内置函数: 序号 函数及描述 1 cmp(dict1, dict2)比较两个字典元素. 2 len(dict)计算字典元素个数,即键的总数. 3 str(dict)输出字典可 ...
- Android开发技巧——BaseAdapter的另一种优雅封装
RecyclerView虽然因其灵活性.高效性等特点而备受好评,但也不是一定得用它把ListView给替代掉.在某些场景中,ListView还是相对更适合的.比如数据量不大,不频繁更新,并且需要简单地 ...
- MySQL系列教程(二)
mySQL执行计划 语法 explain <sql语句> 例如: explain select * from t3 where id=3952602; explain输出解释 +---- ...
- Gi之(二)基础命令
三个工作区域 使用Git之前,首先要弄清Git的三个管理区域,有助于理解Git的运行原理,以及每个Git命令对文件造成的影响. 对于任何一个文件,在本地的Git内部都有三种状态: l 已修改(mo ...
- Redis 学习笔记3:Jedis 连接虚拟机下的Redis 服务
Jedis 是 Redis 官方首选的 Java 客户端开发包. 虚拟机的IP地址是192.168.8.88. Jedis代码是放在windows上的,启动虚拟机上的Redis服务之后,用Jedis连 ...
- Swift如何取得View所属的ViewController
从VC取得View很容易,但有些情况下我们需要从View反向获取VC. 不过在一些特殊的场合,Cocoa库帮我们想的很周到,比如在自定义View过渡动画的时候: func animateTransit ...
- [ExtJS5学习笔记]第三十节 sencha extjs 5表格gridpanel分组汇总
本文地址:http://blog.csdn.net/sushengmiyan/article/details/42240531 本文作者:sushengmiyan ------------------ ...
- Dynamics CRM2016 新功能之Solution enhancements
CRM2016中对解决方案的功能有了一定的加强,CRM自2011版本开始引入了solution的概念,但大家的共识是solution的导出导入以及发布都非常的慢,常常会出现发布超时的情况很是头疼. 以 ...
- Hive-RCFile文件存储格式
在新建Hive表时,可以使用stored as rcfile来指定hive文件的存储方式为RCFile. 一.RCFile文件结构 下图是一个RCFile的文件结构形式. 从上图可以看出: 1)一张表 ...
- Storm并发机制详解
本文可作为 <<Storm-分布式实时计算模式>>一书1.4节的读书笔记 在Storm中,一个task就可以理解为在集群中某个节点上运行的一个spout或者bolt实例. 记住 ...