首页 > 其他分享 >自定义View-- wifi强度

自定义View-- wifi强度

时间:2024-08-10 13:26:01浏览次数:14  
标签:自定义 -- wifi private paint int import android

自定义View和自定义属性的基本步骤:自定义View:

1.创建一个自定义View类:首先,你需要创建一个继承自View或其子类(如ImageView、Button等)的Java类。这个类将代表你的自定义View,并负责绘制和处理用户交互。

2.重写onDraw方法:在自定义View类中,你通常会重写onDraw方法来定义如何绘制你的View。在onDraw方法中,你可以使用Canvas对象进行绘制,绘制各种形状、文本、图像等。

3.处理用户交互:如果需要处理用户交互,你可以重写相应的方法,如onTouchEvent,以响应触摸事件。

项目中有遇到自定义wifi。

直接上代码

kotlin:

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.net.wifi.WifiManager
import android.util.AttributeSet
import android.view.View
import kotlin.math.min
import kotlin.math.sqrt


class WiFiStateView @JvmOverloads constructor(
    context: Context?,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    View(context, attrs, defStyleAttr) {
    private var wifi_state = 1

    private var height = 0
    private var width = 0

    private var paint: Paint? = null

    private var startAngle = 0
    private var sweepAngle = 0

    private var wifiHeight = 0

    private var padding_bottom = 0

    private var bottom_x = 0
    private var bottom_y = 0

    enum class Style {
        RECT, ROUND
    }

    private var style = Style.ROUND

    init {
        init()
    }

    private fun init() {
        paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint!!.color = Color.BLACK
        paint!!.isAntiAlias = true
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //获取宽的测量模式
        val heightSize = MeasureSpec.getSize(heightMeasureSpec) //测量值
        height = resolveSize(heightSize, heightMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec) //测量值
        width = resolveSize(widthSize, widthMeasureSpec)

        val calc_wifi_height = (width / (sqrt(2.0))).toInt()
        wifiHeight = min(calc_wifi_height.toDouble(), height.toDouble()).toInt()
        padding_bottom = (height - wifiHeight) / 2
        bottom_x = width / 2
        bottom_y = height - padding_bottom

        setMeasuredDimension(width, height)
    }

    fun setWifi_state(level: Int) {
        this.wifi_state = WifiManager.calculateSignalLevel(level, 5)
        postInvalidate()
    }

    fun setStyle(style: Style) {
        this.style = style
        postInvalidate()
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val signalRadius = wifiHeight / 4
        val paint_width = signalRadius / 2
        paint!!.strokeWidth = paint_width.toFloat()
        if (style == Style.RECT) {
            paint!!.strokeCap = Paint.Cap.BUTT
            startAngle = -135
            sweepAngle = 90
        } else {
            paint!!.strokeCap = Paint.Cap.ROUND
            startAngle = -130
            sweepAngle = 80
        }
        for (i in 1..4) {
            val radius = (signalRadius * i).toFloat()
            if (i <= wifi_state) {
                paint!!.color = Color.parseColor("#4b4b4b")
            } else {
                paint!!.color = Color.parseColor("#c9c9c9")
            }
            var rectf: RectF
            if (i == 1) {
                paint!!.style = Paint.Style.FILL
                if (style == Style.RECT) {
                    rectf = RectF(
                        bottom_x - radius,
                        bottom_y - radius,
                        bottom_x + radius,
                        bottom_y + radius
                    )
                    canvas.drawArc(
                        rectf, startAngle.toFloat(), sweepAngle.toFloat(), true,
                        paint!!
                    )
                } else {
                    canvas.drawCircle(
                        bottom_x.toFloat(),
                        (bottom_y - paint_width).toFloat(),
                        paint_width.toFloat(),
                        paint!!
                    )
                }
            } else {
                paint!!.style = Paint.Style.STROKE
                rectf = RectF(
                    bottom_x - radius + paint_width / 2,
                    bottom_y - radius + paint_width / 2,
                    bottom_x + radius - paint_width / 2,
                    bottom_y + radius - paint_width / 2
                )
                canvas.drawArc(rectf, startAngle.toFloat(), sweepAngle.toFloat(), false, paint!!)
            }
        }
    }
}

 java:

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.net.wifi.WifiManager;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;


public class WiFiStateView extends View {

    private int wifi_state = 1;

    private int height,width;

    private Paint paint;

    private int startAngle,sweepAngle;

    private int wifiHeight = 0;

    private int padding_bottom ;

    private int bottom_x,bottom_y;

    enum Style{
        RECT,ROUND
    }
    private Style style = Style.ROUND;

    public WiFiStateView(Context context) {
        this(context,null);
    }

    public WiFiStateView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public WiFiStateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取宽的测量模式
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);//测量值
        height = resolveSize(heightSize, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);//测量值
        width = resolveSize(widthSize, widthMeasureSpec);

        int calc_wifi_height = (int) (width / (Math.sqrt(2)));
        wifiHeight = Math.min(calc_wifi_height,height);
        padding_bottom = (height - wifiHeight)/2;
        bottom_x = width /2;
        bottom_y = height - padding_bottom;

        setMeasuredDimension(width, height);
    }

    public void setWifi_state(int level) {
        this.wifi_state = WifiManager.calculateSignalLevel(level,5);
        postInvalidate();
    }

    public void setStyle(Style style) {
        this.style = style;
        postInvalidate();
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int signalRadius = wifiHeight / 4;
        int paint_width = signalRadius/2;
        paint.setStrokeWidth(paint_width);
        if(style == Style.RECT){
            paint.setStrokeCap(Paint.Cap.BUTT);
            startAngle = -135;
            sweepAngle = 90;
        }else {
            paint.setStrokeCap(Paint.Cap.ROUND);
            startAngle = -130;
            sweepAngle = 80;
        }
        for(int i = 1;i <= 4; i ++){
            float radius = signalRadius * i;
            if(i<=wifi_state){
                paint.setColor(Color.parseColor("#4b4b4b"));
            }else {
                paint.setColor(Color.parseColor("#c9c9c9"));
            }
            RectF rectf;
            if(i == 1){
                paint.setStyle(Paint.Style.FILL);
                if(style == Style.RECT){
                    rectf = new RectF(bottom_x - radius  ,bottom_y - radius,bottom_x + radius,bottom_y + radius);
                    canvas.drawArc(rectf,startAngle,sweepAngle,true , paint);
                }else {
                    canvas.drawCircle(bottom_x,bottom_y -paint_width,paint_width,paint );
                }

            }else {
                paint.setStyle(Paint.Style.STROKE);
                rectf = new RectF(bottom_x - radius + paint_width/2,bottom_y - radius + paint_width/2,bottom_x + radius -  paint_width/2,bottom_y + radius -  paint_width/2);
                canvas.drawArc(rectf,startAngle,sweepAngle,false , paint);
            }
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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">

    <wendu.dsbridge.DWebView
        android:id="@+id/dwebview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <Button
        android:layout_gravity="bottom"
        android:id="@+id/btn_sendJS"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这是原生控件,发送数据给JS"/>

    <com.example.dsbridge_demo.WiFiStateView
        android:layout_width="25dp"
        android:layout_height="25dp"

        />

</FrameLayout>

===============

这里涉及到 Android 自定义view 自定义属性

自定义属性:

1.定义自定义属性:在res/values/attrs.xml文件中定义自定义属性。这是一个XML文件,你可以在其中指定自定义属性的名称、类型、默认值等。例如:

<resources>
    <declare-styleable name="MyCustomView">
        <attr name="customText" format="string" />
        <attr name="customColor" format="color" />
    </declare-styleable>
</resources>

2.在XML布局文件中使用自定义属性:在XML布局文件中,可以使用你定义的自定义属性来配置自定义View。例如:

<com.example.myapp.MyCustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:customText="Hello, Custom View!"
    app:customColor="#FF0000" />

3.在自定义View中获取自定义属性:在自定义View类中,可以通过obtainStyledAttributes方法获取自定义属性的值,并在View的初始化中使用这些值。例如:

TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
String customText = attributes.getString(R.styleable.MyCustomView_customText);
int customColor = attributes.getColor(R.styleable.MyCustomView_customColor, Color.BLACK);
attributes.recycle();

// 使用获取到的属性值进行初始化

这样,你就可以通过自定义属性来配置你的自定义View,并在XML布局文件中以可视化方式使用它。这使得你的自定义View更加灵活和易于重用。

标签:自定义,--,wifi,private,paint,int,import,android
From: https://blog.csdn.net/wulong756273/article/details/141037730

相关文章

  • trie算法
    1、定义高效的存储和查找字符串集合的数据结构它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高2、构建我们可以使用数组来模拟实现Trie树。我们设计一个二维数组son[N][26]来模拟整个树的结构,而cnt[N]来记录单词个......
  • R语言用户自定义函数的语法结构、编写自定义统计值计算函数(使用ifelse结构计算均值和
    R语言用户自定义函数的语法结构、编写自定义统计值计算函数(使用ifelse结构计算均值和标准差等)、编写自定义日期格式化(format)函数(switch函数使用不同分枝格式化日期数据)、应用自定函数目录R语言用户自定义函数的语法结构、编写自定义统计值计算函数(使用ifelse结构计算均值和......
  • R语言生存分析:生存分析(survival analysis)与生存资料有关的概念详解
     R语言生存分析:生存分析(survivalanalysis)与生存资料有关的概念详解目录R语言生存分析(survivalanalysis)与生存资料有关的概念详解#生存分析#生存资料特点#终点事件#生存时间#截尾的主要原因#生存分析研究的内容#生存分析概念大全 #生存分析对一个或多个非负......
  • C++day05
    1>思维导图2>搭建一个货币的场景,创建一个名为RMB的类,该类具有整型私有成员变量yuan(元)、jiao(角)和fen(分),并且具有以下功能:(1)重载算术运算符+和-,使得可以对两个RMB对象进行加法和减法运算,并返回一个新的RMB对象作为结果。(2)重载关系运算符>,判断一个RMB对象是......
  • C++day04
    1】思维导图2】完成关系运算符重载,实现成员函数和全局函数的版本。#include<iostream>usingnamespacestd;classStu{friendbooloperator<(constStu&L,constStu&R);private:intage;intid;public:Stu(){}Stu(intage,intid):age(age)......
  • C++day03
    1>思维导图2>设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数和拷贝构造函数。#include<iostream>usingnamespacestd;classPer{private:stringname;......
  • 基于SpringBoot+Vue的互联网违法行为举报平台设计和实现(源码+论文+部署讲解等)
    博主介绍:✌全网粉丝50W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P......
  • Ai小说推文工具,Ai漫画工具AIGC阿祖绘唐3
    AIGC阿祖绘唐3是一款Ai小说推文工具和Ai漫画工具,它由Ai技术驱动,旨在帮助用户创作优质的小说和漫画作品。【绘唐3下载】小说推文批量Ai生成工具https://qvfbz6lhqnd.feishu.cn/wiki/D3YLwmIzmivZ7BkDij6coVcbn7W该工具具有智能创作功能,可以根据用户输入的关键词和情节要求,自......
  • 如果忘了Linux密码如何重置?
    忘记密码是我们常会遇到的情况之一,无论是在操作系统、网站账户、手机、电子邮件还是其他渠道上。忘记密码是我们常会遇到的情况之一,无论是在操作系统、网站账户、手机、电子邮件还是其他渠道上。有时候如果密码需要符合特定的复杂性要求,例如包含大写字母、小写字母、数字和特......
  • 谷歌终于赢了OpenAI一回:实验版本Gemini 1.5 Pro超越GPT-4o
    近两日,谷歌在不断发布最新研究。继昨日放出最强端侧Gemma22B小模型后,刚刚,Gemini1.5Pro实验版本(0801)已经推出。用户可以通过GoogleAIStudio和GeminiAPI进行测试和反馈。既然免费,那我们帮大家测试一下最近比较火的比大小问题。当我们问Gemini1.5Pro(0801......