*/
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec); //获取具体的测量模式(EXACTLY,AT_MOST,UNSPECIFIED)
int specSize = MeasureSpec.getSize(measureSpec); //获取具体的测量大小
if (specMode == MeasureSpec.EXACTLY) { //默认模式
result = measureSpec;
} else {
result = 400; //给一个默认的大小
if (specMode == MeasureSpec.AT_MOST) { //如果是wrap_content
result = Math.min(result, specSize); //取最小的 适合控件大小的
}
}
return result;
}
/*
-
这个是系统回调方法,是系统调用的,它的方法名已经告诉我们了,这个方法会在这个view的大小发生改变是被系统调用,
-
我们要记住的就是view
-
大小变化,这个方法就被执行就可以了。最主要的是,它还在onDraw方法之前调用。
-
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = getWidth();
mHeight = getHeight();
//扇形外围的矩形
/*
首先需要一个矩形来包裹这个扇形,其次每隔一定的事件,扇形需要旋转(这个可以用重新绘制,然后让扇形的角度+1).
矩形的4边必须是相等的,其次中心必须在圆形的中心,这样一来,
矩形的4条边就很好决定了,矩形左侧的X坐标:mWidth * 0.1,矩形顶部的Y坐标:mWidth * 0.1,
矩形右侧的X坐标:mWidth * 0.9,
矩形底部的Y坐标:mWidth * 0.9
-
参数:left float:矩形左侧的X坐标 top float:矩形顶部的Y坐标
-
right float:矩形右侧的X坐标 bottom float:矩形底部的Y坐标
-
*/
mRectF = new RectF((float) (mWidth * 0.1), (float) (mWidth * 0.1),
(float) (mWidth * 0.9), (float) (mWidth * 0.9));
// 绘制渐变效果
LinearGradient gradient = new LinearGradient((float) (mWidth * 0.3),
(float) (mWidth * 0.9), (float) (mWidth * 0.1),
(float) (mWidth * 0.5),
new int[]{Color.parseColor(“#B1D6FD”), Color.TRANSPARENT},
null, Shader.TileMode.CLAMP);
mArcPaint.setShader(gradient);
// 2个圆的半径
radiusExt = (float) (mWidth * 0.4);
radiusInside = (float) (mWidth * 0.25);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvasArc(canvas); //话扇形
canvasArc2(canvas); //画扇形 引导
canvasLines(canvas); //画线
canvasCircle(canvas); //画圆
canvasSche(canvas); //画进度
canvasPercent(canvas); //画 %
}
/**
-
画 % 符号
-
@param canvas
*/
private void canvasPercent(Canvas canvas) {
//符号的X
float perSignX = mTextX + mTextWidth + 5;
//符号的Y
float perSignY = getHeight() / 2 + 20;
//画字
canvas.drawText(“%”, perSignX, perSignY, mPercentSignPaint);
}
/**
-
画文字 进度
-
@param canvas
*/
private void canvasSche(Canvas canvas) {
String text = String.valueOf(schedule);
//拿到字符串的宽度
mTextWidth = mTextPaint.measureText(text);
//文字的x轴坐标
mTextX = (getWidth() - mTextWidth) / 2;
//文字的y轴坐标
//描述给定文本大小的字体的各种指标的类。
// 记住,Y值增加下降,所以这些值将是正的,测量距离上升的值将为负。 这个类由getFontMetrics()返回。
Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
mTextY = getHeight() / 2 + (Math.abs(fontMetrics.ascent) - fontMetrics.descent) / 2;
//画字
canvas.drawText(text, mTextX, mTextY, mTextPaint);
}
/**
-
绘制2根线
-
@param canvas
*/
private void canvasLines(Canvas canvas) {
//横线
canvas.drawLine((float) (mWidth * 0.1), (float) (mHeight * 0.5),
(float) (mWidth * 0.9), (float) (mHeight * 0.5), mLinePaint);
//竖线
canvas.drawLine((float) (mWidth * 0.5), (float) (mHeight * 0.1),
(float) (mWidth * 0.5), (float) (mHeight * 0.9), mLinePaint);
}
/**
-
绘制旋转的扇形
-
@param canvas
*/
private void canvasArc(Canvas canvas) {
canvas.drawArc(mRectF, startAngle, 100, true, mArcPaint);
}
/**
-
绘制旋转的扇形
-
@param canvas
*/
private void canvasArc2(Canvas canvas) {
//第二个的扇形的角度是1,为什么是1呢,原来我这里只是想要它旋转角度的效果,并不需要它有多宽,
// 所以在具体实现自定义View的时候,也要学会活学活用。
canvas.drawArc(mRectF, startAngle, 2, true, mArcPaint2);
}
/**
-
绘制四个圆
-
@param canvas
*/
private void canvasCircle(Canvas canvas) {
canvas.drawCircle(mWidth / 2, mHeight / 2, radiusInside, mCirclePaint);
canvas.drawCircle(mWidth / 2, mHeight / 2, radiusExt, mCirclePaint);
}
/**
- 开始扫描 动画
*/
public void startScanning() {
//运行状态改为true
running = true;
//开一个子线程
mThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(mScanSpeed);
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果正在执行动画,则发送消息,叫UI线程更新UI
if (running) {
mHandler.sendEmptyMessage(UPDATE_UI);
} else {
break;
}
}
}
});
mThread.start();
}
/**
- 重新开启动画
*/
public void restartScan() {
running = true;
}
/**
- 暂停动画
*/
public void stopScan() {
running = false;
}
/**
-
是否在转动
-
@return
*/
public boolean isRunning() {
return running;
}
/**
-
获取当前进度
-
@return 当前进度
*/
public int getSchedule() {
return schedule;
}
/**
-
设置进度
-
@param schedule 进度
*/
public void setSchedule(int schedule) {
if (schedule >= 0 && schedule <= 100) {
this.schedule = schedule;
this.postInvalidate(); //非UI线程更新UI
}
}
/**
-
设置扫描速度 1000~20 数字越小扫描速度越快
-
@param mScanSpeed 速度 1000~20
*/
public void setmScanSpeed(int mScanSpeed) {
//检查参数
if (mScanSpeed < 20 || mScanSpeed > 1000) {
mScanSpeed = 50; //设置为速度默认值
} else {
this.mScanSpeed = mScanSpeed;
}
}
/**
-
获取当前扫描速度
-
@return
*/
public int getmScanSpeed() {
return mScanSpeed;
}
}
然后在布局中的使用 activity_antivirusi.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”
tools:context=“com.xfhy.mobilesafe.activity.AntivirusiActivity”>
<TextView
style=“@style/TitleTheme”
android:text=“病毒查杀”/>
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“0dp”
android:layout_weight=“2”
android:orientation=“vertical”>
<com.xfhy.mobilesafe.view.VirusKilling
android:id=“@+id/vk_scan_virus”
android:layout_width=“200dp”
android:layout_height=“200dp”
android:layout_gravity=“center_horizontal”
/>
<TextView
android:id=“@+id/tv_scan_app_package”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center_horizontal”
android:text=“正在扫描:com.xfhy.hehe”
android:textColor=“@color/bright_foreground_light_disabled”
android:textSize=“18sp”/>
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“0dp”
android:layout_weight=“2”
android:orientation=“vertical”
android:paddingBottom=“10dp”
android:paddingEnd=“20dp”
android:paddingStart=“20dp”
android:paddingTop=“10dp”>
<RelativeLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_weight=“1”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentStart=“true”
android:gravity=“center_vertical”
android:text=“病毒”
android:textColor=“@color/colorBlack”
android:textSize=“22sp”
/>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentEnd=“true”
android:gravity=“center_vertical”
android:text=“正在扫描…”
android:textColor=“@color/bright_foreground_light_disabled”
android:textSize=“18sp”
/>
<RelativeLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_weight=“1”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentStart=“true”
android:gravity=“center_vertical”
android:text=“风险软件”
android:textColor=“@color/colorBlack”
android:textSize=“22sp”
/>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentEnd=“true”
android:gravity=“center_vertical”
android:text=“正在扫描…”
android:textColor=“@color/bright_foreground_light_disabled”
android:textSize=“18sp”
/>
<RelativeLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_weight=“1”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentStart=“true”
android:gravity=“center_vertical”
android:text=“非官方证书”
android:textColor=“@color/colorBlack”
android:textSize=“22sp”
/>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentEnd=“true”
android:gravity=“center_vertical”
android:text=“正在扫描…”
android:textColor=“@color/bright_foreground_light_disabled”
android:textSize=“18sp”
/>
<RelativeLayout
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_weight=“1”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentStart=“true”
android:gravity=“center_vertical”
android:text=“云查杀”
android:textColor=“@color/colorBlack”
android:textSize=“22sp”
/>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_alignParentEnd=“true”
android:gravity=“center_vertical”
android:text=“正在扫描…”
android:textColor=“@color/bright_foreground_light_disabled”
android:textSize=“18sp”
/>
<Button
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_margin=“20dp”
android:background=“@drawable/selector_button_scan_bg”
android:text=“停止扫描”
android:textColor=“#017EFF”
android:textSize=“20sp”/>
最后在Activity中的使用 AntivirusiActivity.java
最后
针对于上面的问题,我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
ndroid:gravity=“center_vertical”
android:text=“正在扫描…”
android:textColor=“@color/bright_foreground_light_disabled”
android:textSize=“18sp”
/>
<Button
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:layout_margin=“20dp”
android:background=“@drawable/selector_button_scan_bg”
android:text=“停止扫描”
android:textColor=“#017EFF”
android:textSize=“20sp”/>
最后在Activity中的使用 AntivirusiActivity.java
最后
针对于上面的问题,我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
[外链图片转存中…(img-xNrBolsy-1720121833424)]