Android利用温度传感器实现带动画效果的电子温度计
概述
Android利用温度传感器实现带动画效果的电子温度计。
详细
一、准备工作
需要准备一部带有温度传感器的安卓手机,或者使用有温度传感器的模拟器。
二、程序实现
1、需要截图程序结构
2、实现思路怎样
要想实现带动画效果的电子温度计,需要以下几个知识点:
-
温度传感器相关知识。
-
ScaleAnimation动画相关知识,来进行水印刻度的缩放效果。
-
Android:layout_weight属性的合理运用,关于android:layout_weight属性的讲解,可以参考:《我的Android进阶之旅------>关于android:layout_weight属性的一个面试题》
首先来看看本实例的具体效果,然后再来具体实现功能。
1、将温度强制设置为0度时,画面如下:
2、将温度强制设置为50度时,画面如下:
3、将温度强制设置为-20度时,画面如下:
4、从传感器动态得到温度值,并实时更新画面,如下所示:
首先来看布局文件的代码:layout_thermometer.xml
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | <? xml version="1.0" encoding="utf-8"?> < LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/Parent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/background_thermometer" android:clipChildren="false" android:clipToPadding="false" android:gravity="bottom|center" android:keepScreenOn="true" android:orientation="vertical" > < FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="bottom|center" > < LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- 顶部图片 --> < ImageView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/background_top" /> < LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="100.0" android:orientation="horizontal" > <!-- 横向空白占1份 --> < LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="bottom|center" > </ LinearLayout > <!-- 横向占4份 --> < LinearLayout android:id="@+id/meter" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_weight="4" android:animationCache="true" android:background="@drawable/thermometer_dial" android:clipChildren="false" android:clipToPadding="false" android:persistentDrawingCache="all" > <!-- 横向占189份,刻度表左边刻度摄氏温度所占比例 --> < LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="189" android:visibility="invisible" /> <!-- 横向占69份,刻度表水银柱子所在区域所占比例 --> < LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="69" android:orientation="vertical" > <!-- 竖向占131.0份,刻度表50°以上的部分 --> < LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="131.0" /> <!-- 竖向占773.0份,水银针正好等于刻度表从-20°到50° 因为柱子和圆球直接有点断层,把773变成774 默认不显示柱子,当有传感器数据时,才显示出来 --> < LinearLayout android:id="@+id/alcohol" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="774.0" android:background="@drawable/alcohol" android:orientation="horizontal" android:visibility="invisible" /> <!-- 竖向占104.0份 ,刻度表-20°以上的部分 因为柱子和圆球直接有点断层,把104变成103 --> < LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="103.0" /> </ LinearLayout > <!-- 横向占189份,刻度表右边刻度华氏温度所占比例 --> < LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="187" android:visibility="invisible" /> </ LinearLayout > <!-- 横向占4份 --> < LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="150dp" android:layout_weight="4" android:gravity="center" android:orientation="vertical" android:paddingLeft="30dp" > < LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <!-- 摄氏温度 --> < TextView android:id="@+id/thermo_c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#e9bc57" android:textSize="38sp" /> <!-- 摄氏温度图标 --> < ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingLeft="2dp" android:src="@drawable/thermo_c" /> </ LinearLayout > <!-- 分割线 --> < ImageView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/divider" /> < LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <!-- 华氏温度 --> < TextView android:id="@+id/thermo_f" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#dadada" android:textSize="18sp" /> <!-- 华氏温度图标 --> < ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingLeft="2dp" android:src="@drawable/thermo_f" /> </ LinearLayout > </ LinearLayout > <!-- 横向空白占1份 --> < LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="bottom|center" > </ LinearLayout > </ LinearLayout > < LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center_vertical" android:orientation="vertical" > <!-- 作者信息--> < TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#ffff00" android:textSize="18sp" android:text="@string/author" android:layout_gravity="center"/> <!-- 博客地址 --> < TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:autoLink="web" android:text="@string/blog_address" android:textColor="#ffff00" android:textSize="18sp" /> </ LinearLayout > <!-- 尾部图片 --> < ImageView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/background_bottom" /> </ LinearLayout > </ FrameLayout > </ LinearLayout > |
接着看Activity的代码:ThermometerActivity.java
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | package com.oyp.thermometer; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.view.animation.ScaleAnimation; import android.widget.LinearLayout; import android.widget.TextView; /** * @author 欧阳鹏 * @date 2015年9月14日 <br> * <a href="http://blog.csdn.net/ouyang_peng">欧阳鹏CSDN博客地址</a></n> */ public class ThermometerActivity extends Activity implements SensorEventListener { private LinearLayout alcohol; private LinearLayout meter; private SensorManager mSensorManager; private Sensor temperatureSensor; private TextView thermo_c; private TextView thermo_f; public float staratemp; public float temp; private float temperatureC; /** * 获取华氏温度 * * @author ouyang * @date 2015年9月14日 * @return */ public float getTemperatureF() { float temperatureF = (temperatureC * 9 / 5 ) + 32 ; return getFloatOne(temperatureF); } /** * 保留一位小数点 * * @author ouyang * @date 2015年9月14日 * @param tempFloat * @return */ public float getFloatOne( float tempFloat) { return ( float ) (Math.round(tempFloat * 10 )) / 10 ; } /** * 获取摄氏温度 * * @author ouyang * @date 2015年9月14日 * @return */ public float getTemperatureC() { return getFloatOne(temperatureC); } public void setTemperatureC( float temperatureC) { this .temperatureC = temperatureC; } @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.layout_thermometer); meter = ((LinearLayout) findViewById(R.id.meter)); alcohol = ((LinearLayout) findViewById(R.id.alcohol)); thermo_c = (TextView) findViewById(R.id.thermo_c); thermo_f = (TextView) findViewById(R.id.thermo_f); } @Override protected void onResume() { super .onResume(); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); temperatureSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE); mSensorManager.registerListener( this , temperatureSensor, SensorManager.SENSOR_DELAY_NORMAL); } @Override public final void onSensorChanged(SensorEvent event) { float temperatureValue = event.values[ 0 ]; // 得到温度 setTemperatureC(temperatureValue); // 设置温度 mUpdateUi(); // 更新UI } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } /** * 更新刻度上水银柱的长度 * * @author ouyang * @date 2015年9月14日 */ private void mUpdateUi() { ScaleAnimation localScaleAnimation1 = new ScaleAnimation( 1 .0F, 1 .0F, this .staratemp, this .temp, 1 , 0 .5F, 1 , 1 .0F); localScaleAnimation1.setDuration(2000L); localScaleAnimation1.setFillEnabled( true ); localScaleAnimation1.setFillAfter( true ); this .alcohol.startAnimation(localScaleAnimation1); this .staratemp = this .temp; ScaleAnimation localScaleAnimation2 = new ScaleAnimation( 1 .0F, 1 .0F, 1 .0F, 1 .0F, 1 , 0 .5F, 1 , 0 .5F); localScaleAnimation2.setDuration(10L); localScaleAnimation2.setFillEnabled( true ); localScaleAnimation2.setFillAfter( true ); this .meter.startAnimation(localScaleAnimation2); // 把刻度表看出总共700份,如何计算缩放比例。从-20°到50°。 // 例如,现在温度是30°的话,应该占(30+20)*10=500份 其中20是0到-20°所占有的份 this .temp = ( float ) (( 20 .0F + getTemperatureC()) * 10 ) / ( 70 .0F * 10 ); thermo_c.setText(getTemperatureC() + "" ); thermo_f.setText(getTemperatureF() + "" ); } } |
三、运行效果
1、运行,右键项目:Run as -》Android Application
2、如上图所示,也就是这样子:
四、其他补充
暂时没
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?