最近项目需要,需要做一个BMI指数的指示条,先上效果图:

BMI指数从18到35,然后上面指示条的颜色会随着偏移量的变化而改变,数字显示当前的BMI指数,下面的BMI标准也是根据不同数值的范围来判断的。考虑到这个view的特殊性,最后采用的是自定义的view来完成的。

1.页面布局:

android:layout_width="fill_parent"

android:layout_height="100dp"

android:layout_marginLeft="5dp"

android:layout_marginRight="5dp"

android:layout_marginTop="50dp"

android:background="@color/white"

android:orientation="horizontal" >

style="@style/w_wrap_h_wrap"

android:layout_marginTop="@dimen/login_hei"

android:text="@string/bmi_text"

android:textColor="@color/gray"

android:textSize="@dimen/login_edit_border_margin" />

android:id="@+id/bmiview"

android:layout_width="fill_parent"

android:layout_height="fill_parent" />

左边是BMI文字,右边是自定义的view,没啥说的,下面是view的具体过程:

2.代码实现:新建一个NewBmiView类,并且继承自view类,然后添加构造方法;

public class NewBmiView extends View {

/** 分段颜色 */

private static final int[] SECTION_COLORS = { Color.rgb(255, 204, 47), Color.GREEN,

Color.RED };

/** 画笔 */

private Paint mPaint;

private Paint textPaint;

private Paint drawablePaint;

private Paint drawableBMIPaint;

private Paint bmiTextpaint;

private int bmiwidth, mWidth, mHeight, widthSum;

private double value;

private double i;

private double bmi;

private float valueWidth;

private String bmiText;

// 定义计算颜色的参数

private int x, y, z;

public NewBmiView(Context context) {

super(context);

initviews(context);

}

public NewBmiView(Context context, AttributeSet attrs) {

super(context, attrs);

initviews(context);

}

public NewBmiView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initviews(context);

}

private void initviews(Context context) {

}

然后就是重写onMeasure与onDraw这两个方法,通过onMeasure这个方法获取到了view的宽高,关于具体设置,可以参考鸿洋大神的相关说明:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);

int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);

int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

if (widthSpecMode == MeasureSpec.EXACTLY

|| widthSpecMode == MeasureSpec.AT_MOST) {

widthSum = widthSpecSize;

} else {

widthSum = 0;

}

if (heightSpecMode == MeasureSpec.AT_MOST

|| heightSpecMode == MeasureSpec.UNSPECIFIED) {

mHeight = dipToPx(15);

} else {

mHeight = heightSpecSize;

}

setMeasuredDimension(widthSum, mHeight);

}

然后重点就是onDraw这个方法了:

// 画自定义的渐变条

mPaint = new Paint();

// 去除锯齿

mPaint.setAntiAlias(true);

// 自定义圆角的弧度

int round = mHeight / 20;

// 新建矩形

RectF rectBg = new RectF(bmiwidth, mHeight - (mHeight * 1 / 2), mWidth

+ bmiwidth, mHeight - (mHeight * 2 / 5));

// 设置渐变色

// CLAMP重复最后一个颜色至最后

// MIRROR重复着色的图像水平或垂直方向已镜像方式填充会有翻转效果

// REPEAT重复着色的图像水平或垂直方向

LinearGradient shader = new LinearGradient(bmiwidth, mHeight

- (mHeight * 1 / 2), mWidth + bmiwidth, mHeight

- (mHeight * 2 / 5), SECTION_COLORS, null,

Shader.TileMode.MIRROR);

mPaint.setShader(shader);

// rect:RectF对象。x方向上的圆角半径。ry:y方向上的圆角半径。paint:绘制时所使用的画笔。

canvas.drawRoundRect(rectBg, round, round, mPaint);

// 画下面的小箭头

drawablePaint = new Paint();

drawablePaint.setAntiAlias(true);

Bitmap arrowBitmap = BitmapFactory.decodeResource(getResources(),

R.drawable.arrow_up);

canvas.drawBitmap(arrowBitmap, mWidth * 2 / 17 + bmiwidth, mHeight

- (mHeight * 2 / 5) + 5, drawablePaint);

canvas.drawBitmap(arrowBitmap, mWidth * 7 / 17 + bmiwidth, mHeight

- (mHeight * 2 / 5) + 5, drawablePaint);

canvas.drawBitmap(arrowBitmap, mWidth * 12 / 17 + bmiwidth, mHeight

- (mHeight * 2 / 5) + 5, drawablePaint);

// 画下方的文字

String text = "偏瘦";

Rect textBounds = new Rect();

textPaint = new Paint();

textPaint.setAntiAlias(true);

textPaint.setColor(Color.GRAY);

textPaint.setTextSize(30);

// 获取字体的高宽

textPaint.getTextBounds(text, 0, text.length(), textBounds);

float textWidth = textBounds.width();

float textHeight = textBounds.height();

canvas.drawText("偏瘦", (mWidth * 2 / 17) / 2 - textWidth / 2 + bmiwidth,

mHeight * 7 / 10 + textHeight / 2 + 10, textPaint);

canvas.drawText("标准", (mWidth * 2 / 17) + (mWidth * 5 / 17) / 2

- textWidth / 2 + bmiwidth, mHeight * 7 / 10 + textHeight / 2

+ 10, textPaint);

canvas.drawText("超重", (mWidth * 7 / 17) + (mWidth * 5 / 17) / 2

- textWidth / 2 + bmiwidth, mHeight * 7 / 10 + textHeight / 2

+ 10, textPaint);

canvas.drawText("肥胖", (mWidth * 12 / 17) + (mWidth * 5 / 17) / 2

- textWidth / 2 + bmiwidth, mHeight * 7 / 10 + textHeight / 2

+ 10, textPaint);

// 画上方偏移的小方块

drawableBMIPaint = new Paint();

drawableBMIPaint.setAntiAlias(true);

// 设置颜色

// 通过BMI来RGB计算颜色

i = (value - 18) * (34 / 17);

if (i >= 0 && i <= 17) {

x = (int) ((17 - i) * (255 / 17));

y = 204;

z = 47;

}

if (i > 17 && i <= 34) {

x = (int) ((i - 17) * (255 / 17));

y = (int) ((34 - i) * (255 / 17));

z = 0;

}

drawableBMIPaint.setColor(Color.rgb(x, y, z));

System.out.println("颜色值为" + String.valueOf(x) + String.valueOf(y)

+ String.valueOf(z));

canvas.drawRect(getvalue(), mHeight / 6, getvalue() + bmiBitmap.getWidth(),

bmiBitmap.getHeight()+mHeight / 6, drawableBMIPaint);

System.out.println("偏移量为" + getvalue());

canvas.drawBitmap(bmiBitmap, getvalue(), mHeight / 6, drawablePaint);

// 画上方偏移的小方块里面的文字

String bmitext = "40.0";

Rect bmitextBounds = new Rect();

bmiTextpaint = new Paint();

bmiTextpaint.setAntiAlias(true);

bmiTextpaint.setTextSize(35);

bmiTextpaint.setColor(Color.WHITE);

// 获取字体的高宽

bmiTextpaint.getTextBounds(bmitext, 0, bmitext.length(), bmitextBounds);

canvas.drawText(bmiText, getvalue() - (bmitextBounds.width() / 2)

+ bmiwidth, mHeight / 3 + (bmitextBounds.height() / 3),

bmiTextpaint);

其中需要注意的是,这里小方块的颜色值我是根据BMI值大小,算出RGB三原色的渐变值,没有找到系统自带渲染渐变条的方法中,提供的颜色值,所以就用这种方法计算出来,会有一定得误差。

然后就是关于Textview,因为自带宽高,所以在绘制Textview的时候,需要考虑宽高再绘制。

通过set方法传递参数

public void setBmi(double bmi) {

this.value = bmi;

// 设置颜色

if (value < 18) {

this.value = 18;

} else if (value > 35) {

this.value = 35;

}

invalidate();

}

public void setBmiText(String bmiText) {

this.bmiText = bmiText;

}

最后就是在activity中应用了:

bmiview= (NewBmiView) getView().findViewById(R.id.bmiview);

//将BMI指数传递过去

bmiview.setBmi(35);

bmiview.setBmiText("35.0");

然后就达到了预期的效果,代码有点乱~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

安卓bmi项目_Android自定义View实现BMI指数条相关推荐

  1. android 自定义view滚动条,Android自定义View实现等级滑动条的实例

    Android自定义View实现等级滑动条的实例 实现效果图: 思路: 首先绘制直线,然后等分直线绘制点: 绘制点的时候把X值存到集合中. 然后绘制背景图片,以及图片上的数字. 点击事件down的时候 ...

  2. android自定义view 模仿win10进度条

    android自定义view 模仿win10进度条 本文已授权微信公众号:鸿洋(hongyangAndroid)在微信公众号平台原创首发. PS:有朋友反映动画无法播放,那是因为PathMeasure ...

  3. android自定义view圆环,Android自定义View实现圆环进度条

    本文实例为大家分享了android自定义view实现圆环进度条的具体代码,供大家参考,具体内容如下 效果展示 动画效果 view实现 1.底层圆环是灰色背景 2.上层圆环是红色背景 3.使用动画画一条 ...

  4. 安卓bmi项目_Android|BMI体质计算器实现(附测试源码)

    大家好,我是执念.本博文源于安卓基础,主要介绍如何实现BMI体质计算器.先讲规则后讲实现 体质计算规则 胖瘦程度 体质指数 过轻 男性低于20,女性低于19 适中 男性20-25,女性19-24 超重 ...

  5. 安卓仿苹果音量调节_android自定义view仿照MIUI中音量控制效果

    先看效果图: 这就是miui中的音量效果图,实现思路是自定义视图,绘制圆环,然后设置进度显示. 核心代码在onDraw中实现如下: @Override protected void onDraw(Ca ...

  6. android canvas绘制圆角_Android自定义View撸一个渐变的温度指示器(TmepView)

    秦子帅明确目标,每天进步一点点..... 作者 |  andy 地址 |  blog.csdn.net/Andy_l1/article/details/82910061 1.概述 自定义View对需要 ...

  7. android绘制心形_Android自定义View系列(一)——打造一个爱心进度条

    写作原因:Android进阶过程中有一个绕不开的话题--自定义View.这一块是安卓程序员更好地实现功能自主化必须迈出的一步.下面这个系列博主将通过实现几个例子来认识安卓自定义View的方法.从自定义 ...

  8. android java 圆角_Android自定义View实现带4圆角或者2圆角的效果

    1 问题 实现任意view经过自定义带4圆角或者2圆角的效果 2 原理 1) 实现view 4圆角 我们只需要把左边的图嵌入到右边里面去,最终显示左边的图就行. 2) 实现view上2圆角 我们只需要 ...

  9. android 清空canvas部分内容_Android自定义View实现圆形头像效果

    在我们的APP中通常会遇到,展示圆形头像的需求,一般通过Glide就能实现,但是让我们做一个圆形头像,如果让我们自定义实现这种效果,该怎样做呢? 好,接下来本文通过三种方式来实现这种效果! 注意:这是 ...

最新文章

  1. 阿里开源组装式 Flutter 应用框架 Fish Redux
  2. 分享一款博客园皮肤及其解决方案
  3. Spring IOC和MVC基础知识
  4. 【学术相关】为什么吐槽导师的帖子几乎全是理工科类?文科的研究生都在干嘛?...
  5. 小明分享|sigmstar SSD201/SSD202 针对MIPI的LCD屏配置操作说明分享,更多Sigmastar相关技术文档及沟通讨论,可以给小明留言,小明邀请你进入我们的技术沟通群
  6. [agc014d] Black and White Tree(玄学树D)
  7. Python3网络爬虫(四): 登录
  8. 通过福禄克测试仪进行数据中心机房各个区域的测试或认证
  9. CYQ.Data 数据框架 V4.0 开源版本发布(源码提供下载,秋色园V2.5版本标配框架)
  10. win10下JDK环境变量配置与IDEA开发工具清晰简洁步骤,迈出Java学习第一步
  11. 关于C++中二维vector使用
  12. python官网网址是什么意思_大家都是怎么部署python网站的?
  13. 第一百零四天 how can I 坚持
  14. [基础]sizeof和strlen
  15. 关于在Webservice里使用LinqToSQL遇到一对多关系的父子表中子表需要ToList输出泛型而产生循环引用错误的解决办法!...
  16. JMeter压力测试高并发测试
  17. 【经典】具有中国特色的脑筋急转弯
  18. 上海电信中兴B860A 4K版破解
  19. 局域网计算机怎样注销用户名,win10系统取消局域网共享用户名密码的解决办法...
  20. java实现ftp文件上传失败_用java+ftp实现文件上传的问题?

热门文章

  1. 【剑指 offer】(二十九)—— 数组中出现次数超过一半的数字(及该数字出现的次数)
  2. 实用的 Python 之 feedparser
  3. linux创建空镜像,Docker创建base镜像
  4. vue 心跳监控_Vue中WebSocket加入心跳机制
  5. 怎样学好python编程-3个月学好Python有多简单?
  6. python做excel自动化-用Python控制Excel实现自动化办公,手把手教你
  7. python可以给你干什么-你最想用python做什么?python到底能用来做什么?
  8. python里怎么读取文件-python之文件读写
  9. python工资一般多少p-Python是什么?简单了解pythonp-入门
  10. 学了python可以干嘛-学Python后到底能干什么?网友:我太难了