- 任务描述
这里介绍的水平仪就是那种比较传统的水平仪,在一个透明的圆盘中充满某种液体,液体中留有一个气泡,当一端翘起时,该气泡将会浮向翘起的一端。
该程序用了一个自定义View,该自定义View很简单,就是绘制透明圆盘和气泡——其中气泡的位置会动态改变。
在真机中测试该程序,可看到下图展示的结果:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity">
<com.keven.android.waterlevel.WaterLevel
android:id="@+id/WaterLevelView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
WaterLevel.java
package com.keven.android.waterlevel;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import androidx.annotation.Nullable;
public class WaterLevel extends View {
public Bitmap back;
public Bitmap bubble;
private WindowManager windowsMannager;
private Paint paint;
public int bubbleX = 0;
public int bubbleY = 0;
public WaterLevel(Context context) {
this(context, null);
}
public WaterLevel(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public WaterLevel(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Settings(context);
initView();
}
private void initView() {
Display windowDisplay = windowsMannager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
windowDisplay.getMetrics(metrics);
int ScreenWidth = metrics.widthPixels;
back = Bitmap.createBitmap(ScreenWidth, ScreenWidth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(back);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
LinearGradient linearGradient = new LinearGradient(0f, ScreenWidth, ScreenWidth * 0.8f, ScreenWidth * 0.2f, Color.YELLOW, Color.WHITE, Shader.TileMode.MIRROR);
// 设置渐变笔刷
paint.setShader(linearGradient);
// 绘制圆形
canvas.drawCircle(ScreenWidth / 2, ScreenWidth / 2, ScreenWidth / 2, paint);
Paint paint1 = new Paint();
paint1.setAntiAlias(true);
paint1.setStrokeWidth(5F);
paint1.setColor(Color.BLACK);
// 绘制边框
canvas.drawCircle(ScreenWidth / 2, ScreenWidth / 2, ScreenWidth / 2, paint1);
//绘制 水平线
canvas.drawLine(0f, ScreenWidth / 2, ScreenWidth, ScreenWidth / 2, paint1);
//绘制垂直线
canvas.drawLine(ScreenWidth / 2, 0f, ScreenWidth / 2, ScreenWidth, paint1);
paint1.setStrokeWidth(10f);
paint1.setColor(Color.RED);
// canvas.drawLine(ScreenWidth/2 - 30 , ScreenWidth/ 2 , ScreenWidth/2+30 , ScreenWidth /2 , paint1 );
// canvas.drawLine(ScreenWidth/2 , ScreenWidth/ 2- 30 , ScreenWidth/2 , ScreenWidth /2 +30 , paint1 );
canvas.drawLine(ScreenWidth / 2, 0, ScreenWidth / 2, ScreenWidth, paint1);
canvas.drawLine(0, ScreenWidth / 2, ScreenWidth, ScreenWidth / 2, paint1);
bubble = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
}
private void Settings(Context context) {
windowsMannager = (WindowManager) context.getSystemService(
Context.WINDOW_SERVICE
);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制表
canvas.drawBitmap(back, 0, 0, paint);
canvas.drawBitmap(bubble, bubbleX, bubbleY, paint);
}
}
MainActivity.java
package com.keven.android.waterlevel;
import androidx.appcompat.app.AppCompatActivity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager sensorMannager;
private WaterLevel waterLevelView;
private int MAX_Angle = 30;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
initEvent();
}
private void initData() {
sensorMannager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMannager.registerListener(this, sensorMannager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
}
private void initView() {
waterLevelView = findViewById(R.id.WaterLevelView);
}
private void initEvent() {
}
// 注册床传感器回调
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
float[] values = sensorEvent.values;
int type = sensorEvent.sensor.getType();
switch (type) {
case Sensor.TYPE_ORIENTATION:
float yAngle = values[1];
float zAngle = values[2];
int x = (waterLevelView.back.getWidth() - waterLevelView.bubble.getWidth()) / 2;
int y = (waterLevelView.back.getHeight() - waterLevelView.bubble.getHeight()) / 2;
if (Math.abs(zAngle) <= MAX_Angle) {
int deltax = (int) ((waterLevelView.back.getWidth() - waterLevelView.bubble.getWidth()) / 2 * zAngle / MAX_Angle);
x += deltax;
} else if (zAngle > MAX_Angle) {
x = 0;
} else {
x = waterLevelView.back.getWidth() - waterLevelView.bubble.getWidth();
}
if (Math.abs(yAngle) < MAX_Angle) {
int deltay = (int) ((waterLevelView.back.getHeight() - waterLevelView.bubble.getHeight()) / 2 * yAngle / MAX_Angle);
y += deltay;
} else if (yAngle > MAX_Angle) {
y = waterLevelView.back.getHeight() - waterLevelView.bubble.getHeight();
} else {
y = 0;
}
if (isContaint(x, y)) {
waterLevelView.bubbleX = x;
waterLevelView.bubbleY = y;
waterLevelView.postInvalidate();
break;
}
}
}
private boolean isContaint(int x, int y) {
int Cy = y + waterLevelView.bubble.getHeight() / 2;
int Cx = x + waterLevelView.bubble.getWidth() / 2;
int Bcy = waterLevelView.back.getHeight() / 2;
int Bcx = waterLevelView.back.getWidth() / 2;
double distance = Math.sqrt((Cx - Bcx) * (Cy - Bcy) + (Cy - Bcy) * (Cx - Bcx));
return distance < (waterLevelView.back.getWidth() - waterLevelView.bubble.getWidth()) / 2;
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
标签:水平仪,H2,paint1,waterLevelView,int,import,Android,ScreenWidth,android
From: https://blog.csdn.net/2401_83566316/article/details/142823985