自定义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.sqrtclass WiFiStateView @JvmOverloads constructor(context: Context?,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) :View(context, attrs, defStyleAttr) {private var wifi_state = 1private var height = 0private var width = 0private var paint: Paint? = nullprivate var startAngle = 0private var sweepAngle = 0private var wifiHeight = 0private var padding_bottom = 0private var bottom_x = 0private var bottom_y = 0enum class Style {RECT, ROUND}private var style = Style.ROUNDinit {init()}private fun init() {paint = Paint(Paint.ANTI_ALIAS_FLAG)paint!!.color = Color.BLACKpaint!!.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) / 2bottom_x = width / 2bottom_y = height - padding_bottomsetMeasuredDimension(width, height)}fun setWifi_state(level: Int) {this.wifi_state = WifiManager.calculateSignalLevel(level, 5)postInvalidate()}fun setStyle(style: Style) {this.style = stylepostInvalidate()}@SuppressLint("DrawAllocation")override fun onDraw(canvas: Canvas) {super.onDraw(canvas)val signalRadius = wifiHeight / 4val paint_width = signalRadius / 2paint!!.strokeWidth = paint_width.toFloat()if (style == Style.RECT) {paint!!.strokeCap = Paint.Cap.BUTTstartAngle = -135sweepAngle = 90} else {paint!!.strokeCap = Paint.Cap.ROUNDstartAngle = -130sweepAngle = 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: RectFif (i == 1) {paint!!.style = Paint.Style.FILLif (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.STROKErectf = 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);}@Overrideprotected 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")@Overrideprotected 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.DWebViewandroid:id="@+id/dwebview"android:layout_width="match_parent"android:layout_height="match_parent"/><Buttonandroid: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.WiFiStateViewandroid: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.MyCustomViewandroid: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更加灵活和易于重用。