基于andoird的计步器(全代码)
程序员文章站
2022-08-07 16:07:18
收集了一些资料整理了一个简单计步器,带简单界面,作课程设计的。网上很多都不能用,或者是项目太大,分享一下自己弄的,帮助一下像我这样的苦孩子。最后贴上了运行结果和目录结构。怎么进行改进就看自己了。权限:
收集了一些资料整理了一个简单计步器,带简单界面,作课程设计的。网上很多都不能用,或者是项目太大,分享一下自己弄的,帮助一下像我这样的苦孩子。最后贴上了运行结果和目录结构。
怎么进行改进就看自己了。
权限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.step">
<!-- 计歩需要的权限 -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-feature android:name="android.hardware.sensor.accelerometer" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-feature
android:name="android.hardware.sensor.stepcounter"
android:required="true" />
<uses-feature
android:name="android.hardware.sensor.stepdetector"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".WelcomeShow">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".StepView" />
<activity android:name=".MainActivity"></activity>
<service
android:name=".BindService"
android:enabled="true"
android:exported="true" />
</application>
</manifest>
创建服务,创建的时候注意是服务,别创成类了!!!
BindService
package com.example.step;
import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
public class BindService extends Service implements SensorEventListener {
/**
* binder服务与activity交互桥梁
*/
private LcBinder lcBinder = new LcBinder();
/**
* 当前步数
*/
private int nowBuSu = 0;
/**
* 传感器管理对象
*/
private SensorManager sensorManager;
/**
* 加速度传感器中获取的步数
*/
private StepCount mStepCount;
/**
* 数据回调接口,通知上层调用者数据刷新
*/
private UpdateUiCallBack mCallback;
/**
* 计步传感器类型 Sensor.TYPE_STEP_COUNTER或者Sensor.TYPE_STEP_DETECTOR
*/
private static int stepSensorType = -1;
/**
* 每次第一次启动记步服务时是否从系统中获取了已有的步数记录
*/
private boolean hasRecord = false;
/**
* 系统中获取到的已有的步数
*/
private int hasStepCount = 0;
/**
* 上一次的步数
*/
private int previousStepCount = 0;
/**
* 构造函数
*/
public BindService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.i("BindService—onCreate", "开启计步");
new Thread(new Runnable() {
@Override
public void run() {
startStepDetector();
Log.i("BindService—子线程", "startStepDetector()");
}
}).start();
}
/**
* 选择计步数据采集的传感器
* SDK大于等于19,开启计步传感器,小于开启加速度传感器
*/
private void startStepDetector() {
if (sensorManager != null) {
sensorManager = null;
}
//获取传感器管理类
sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
int versionCodes = Build.VERSION.SDK_INT;//取得SDK版本
if (versionCodes >= 19) {
//SDK版本大于等于19开启计步传感器
addCountStepListener();
} else { //小于就使用加速度传感器
addBasePedometerListener();
}
}
/**
* 启动计步传感器计步
*/
private void addCountStepListener() {
Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
Sensor detectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
if (countSensor != null) {
stepSensorType = Sensor.TYPE_STEP_COUNTER;
sensorManager.registerListener(BindService.this, countSensor, SensorManager.SENSOR_DELAY_NORMAL);
Log.i("计步传感器类型", "Sensor.TYPE_STEP_COUNTER");
} else if (detectorSensor != null) {
stepSensorType = Sensor.TYPE_STEP_DETECTOR;
sensorManager.registerListener(BindService.this, detectorSensor, SensorManager.SENSOR_DELAY_NORMAL);
} else {
addBasePedometerListener();
}
}
/**
* 启动加速度传感器计步
*/
private void addBasePedometerListener() {
Log.i("BindService", "加速度传感器");
mStepCount = new StepCount();
mStepCount.setSteps(nowBuSu);
//获取传感器类型 获得加速度传感器
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//此方法用来注册,只有注册过才会生效,参数:SensorEventListener的实例,Sensor的实例,更新速率
boolean isAvailable = sensorManager.registerListener(mStepCount.getStepDetector(), sensor, SensorManager.SENSOR_DELAY_UI);
mStepCount.initListener(new StepValuePassListener() {
@Override
public void stepChanged(int steps) {
nowBuSu = steps;//通过接口回调获得当前步数
updateNotification(); //更新步数通知
}
});
}
/**
* 通知调用者步数更新 数据交互
*/
private void updateNotification() {
if (mCallback != null) {
Log.i("BindService", "数据更新");
mCallback.updateUi(nowBuSu);
}
}
@Override
public IBinder onBind(Intent intent) {
return lcBinder;
}
/**
* 计步传感器数据变化回调接口
*/
@Override
public void onSensorChanged(SensorEvent event) {
//这种类型的传感器返回步骤的数量由用户自上次重新启动时激活。返回的值是作为浮动(小数部分设置为0),
// 只在系统重启复位为0。事件的时间戳将该事件的第一步的时候。这个传感器是在硬件中实现,预计低功率。
if (stepSensorType == Sensor.TYPE_STEP_COUNTER) {
//获取当前传感器返回的临时步数
int tempStep = (int) event.values[0];
//首次如果没有获取手机系统中已有的步数则获取一次系统中APP还未开始记步的步数
if (!hasRecord) {
hasRecord = true;
hasStepCount = tempStep;
} else {
//获取APP打开到现在的总步数=本次系统回调的总步数-APP打开之前已有的步数
int thisStepCount = tempStep - hasStepCount;
//本次有效步数=(APP打开后所记录的总步数-上一次APP打开后所记录的总步数)
int thisStep = thisStepCount - previousStepCount;
//总步数=现有的步数+本次有效步数
nowBuSu += (thisStep);
//记录最后一次APP打开到现在的总步数
previousStepCount = thisStepCount;
}
}
//这种类型的传感器触发一个事件每次采取的步骤是用户。只允许返回值是1.0,为每个步骤生成一个事件。
// 像任何其他事件,时间戳表明当事件发生(这一步),这对应于脚撞到地面时,生成一个高加速度的变化。
else if (stepSensorType == Sensor.TYPE_STEP_DETECTOR) {
if (event.values[0] == 1.0) {
nowBuSu++;
}
}
updateNotification();
}
/**
* 计步传感器精度变化回调接口
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
/**
* 绑定回调接口
*/
public class LcBinder extends Binder {
BindService getService() {
return BindService.this;
}
}
/**
* 数据传递接口
*/
public void registerCallback(UpdateUiCallBack paramICallback) {
this.mCallback = paramICallback;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
//取消前台进程
stopForeground(true);
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}
MainActivity
package com.example.step;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
private BindService bindService;
private TextView textView;
private boolean isBind;
private StepView mStepView;
private float ProgressAni;
private int ST = 0;
private String AIM ;
private int mAIM;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) { //创建线程更新view
if (msg.what == 1) {
// STEPVIEW.setText(STEP);
new Thread(new Runnable() {
@Override
public void run() {
// while (true){
//mStepView.sleep(1000);
runOnUiThread(new Runnable() {
@Override
public void run() {
ProgressAni = (float)STEP*365/mAIM; //改变蓝条
mStepView.setText(STEP, ProgressAni,AIM);
// mStepView.startCustomAnimation();
}
});
// }
}
}).start();
}
}
};
public int STEP;
private Button start;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent2 =getIntent();
Bundle bun = intent2.getExtras();
AIM = bun.getString("aim");
mStepView = (StepView) findViewById(R.id.shapeView);
//Intent intent = new Intent(MainActivity.this, BindService.class);
//mAIM = Integer.parseInt(AIM);
// isBind = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
//startService(intent);
Button start =(Button)findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, R.string.ST, Toast.LENGTH_LONG).show();
ST = 1;
}
});
}
//和绷定服务数据交换的桥梁,可以通过IBinder service获取服务的实例来调用服务的方法或者数据
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
BindService.LcBinder lcBinder = (BindService.LcBinder) service;
bindService = lcBinder.getService();
bindService.registerCallback(new UpdateUiCallBack() {
@Override
public void updateUi(int stepCount) {
//当前接收到stepCount数据,就是最新的步数
Message message = Message.obtain();
message.what = 1;
if(ST == 1) {
message.arg1 = stepCount;
STEP = stepCount;
handler.sendMessage(message);
Log.i("MainActivity—updateUi", "当前步数" + stepCount);
}
}
});
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onStart() {
super.onStart();
}
@Override
public void onDestroy() { //app被关闭之前,service先解除绑定
super.onDestroy();
if (isBind) {
this.unbindService(serviceConnection);
}
}
}
StepCount
package com.example.step;
import android.util.Log;
/**
*计步逻辑
*/
public class StepCount implements StepCountListener {
private int mCount; //当前步数
private int count; //缓存步数,步数3秒内小于10步则不计数
private long timeOfLastPeak = 0;//计时 开始时间 步数3秒内小于10步则不计数
private long timeOfThisPeak = 0;//计时 现在时间 步数3秒内小于10步则不计数
private StepValuePassListener stepValuePassListener;//接口用来传递步数变化
private StepDetector stepDetector;//传感器SensorEventListener子类实例
public StepCount() {
stepDetector = new StepDetector();
stepDetector.initListener(this);
}
@Override
public void countStep() {
this.timeOfLastPeak = this.timeOfThisPeak;
this.timeOfThisPeak = System.currentTimeMillis();
Log.i("countStep","传感器数据刷新回调");
if (this.timeOfThisPeak - this.timeOfLastPeak <= 3000L) {
if (this.count < 9) {
this.count++;
} else if (this.count == 9) {
this.count++;
this.mCount += this.count;
notifyListener();
} else {
this.mCount++;
notifyListener();
}
} else {//超时
this.count = 1;
}
}
public void setSteps(int initNowBusu){
this.mCount = initNowBusu;//接收上层调用传递过来的当前步数
this.count = 0;
timeOfLastPeak = 0;
timeOfThisPeak = 0;
notifyListener();
}
/**
* 用来给调用者获取SensorEventListener实例
* return 返回SensorEventListener实例
*/
public StepDetector getStepDetector(){
return stepDetector;
}
/**
* 更新步数,通过接口函数通知上层调用者
*/
public void notifyListener(){
if(this.stepValuePassListener != null){
Log.i("countStep","数据更新");
this.stepValuePassListener.stepChanged(this.mCount); //当前步数通过接口传递给调用者
}
}
public void initListener(StepValuePassListener listener){
this.stepValuePassListener = listener;
}
}
StepCountListener(接口)
package com.example.step;
public interface StepCountListener {
void countStep();
}
StepDetector
package com.example.step;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
/*
* 算法的主要部分,检测是否是步点
* */
public class StepDetector implements SensorEventListener {
//存放三轴数据
float[] oriValues = new float[3];
final int ValueNum = 4;
//用于存放计算阈值的波峰波谷差值
float[] tempValue = new float[ValueNum];
int tempCount = 0;
//是否上升的标志位
boolean isDirectionUp = false;
//持续上升次数
int continueUpCount = 0;
//上一点的持续上升的次数,为了记录波峰的上升次数
int continueUpFormerCount = 0;
//上一点的状态,上升还是下降
boolean lastStatus = false;
//波峰值
float peakOfWave = 0;
//波谷值
float valleyOfWave = 0;
//此次波峰的时间
long timeOfThisPeak = 0;
//上次波峰的时间
long timeOfLastPeak = 0;
//当前的时间
long timeOfNow = 0;
//当前传感器的值
float gravityNew = 0;
//上次传感器的值
float gravityOld = 0;
//动态阈值需要动态的数据,这个值用于这些动态数据的阈值
final float InitialValue = (float) 1.3;
//初始阈值
float ThreadValue = (float) 2.0;
//波峰波谷时间差
int TimeInterval = 250;
private StepCountListener mStepListeners;
@Override
public void onSensorChanged(SensorEvent event) {//当传感器值改变回调此方法
for (int i = 0; i < 3; i++) {
oriValues[i] = event.values[i];
}
gravityNew = (float) Math.sqrt(oriValues[0] * oriValues[0]
+ oriValues[1] * oriValues[1] + oriValues[2] * oriValues[2]);
detectorNewStep(gravityNew);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//
}
public void initListener(StepCountListener listener) {
this.mStepListeners = listener;
}
/*
* 检测步子,并开始计步
* */
public void detectorNewStep(float values) {
if (gravityOld == 0) {
gravityOld = values;
} else {
if (detectorPeak(values, gravityOld)) {
timeOfLastPeak = timeOfThisPeak;
timeOfNow = System.currentTimeMillis();
if (timeOfNow - timeOfLastPeak >= TimeInterval
&& (peakOfWave - valleyOfWave >= ThreadValue)) {
timeOfThisPeak = timeOfNow;
mStepListeners.countStep();
}
if (timeOfNow - timeOfLastPeak >= TimeInterval
&& (peakOfWave - valleyOfWave >= InitialValue)) {
timeOfThisPeak = timeOfNow;
ThreadValue = peakValleyThread(peakOfWave - valleyOfWave);
}
}
}
gravityOld = values;
}
/*
* 检测波峰
* 以下四个条件判断为波峰:
* 1.目前点为下降的趋势:isDirectionUp为false
* 2.之前的点为上升的趋势:lastStatus为true
* 3.到波峰为止,持续上升大于等于2次
* 4.波峰值大于20
* 记录波谷值
* 1.观察波形图,可以发现在出现步子的地方,波谷的下一个就是波峰,有比较明显的特征以及差值
* 2.所以要记录每次的波谷值,为了和下次的波峰做对比
* */
public boolean detectorPeak(float newValue, float oldValue) {
lastStatus = isDirectionUp;
if (newValue >= oldValue) {
isDirectionUp = true;
continueUpCount++;
} else {
continueUpFormerCount = continueUpCount;
continueUpCount = 0;
isDirectionUp = false;
}
if (!isDirectionUp && lastStatus
&& (continueUpFormerCount >= 2 || oldValue >= 20)) {
peakOfWave = oldValue;
return true;
} else if (!lastStatus && isDirectionUp) {
valleyOfWave = oldValue;
return false;
} else {
return false;
}
}
/*
* 阈值的计算
* 1.通过波峰波谷的差值计算阈值
* 2.记录4个值,存入tempValue[]数组中
* 3.在将数组传入函数averageValue中计算阈值
* */
public float peakValleyThread(float value) {
float tempThread = ThreadValue;
if (tempCount < ValueNum) {
tempValue[tempCount] = value;
tempCount++;
} else {
tempThread = averageValue(tempValue, ValueNum);
for (int i = 1; i < ValueNum; i++) {
tempValue[i - 1] = tempValue[i];
}
tempValue[ValueNum - 1] = value;
}
return tempThread;
}
/*
* 梯度化阈值
* 1.计算数组的均值
* 2.通过均值将阈值梯度化在一个范围里
* */
public float averageValue(float value[], int n) {
float ave = 0;
for (int i = 0; i < n; i++) {
ave += value[i];
}
ave = ave / ValueNum;
if (ave >= 8)
ave = (float) 4.3;
else if (ave >= 7 && ave < 8)
ave = (float) 3.3;
else if (ave >= 4 && ave < 7)
ave = (float) 2.3;
else if (ave >= 3 && ave < 4)
ave = (float) 2.0;
else {
ave = (float) 1.3;
}
return ave;
}
}
StepValuePassListener
package com.example.step;
public interface StepValuePassListener {
void stepChanged(int steps);
}
StepView
package com.example.step;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
/**
* 重新绘图的圆圈
*/
public class StepView extends View {
private static int mText;
private RectF mColorWheelRectangle = new RectF();// 圆圈的矩形范围
private Paint mDefaultWheelPaint;// 绘制底部灰色圆圈的画笔
private Paint mColorWheelPaint;// 绘制蓝色扇形的画笔
private Paint textPaint;// 中间文字的画笔
private Paint textPaint1;// 上下文字的画笔
private float mColorWheelRadius;// 圆圈普通状态下的半径
private float circleStrokeWidth;// 圆圈的线条粗细
private float pressExtraStrokeWidth;// 按下状态下增加的圆圈线条增加的粗细
// private int mText;// 中间文字内容
private int mCount;// 为了达到数字增加效果而添加的变量,他和mText其实代表一个意思
private float mProgressAni;// 为了达到蓝色扇形增加效果而添加的变量,他和mProgress其实代表一个意思
private float mProgress;// 扇形弧度
private int mTextSize;// 中间文字大小
private int mTextSize1;// 上下文字大小
private int mDistance;// 上下文字的距离
private int STEP;
private float flag;
private String AIM;
BarAnimation anim;// 动画类
public StepView(Context context) {
super(context);
init();
}
public StepView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StepView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
circleStrokeWidth = dip2px(getContext(), 20);// 圆圈的线条粗细
pressExtraStrokeWidth = dip2px(getContext(), 2);// 按下状态下增加的圆圈线条增加的粗细
mTextSize = dip2px(getContext(), 80);// 中间文字大小
mTextSize1 = dip2px(getContext(), 30);// 上下文字大小
mDistance = dip2px(getContext(), 70);//文字间的距离
// 绘制蓝色扇形的画笔
mColorWheelPaint = new Paint();
mColorWheelPaint.setAntiAlias(true);// 抗锯齿
mColorWheelPaint.setColor(0xFF29a6f6);// 设置颜色
mColorWheelPaint.setStyle(Paint.Style.STROKE);// 设置空心
mColorWheelPaint.setStrokeWidth(circleStrokeWidth);// 设置圆圈粗细
// 绘制底部灰色圆圈的画笔
mDefaultWheelPaint = new Paint();
mDefaultWheelPaint.setAntiAlias(true);
mDefaultWheelPaint.setColor(Color.parseColor("#d9d6c3"));
mDefaultWheelPaint.setStyle(Paint.Style.STROKE);
mDefaultWheelPaint.setStrokeWidth(circleStrokeWidth);
// 中间文字的画笔
textPaint = new Paint(Paint.LINEAR_TEXT_FLAG);
textPaint.setAntiAlias(true);
textPaint.setColor(Color.parseColor("#6DCAEC"));
textPaint.setStyle(Style.FILL_AND_STROKE);
textPaint.setTextAlign(Align.LEFT);
textPaint.setTextSize(mTextSize);
// 上下文字的画笔
textPaint1 = new Paint(Paint.LINEAR_TEXT_FLAG);
textPaint1.setAntiAlias(true);
textPaint1.setColor(Color.parseColor("#000000"));
textPaint1.setStyle(Style.FILL_AND_STROKE);
textPaint1.setTextAlign(Align.LEFT);
textPaint1.setTextSize(mTextSize1);
// 动画类
anim = new BarAnimation();
anim.setDuration(1000);
}
@SuppressLint("DrawAllocation")
@Override
//onDraw()方法来将自定义View绘制在布局中
protected void onDraw(Canvas canvas) {
int halfHeight = getHeight() / 2;
int halfWidth = getWidth() / 2;
int radius = halfHeight < halfWidth ? halfHeight : halfWidth;
// 圆圈的矩形范围 绘制底部灰色圆圈的画笔
canvas.drawCircle(halfWidth, halfHeight, radius - 20f,
mDefaultWheelPaint);
// mColorWheelRectangle是绘制蓝色扇形的画笔
mColorWheelRectangle.top = halfHeight - radius + 20f;
mColorWheelRectangle.bottom = halfHeight + radius - 20f;
mColorWheelRectangle.left = halfWidth - radius + 20f;
mColorWheelRectangle.right = halfWidth + radius - 20f;
// 根据mProgressAni(角度)画扇形
mProgressAni = flag;
canvas.drawArc(mColorWheelRectangle, 90, mProgressAni, false,
mColorWheelPaint);
Rect bounds = new Rect();
String middleText = null;// 中间的文字
String upText = null;// 上面文字
String downText = null;// 底部文字
upText = "步数";
downText = "目标:"+AIM;
middleText = String.valueOf(mText); //数字接口
// 中间文字的画笔
textPaint.getTextBounds(middleText, 0, middleText.length(), bounds);
// drawText各个属性的意思(文字,x坐标,y坐标,画笔)
canvas.drawText(middleText, (mColorWheelRectangle.centerX())
- (textPaint.measureText(middleText) / 2),
mColorWheelRectangle.centerY() + bounds.height() / 2, textPaint);
textPaint1.getTextBounds(upText, 0, upText.length(), bounds);
canvas.drawText(
upText,
(mColorWheelRectangle.centerX())
- (textPaint1.measureText(upText) / 2),
mColorWheelRectangle.centerY() + bounds.height() / 2
- mDistance, textPaint1);
textPaint1.getTextBounds(downText, 0, downText.length(), bounds);
canvas.drawText(downText, (mColorWheelRectangle.centerX())
- (textPaint1.measureText(downText) / 2),
mColorWheelRectangle.centerY() + bounds.height() / 2
+ mDistance, textPaint1);
}
// 进行测量出自定义控件的宽和高并且调用setMeasureDimension(width,height)方法,将宽高配置好
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = getDefaultSize(getSuggestedMinimumHeight(),
heightMeasureSpec);
int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int min = Math.min(width, height);
setMeasuredDimension(min, min);
mColorWheelRadius = min - circleStrokeWidth - pressExtraStrokeWidth;
// set方法的参数意思:left,top,right,bottom
mColorWheelRectangle.set(circleStrokeWidth + pressExtraStrokeWidth,
circleStrokeWidth + pressExtraStrokeWidth, mColorWheelRadius,
mColorWheelRadius);
}
// 对外的一个接口,用来开启动画
public void startCustomAnimation() {
this.startAnimation(anim);
}
// 中间的数值
public void setText(int text,float ProgressAni,String aim) {
mText = text;
flag = ProgressAni;
AIM = aim;
this.postInvalidate();// 可以用子线程更新视图的方法调用。view会执行onDraw()方法
//invalidate();
}
/**
* 继承animation的一个动画类
*
*/
public class BarAnimation extends Animation {
protected void applyTransformation(float interpolatedTime,
Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
mProgressAni = interpolatedTime * mProgress;
mCount = (int) (interpolatedTime * mText);
} else {
mProgressAni = mProgress;
mCount = mText;
}
postInvalidate();
}
}
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
}
UpdateUiCallBack
package com.example.step;
public interface UpdateUiCallBack {
/**
* 更新UI步数
*/
void updateUi(int stepCount);
}
WelcomeShow
package com.example.step;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
* 欢迎界面
*/
public class WelcomeShow extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome_show);
Button TRUE =(Button)findViewById(R.id.TRUE);
TRUE.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(WelcomeShow.this,MainActivity.class);
String str1=((EditText)findViewById(R.id.AIM)).getText().toString();
Bundle bundle=new Bundle();
bundle.putCharSequence("aim",str1);
intent.putExtras(bundle) ;
startActivity(intent);
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.step.StepView
android:id="@+id/shapeView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/busu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="33dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="37dp"
android:layout_below="@+id/shapeView"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="104dp"
android:background="#FFFFFF"
android:text="@string/butt1" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WelcomeShow">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="369dp"
android:orientation="horizontal">
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="371dp"
android:layout_toStartOf="@+id/AIM"
android:layout_toLeftOf="@+id/AIM"
android:padding="10dp"
android:text="@string/TE"
android:textSize="20dp" />
<EditText
android:id="@+id/AIM"
android:layout_width="136dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="52dp"
android:layout_marginRight="52dp"
android:layout_marginBottom="376dp"
android:hint=" "
android:inputType="number"
android:padding="10dp" />
<Button
android:id="@+id/TRUE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginEnd="141dp"
android:layout_marginRight="141dp"
android:layout_marginBottom="141dp"
android:text="@string/TRUE" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StepView">
</androidx.constraintlayout.widget.ConstraintLayout>
目录结构:
运行结果:
本文地址:https://blog.csdn.net/qq_42018521/article/details/107180214
上一篇: 比干的后代姓什么?历史上最有名的“林”姓名人是谁?
下一篇: Untitled2