先上效果图。

转盘绘制

通过观察,我们看到转盘主要由圆和扇形组成,如下图

我们只需按照我们需要的数量画出扇形即可。

  • 第一步:画大圆

    private fun drawLargeCircle(canvas: Canvas?) {val centerX = measuredWidth / 2Fval centerY = measuredHeight / 2Fval radius = measuredWidth / 2FmPaint.color = bgColorcanvas?.drawCircle(centerX, centerY, radius - 10, mPaint)mPaint.color = centerStrokeColormPaint.style = Paint.Style.STROKEfor (i in 0 until 10) {mPaint.alpha = 5 * (i + 1)canvas?.drawCircle(centerX, centerY, radius - i, mPaint)}}
    
  • 第二步:画扇形(小圆只是为了确定扇形圆心的位置,并不用真正画出来)

    private fun drawSector(canvas: Canvas?) {val sectorRadius = (measuredWidth / 2) * sectorProportionval sectorCenterRadius = (measuredWidth / 2) * 0.07fval centerX = measuredWidth / 2Fval centerY = measuredHeight / 2FmPaint.color = sectorColormPaint.style = Paint.Style.FILLvar angle = 360F / selectList.sizefor (i in 0 until selectList.size) {if ((i + 2) % selectList.size == selectedIndex) {mPaint.color = startColor} else {mPaint.color = sectorColor}val cx = centerX + cos(angleToRadian(angle * i)).toFloat() * sectorCenterRadiusval cy = centerY + sin(angleToRadian(angle * i)).toFloat() * sectorCenterRadiusval oval = RectF(cx - sectorRadius, cy - sectorRadius, cx + sectorRadius, cy + sectorRadius)canvas?.drawArc(oval, (angle * i) - (angle / 2), angle, true, mPaint)}mPaint.color = sectorColormPaint.alpha = 50val littleCircleCount = selectList.size * 2angle = 360F / littleCircleCountfor (i in 0 until littleCircleCount) {val littleCenterX = centerX + cos(angleToRadian(angle * i)).toFloat() * (((measuredWidth / 2) + sectorRadius + sectorCenterRadius) / 2F - 5)val littleCenterY = centerY + sin(angleToRadian(angle * i)).toFloat() * (((measuredWidth / 2) + sectorRadius + sectorCenterRadius) / 2F - 5)canvas?.drawCircle(littleCenterX, littleCenterY, (measuredWidth / 2) * littleCircleProportion, mPaint)}
    
  • 第三步:绘制其他元素

    private fun drawCenter(canvas: Canvas?) {val centerX = measuredWidth / 2Fval centerY = measuredHeight / 2FmPaint.color = bgColormPaint.alpha = 255canvas?.drawCircle(centerX, centerY, (measuredWidth / 2) * centerProportion, mPaint)mPaint.style = Paint.Style.STROKEmPaint.color = centerStrokeColormPaint.strokeWidth = 1Ffor (i in 0..(centerX * centerDistanceProportion).toInt()) {mPaint.alpha = 5 * icanvas?.drawCircle(centerX, centerY, centerX * centerProportion - i, mPaint)}mPaint.color = bgColormPaint.style = Paint.Style.FILLcanvas?.drawCircle(centerX, centerY, (centerX * centerProportion) -  (centerX * centerDistanceProportion), mPaint)mPaint.color = centerBottomColorcanvas?.drawCircle(centerX, centerY, (centerX * centerProportion) -  ((centerX * centerDistanceProportion) * 1.5F), mPaint)if (isClickable) {mPaint.color = startColor} else {mPaint.color = bgColor}canvas?.drawCircle(centerX, centerY, (centerX * centerProportion) -  ((centerX * centerDistanceProportion) * 2), mPaint)}private fun drawText(canvas: Canvas?) {val radius = measuredWidth / 3Fval centerX = measuredWidth / 2Fval centerY = measuredHeight / 2Fval angle = 360F / selectList.sizemPaint.color = sectorTextColormPaint.textSize = centerX * sectorTextSizeProportionfor (i in 0 until selectList.size) {if (selectedIndex == (i + 2) % selectList.size) {mPaint.color = Color.WHITE} else {mPaint.color = sectorTextColor}val cx = centerX + cos(angleToRadian(angle * i)).toFloat() * radius - ((measuredWidth / 2) * sectorTextSizeProportion * 0.42F)val cy = centerY + sin(angleToRadian(angle * i)).toFloat() * radius + ((measuredWidth / 2) * sectorTextSizeProportion * 0.42F)canvas?.drawText(selectList[(i + 2) % selectList.size], cx, cy, mPaint)}if (isClickable) {mPaint.color = startTextColormPaint.textSize = centerX * sectorTextSizeProportion * 0.8ftopText = "开始"canvas?.drawText(topText, centerX * (1 - 0.8F * sectorTextSizeProportion), centerY * (1 + 0.3F * sectorTextSizeProportion), mPaint)} else {mPaint.color = sectorTextColormPaint.textSize = centerX * centerTextProportioncanvas?.drawText(topText, centerX * (1 - 0.3F * centerTextProportion), centerY * (1 + 0.3F * centerTextProportion), mPaint)}}
    

让转盘动起来

这里的让转盘动起来的方式,是通过依次改变扇形的背景颜色,这个是产品需求,你也可以通过动画让他真正的转起来。

我们需要考虑的一点是,我们必须让转盘可控,即转盘的最终结果在开始转之前我们就已经知道,所以我们需要让转盘转到我们指定的结果。

我们可以给转盘一个初始速度和一个结束速度(即美妙转动的次数),理论上结束速度肯定是小于初始速度的,我们每一秒都使速度减小一次,我们通过控制中间减少多少来控制最终转盘转到哪个。

// 确保最后可以选中要选择的private fun computeSpeed() {if (selectedIndex < 0) {selectedIndex = 0}selectedIndex %= selectList.sizevar distance = if (willSelectIndex >= selectedIndex) {willSelectIndex  - selectedIndex} else {selectList.size - selectedIndex + willSelectIndex}distance %= selectList.sizeval speedDistance = (endSpeed - startSpeed) / (selectList.size - 2)speedList.clear()speedList.add(startSpeed)for (i in 1 until selectList.size - 1) {speedList.add(startSpeed + (i * speedDistance))}speedList.add(endSpeed)for (i in 0 until speedList.size) {var count = (1000 / speedList[i])if (count < selectList.size) {count = selectList.size} else {count -= (count % selectList.size)}speedList[i] = 1000 / count}for (i in 0 until distance) {val count = (1000 / speedList[i]) + 1speedList[i] = 1000 / count}}

完整代码

粗略记录,有问题可评论或私信,看到就回。

<declare-styleable name="TurntableView"><attr name="background_color" format="color" /><attr name="sector_color" format="color" /><attr name="center_stroke_color" format="color" /><attr name="center_bottom_color" format="color" /><attr name="sector_text_color" format="color" /><attr name="start_btn_color" format="color" /><attr name="start_text_color" format="color" /></declare-styleable>
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.core.content.ContextCompat
import com.baijiayun.liveuibase.R
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin/*** 转盘工具* @author 陈鹏伟* @date 2022/6/14*/
class TurntableView: View {constructor(context: Context) : super(context) {init(null)}constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {init(attrs)}constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {init(attrs)}constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {init(attrs)}// 默认尺寸private val defaultSize = 150// 扇形半径比例private val sectorProportion = 0.84F// 外圈小圆半径比例private val littleCircleProportion = 0.02F// 中心圆比例private val centerProportion = 0.35F// 中心圆间隔比例private val centerDistanceProportion = 0.05F// 转盘文字比例private val sectorTextSizeProportion = 0.2F// 中心文字比例private val centerTextProportion = 0.3F// 背景颜色(大圆)颜色private var bgColor = 0// 扇形颜色private var sectorColor = 0// 中心圆圈边框颜色private var centerStrokeColor = 0// 中心圆圈底层颜色private var centerBottomColor = 0// 开始按钮背景颜色 = 扇形选中背景颜色private var startColor = 0// 扇形文字颜色private var sectorTextColor = 0// 开始按钮文字颜色 = 扇形选中文字颜色private var startTextColor = 0// 选项列表private var selectList = arrayListOf("1", "2", "3", "4", "5", "6")// 当前选中的选项下标private var selectedIndex = -1// 即将选中的选项下标private var willSelectIndex = 4// 转盘转动的时间 secondsprivate var turnTime = 5// 转盘旋转private var disposableOfTurn: Disposable? = null// 转盘按钮文字private var topText = ""// 初始速度 40ms 一个private var startSpeed = 40// 结束速度 200ms 一个private var endSpeed = 200// 速度列表 1s 一个速度private var speedList = mutableListOf<Int>()// 当前速度private var currentSpeed = 1// 初始是否可点击private var initialClickable = falseprivate val mPaint by lazy {Paint()}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {val width = getRealSize(widthMeasureSpec)val height = getRealSize(heightMeasureSpec)val final = min(width, height)setMeasuredDimension(final, final)}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)mPaint.isAntiAlias = truedrawLargeCircle(canvas)drawSector(canvas)drawCenter(canvas)drawText(canvas)}override fun onTouchEvent(event: MotionEvent?): Boolean {return when (event?.action) {MotionEvent.ACTION_DOWN -> {if (isClickCenter(event.x, event.y)) {performClick()}return isClickCenter(event.x, event.y)}MotionEvent.ACTION_MOVE -> {return false}MotionEvent.ACTION_UP -> {return false}else -> super.onTouchEvent(event)}}override fun setClickable(clickable: Boolean) {super.setClickable(clickable)invalidate()}override fun performClick(): Boolean {return super.performClick()}/*** 设置选项列表* @param list 选项列表,size >= 3*/fun setSelectList(list: ArrayList<String>) {if (list.size < 3) {return}selectList = list}/*** 设置要选中的选项下标* @param index 选项下标*/private fun setWillSelectIndex(index: Int) {if (willSelectIndex != index) {willSelectIndex = index}if (willSelectIndex >= selectList.size) {willSelectIndex = selectList.size - 1}if (willSelectIndex < 0) {willSelectIndex = 0}willSelectIndex = (willSelectIndex + 3) % selectList.size}/*** 设置转盘转动时间* @param time 转盘转动时间 s*/private fun setTurnTime(time: Int) {turnTime = time}/*** 设置背景颜色*/override fun setBackgroundColor(color: Int) {this.bgColor = colorinvalidate()}/*** 设置扇形颜色*/fun setSectorColor(color: Int) {this.sectorColor = colorinvalidate()}/*** 设置阴影颜色*/fun setStrokeColor(color: Int) {this.centerStrokeColor = colorinvalidate()}/*** 设置中心圆底层颜色*/fun setCenterBottomColor(color: Int) {this.centerBottomColor = colorinvalidate()}/*** 设置开始按钮背景颜色和扇形选中颜色*/fun setStartBackgroundColor(color: Int) {this.startColor = colorinvalidate()}/*** 设置扇形文字颜色*/fun setSectorTextColor(color: Int) {this.sectorTextColor = colorinvalidate()}/*** 设置开始按钮文字颜色*/fun setStartTextColor(color: Int) {this.startTextColor = colorinvalidate()}/*** 开始转动转盘* @param selectIndex 最终要选中的值* @param time 转盘转动时间*/fun startTurn(selectIndex: String, time: Int) {setWillSelectIndex(selectList.indexOf(selectIndex))release()setTurnTime(time)topText = turnTime.toString()invalidate()computeSpeed()currentSpeed = speedList[0]initialClickable = isClickableisClickable = falsedisposableOfTurn = Observable.interval(0, 1, TimeUnit.MILLISECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe {if (it >= currentSpeed && it % currentSpeed == 0L) {selectedIndex ++selectedIndex %= selectList.sizeinvalidate()}if (it >= 1000 && it % 1000 == 0L) {currentSpeed = speedList[(it / 1000).toInt()]topText = (turnTime - it / 1000).toString()invalidate()}if (it == turnTime * 1000L + 500) {if (initialClickable) {isClickable = truetopText = "开始"} else {topText = ""}disposableOfTurn?.dispose()invalidate()}}}/*** 转盘是否正在转动*/fun isTurning() = disposableOfTurn != null && !disposableOfTurn!!.isDisposed/*** 释放资源,父容器销毁时须调用*/fun release() {disposableOfTurn?.dispose()}private fun init(attrs: AttributeSet?) {val typedArray = context.obtainStyledAttributes(attrs, R.styleable.TurntableView)bgColor = typedArray.getColor(R.styleable.TurntableView_background_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_background_color))sectorColor = typedArray.getColor(R.styleable.TurntableView_sector_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_sector_color))centerStrokeColor = typedArray.getColor(R.styleable.TurntableView_center_stroke_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_center_stroke_color))centerBottomColor = typedArray.getColor(R.styleable.TurntableView_center_bottom_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_center_bottom_color))sectorTextColor = typedArray.getColor(R.styleable.TurntableView_sector_text_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_sector_text_color))startColor = typedArray.getColor(R.styleable.TurntableView_start_btn_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_start_btn_color))startTextColor = typedArray.getColor(R.styleable.TurntableView_start_text_color, ContextCompat.getColor(context, R.color.bjy_base_turntable_default_start_text_color))typedArray.recycle()}private fun getRealSize(measureSpec: Int): Int {val mode = MeasureSpec.getMode(measureSpec)val size = MeasureSpec.getSize(measureSpec)return if (mode == MeasureSpec.EXACTLY) {size} else {defaultSize}}private fun drawLargeCircle(canvas: Canvas?) {val centerX = measuredWidth / 2Fval centerY = measuredHeight / 2Fval radius = measuredWidth / 2FmPaint.color = bgColorcanvas?.drawCircle(centerX, centerY, radius - 10, mPaint)mPaint.color = centerStrokeColormPaint.style = Paint.Style.STROKEfor (i in 0 until 10) {mPaint.alpha = 5 * (i + 1)canvas?.drawCircle(centerX, centerY, radius - i, mPaint)}}private fun drawSector(canvas: Canvas?) {val sectorRadius = (measuredWidth / 2) * sectorProportionval sectorCenterRadius = (measuredWidth / 2) * 0.07fval centerX = measuredWidth / 2Fval centerY = measuredHeight / 2FmPaint.color = sectorColormPaint.style = Paint.Style.FILLvar angle = 360F / selectList.sizefor (i in 0 until selectList.size) {if ((i + 2) % selectList.size == selectedIndex) {mPaint.color = startColor} else {mPaint.color = sectorColor}val cx = centerX + cos(angleToRadian(angle * i)).toFloat() * sectorCenterRadiusval cy = centerY + sin(angleToRadian(angle * i)).toFloat() * sectorCenterRadiusval oval = RectF(cx - sectorRadius, cy - sectorRadius, cx + sectorRadius, cy + sectorRadius)canvas?.drawArc(oval, (angle * i) - (angle / 2), angle, true, mPaint)}mPaint.color = sectorColormPaint.alpha = 50val littleCircleCount = selectList.size * 2angle = 360F / littleCircleCountfor (i in 0 until littleCircleCount) {val littleCenterX = centerX + cos(angleToRadian(angle * i)).toFloat() * (((measuredWidth / 2) + sectorRadius + sectorCenterRadius) / 2F - 5)val littleCenterY = centerY + sin(angleToRadian(angle * i)).toFloat() * (((measuredWidth / 2) + sectorRadius + sectorCenterRadius) / 2F - 5)canvas?.drawCircle(littleCenterX, littleCenterY, (measuredWidth / 2) * littleCircleProportion, mPaint)}}private fun drawCenter(canvas: Canvas?) {val centerX = measuredWidth / 2Fval centerY = measuredHeight / 2FmPaint.color = bgColormPaint.alpha = 255canvas?.drawCircle(centerX, centerY, (measuredWidth / 2) * centerProportion, mPaint)mPaint.style = Paint.Style.STROKEmPaint.color = centerStrokeColormPaint.strokeWidth = 1Ffor (i in 0..(centerX * centerDistanceProportion).toInt()) {mPaint.alpha = 5 * icanvas?.drawCircle(centerX, centerY, centerX * centerProportion - i, mPaint)}mPaint.color = bgColormPaint.style = Paint.Style.FILLcanvas?.drawCircle(centerX, centerY, (centerX * centerProportion) -  (centerX * centerDistanceProportion), mPaint)mPaint.color = centerBottomColorcanvas?.drawCircle(centerX, centerY, (centerX * centerProportion) -  ((centerX * centerDistanceProportion) * 1.5F), mPaint)if (isClickable) {mPaint.color = startColor} else {mPaint.color = bgColor}canvas?.drawCircle(centerX, centerY, (centerX * centerProportion) -  ((centerX * centerDistanceProportion) * 2), mPaint)}private fun drawText(canvas: Canvas?) {val radius = measuredWidth / 3Fval centerX = measuredWidth / 2Fval centerY = measuredHeight / 2Fval angle = 360F / selectList.sizemPaint.color = sectorTextColormPaint.textSize = centerX * sectorTextSizeProportionfor (i in 0 until selectList.size) {if (selectedIndex == (i + 2) % selectList.size) {mPaint.color = Color.WHITE} else {mPaint.color = sectorTextColor}val cx = centerX + cos(angleToRadian(angle * i)).toFloat() * radius - ((measuredWidth / 2) * sectorTextSizeProportion * 0.42F)val cy = centerY + sin(angleToRadian(angle * i)).toFloat() * radius + ((measuredWidth / 2) * sectorTextSizeProportion * 0.42F)canvas?.drawText(selectList[(i + 2) % selectList.size], cx, cy, mPaint)}if (isClickable) {mPaint.color = startTextColormPaint.textSize = centerX * sectorTextSizeProportion * 0.8ftopText = "开始"canvas?.drawText(topText, centerX * (1 - 0.8F * sectorTextSizeProportion), centerY * (1 + 0.3F * sectorTextSizeProportion), mPaint)} else {mPaint.color = sectorTextColormPaint.textSize = centerX * centerTextProportioncanvas?.drawText(topText, centerX * (1 - 0.3F * centerTextProportion), centerY * (1 + 0.3F * centerTextProportion), mPaint)}}private fun angleToRadian(angle: Float) = angle * PI / 180private fun isClickCenter(x: Float, y: Float): Boolean {val centerX = measuredWidth / 2val centerY = measuredHeight / 2val radius = (measuredWidth / 2) * centerProportionif (x < centerX - radius || x > centerX + radius) {return false}if (y > centerY + radius || y < centerY - radius) {return false}return true}// 确保最后可以选中要选择的private fun computeSpeed() {if (selectedIndex < 0) {selectedIndex = 0}selectedIndex %= selectList.sizevar distance = if (willSelectIndex >= selectedIndex) {willSelectIndex  - selectedIndex} else {selectList.size - selectedIndex + willSelectIndex}distance %= selectList.sizeval speedDistance = (endSpeed - startSpeed) / (selectList.size - 2)speedList.clear()speedList.add(startSpeed)for (i in 1 until selectList.size - 1) {speedList.add(startSpeed + (i * speedDistance))}speedList.add(endSpeed)for (i in 0 until speedList.size) {var count = (1000 / speedList[i])if (count < selectList.size) {count = selectList.size} else {count -= (count % selectList.size)}speedList[i] = 1000 / count}for (i in 0 until distance) {val count = (1000 / speedList[i]) + 1speedList[i] = 1000 / count}}
}

Android 自定义 View 实现转盘功能相关推荐

  1. android xml画圆,Android自定义View画圆功能

    本文实例为大家分享了Android自定义View画圆的具体代码,供大家参考,具体内容如下 引入布局 xmlns:tools="http://schemas.android.com/tools ...

  2. android+清除循环动画,android自定义View之(4)-一键清除动画

    android自定义View之(四)------一键清除动画 1.前言: 自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法.今天,我参考了一些资料,再结合自已的一些理解, ...

  3. android自定义View之(四)------一键清除动画

    1.前言: 自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法.今天,我参考了一些资料,再结合自已的一些理解,做了一个一键清除的动画.当年,我实现这个是用了几张图片,采用F ...

  4. android代码实现手机加速功能,Android自定义View实现内存清理加速球效果

    Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...

  5. android自定义抽奖,Android自定义view制作抽奖转盘

    本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...

  6. Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能

    支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几 ...

  7. android 自定义 对号,Android自定义View实现打钩动画功能

    先上效果图 动图 静态图 1. 回顾 [Android自定义View:一个精致的打钩小动画]上一篇文章,我们已经实现了基本上实现了控件的效果了,但是...但是...过了三四天后,仔细看回自己写的代码, ...

  8. android 开发打赏布局,Android自定义View模仿虎扑直播界面的打赏按钮功能

    Android自定义View模仿虎扑直播界面的打赏按钮功能 发布时间:2020-09-28 12:15:53 来源:脚本之家 阅读:77 作者:shenhuniurou 前言 作为一个资深篮球爱好者, ...

  9. android wear支付宝6,Android自定义View仿支付宝输入六位密码功能

    跟选择银行卡界面类似,也是用一个PopupWindow,不过输入密码界面是一个自定义view,当输入六位密码完成后用回调在Activity中获取到输入的密码并以Toast显示密码.效果图如下: 自定义 ...

  10. Android5.0自定义闹钟,Android自定义View 实现闹钟唤起播放闹钟铃声功能

    先上图看一下闹钟唤期页面的效果 实现的功能: 1:转动的图片根据天气情况更换 2:转动时间可以设置,转动结束,闹铃声音就结束 3:光圈颜色渐变效果 直接上代码啦: package com.yuekon ...

最新文章

  1. 内核同步机制——完成量
  2. 操作系统经典书籍--现代操作系统
  3. 报文解析_104规约报文结构解析
  4. iWiscloud智慧家居控制中心
  5. Oracle ERP权限管理
  6. setTimeout,setInterval你不知道的事
  7. [项目回顾]基于Annotation与SpringAOP的缓存简单解决方案
  8. Java Web 项目音乐网站的开发与实现
  9. c语言大作业图书馆,大一C语言课程设计—图书馆管理系统
  10. STM32的硬件SPI驱动AD7124的方法
  11. HTML菜鸟教程学习笔记
  12. 库房--库存信息增加导出Excel表格功能
  13. 利用python进行A/B测试
  14. 【编译原理·总复习】第二章||文法语言||语法树||最左最右推导归约||句柄直接短语||例题+知识点
  15. 日语资料和电子版教材无偿分享
  16. Chrome浏览器命令行启动参数
  17. 语音信号短时平稳特性
  18. 犹太人传承了三千多年的10大赚钱定律
  19. 雨伞消费行业调研报告 - 市场现状分析与发展前景预测
  20. 校验Ipv4 ipv6的格式 python

热门文章

  1. outlook邮箱收件服务器密码,outlook邮箱 收件服务器
  2. 改进初学者的PID-测量的比例编码
  3. 概率论与数理统计学习笔记(5)——极大似然估计
  4. uniapp上班考勤打卡情况日历展示
  5. Windows图标-Icon文件格式分析。
  6. 计算机系统图标文件,电脑软件的图标图片文件都集中在哪个文件夹??
  7. ensp 不兼容 virtualbox,virtualbox version not support (AR 报错40 41 解决思路)
  8. 苹果cms大橙子完美版源码,影视模板
  9. windows server 2003忘记密码
  10. 人机交互-13-复习总览