自定义View-- wifi强度

自定义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更加灵活和易于重用。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值