首页 > 其他分享 >Android:H2-20:水平仪

Android:H2-20:水平仪

时间:2024-10-10 15:48:30浏览次数:3  
标签:水平仪 H2 paint1 waterLevelView int import Android ScreenWidth android

  1. 任务描述

这里介绍的水平仪就是那种比较传统的水平仪,在一个透明的圆盘中充满某种液体,液体中留有一个气泡,当一端翘起时,该气泡将会浮向翘起的一端。

该程序用了一个自定义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

相关文章

  • Android14 如何更改无源码应用图标
    没有源码的Android应用一般就是在解析该APK时就要替换图标,如果只在Launcher替换,那么Settings中很多地方都要进行适配,修改比较麻烦,现在提供一种在源头就替换的涉及修改的文件frameworks/base/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java......
  • Android TextView跑马灯效果
    对于很多时候会有显示不全的问题,也就是会以省略号的形式显示,对于可以有焦点的Textview可以很好实现跑马灯效果,但是无焦点的TextView就不好操作,下面我来解决这个问题。1,对于能获取到焦点的只需在布局里面加上如下属性:android:ellipsize="marquee"//文字显示不完全,以什么方式......
  • Android反编译APK与解析软件包img
    1,Jadx反编译APK下载JadxJADX相当于是apktool+dex2jar+jd-gui的结合体,既能反编译代码也能反编译资源支持的文件有:(apk,dex,jar,class,smali,zip,xapk,aar,arsc,jadx,aab)等。打开之后界面如下,点击打开文件,再选择对应所需要反编译的apk(或者直接拖入apk)等......
  • Android 笔记
    1,常用adb命令查看前台显示的Activity:adbshell"dumpsysactivity|grepmFocus" adbshelldumpsyswindow|findstrmCurrentFocus获取手机的分辨率:adbshellwmsize屏幕密度:adbshellwmdensity飞行模式开/关:adbshellsettingsputglobala......
  • 第3天:Android应用组件
    第3天:Android应用组件(Kotlin版本)欢迎来到第3天的Android编程教程!今天我们将深入了解Android应用的四大组件,以及如何管理Activity的生命周期。我们将使用Kotlin来实现示例代码,并学习如何使用Logcat来调试和观察日志。本章节学习内容代码链接:链接:Android应用组件课程目标......
  • 第2天:熟悉Android Studio补充材料——`MainActivity.kt`解读
    下面是对“第2天:熟悉AndroidStudio”该文学习的更深层次的补充材料,对MainActivity.kt文件的理解。下面对MainActivity.kt文件中每一行进行详细解释:packagecom.example.helloworldappimportandroid.os.Bundleimportandroidx.activity.enableEdgeToEdgeimporta......
  • Python基于uniapp+Android平台的校园论坛交流系统 微信小程序z0c7d
    目录项目介绍具体实现截图开发者工具介绍技术路线解决的思路性能/安全/负载方面开发语言以及框架介绍数据库设计python-flask核心代码部分展示python-django核心代码部分展示详细视频演示源码获取项目介绍校园论坛系统设计的目的是为用户提供失物招领、二手闲置、跑......
  • Android Studio启动项目下载gradle失败的问题
    解决AndroidStudio项目初始化下载gradle过慢问题解决方法将谷歌官方源替换为国内阿里云或者腾讯云源解决方案替换掉谷歌原地址:官网地址:https://services.gradle.org/distributions/阿里云镜像Gradle下载地址:https://mirrors.aliyun.com/macports/distfiles/gradle/腾讯......
  • 【含文档】基于Springboot+Android的公交系统查询与设计(含源码+数据库+lw)
    1.开发环境开发系统:Windows10/11架构模式:MVC/前后端分离JDK版本:JavaJDK1.8开发工具:IDEA数据库版本:mysql5.7或8.0数据库可视化工具:navicat服务器:SpringBoot自带apachetomcat主要技术:Java,Springboot,mybatis,mysql,vue2.视频演示地址3.功能该系统......
  • 【Spring Security OAuth2】- 【使用Spring MVC开发RESTful API】 异步处理rest服务
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......