样式效果

还是先来看效果:

这是一个仿雷达扫描的效果,是之前在做地图sdk接入时就想实现的效果,但之前由于赶着毕业设计,就没有亲手去实现,不过现在自己撸一个发现还是挺简单的。

这里主要分享一下我的做法。

目录

主体轮廓的实现(雷达的结构)

动画的实现(雷达扫描的效果)

目标点的加入(图片/点)

主体轮廓实现

不难分析得出,这个View主要由外部的一个圆,中间的锚点圆以及扇形旋转区域组成。而且每个部分理应由不同的Paint去绘制,以方便去定制各部分的样式。

外部圆以及锚点圆的绘制较为简单,主要的点还是要对整个View的宽高进行一定的限制,例如宽高必须相等且在某种模式下,取小的那个值来限定整个RadarView的最大值。那么该如何去控制呢?

onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)

由于我们继承自View,在onMeasure方法中,我们可以根据两个参数来获取Mode,并且根据Mode来指定宽/高对应的值,再通过setMeasuredDimension去指定控件主体的宽高即可。

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec)

val vWidth = measureDimension(widthMeasureSpec)

val vHeight = measureDimension(heightMeasureSpec)

val size = min(vWidth, vHeight)

setMeasuredDimension(size, size)

}

private fun measureDimension(spec: Int) = when (MeasureSpec.getMode(spec)) {

MeasureSpec.EXACTLY -> {

// exactly number or match_parent

MeasureSpec.getSize(spec)

}

MeasureSpec.AT_MOST -> {

// wrap_content

min(mDefaultSize, MeasureSpec.getSize(spec))

}

else -> {

mDefaultSize

}

}

测量工作完成了,我们自然可以去绘制了。为了不让中间的小圆看起来那么突兀(偏大或偏小),这里设置了一个scaleFactor的缩放因子,使其能根据外圆的尺寸来进行缩放。

override fun onDraw(canvas: Canvas?) {

super.onDraw(canvas)

// draw outside circle (background)

canvas?.drawCircle(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2, measuredWidth.toFloat() / 2, mOutlinePaint)

if (mBorderWidth > 0F && mOutlinePaint.shader == null) {

drawBorder(canvas)

}

// mOutlineRect = Rect(0, 0, measuredWidth, measuredHeight)

canvas?.drawArc(mOutlineRect.toRectF(), mStartAngle, mSweepAngle, true, mSweepPaint)

// draw center circle

// scaleFactor = 30F

canvas?.drawCircle(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2, measuredWidth.toFloat() / 2 / mScaleFactor, mPaint)

}

private fun drawBorder(canvas: Canvas?) {

Log.i("RadarView", "drawBorder")

mOutlinePaint.style = Paint.Style.STROKE

mOutlinePaint.color = mBorderColor

mOutlinePaint.strokeWidth = mBorderWidth

canvas?.drawCircle(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2,

(measuredWidth.toFloat() - mBorderWidth) / 2, mOutlinePaint)

// 还原

mOutlinePaint.style = Paint.Style.FILL_AND_STROKE

mOutlinePaint.color = mBackgroundColor

}

绘制了基准圆以后,要实现雷达扫描时那种渐变的效果,我们可以通过SweepGradient来操作。通过指定中心点,渐变颜色,以及颜色的分布,来定制扫描渐变的样式,默认的即时开头时gif展示的那种。由于这里是从第一象限开始旋转,因此将旋转的起点通过matrix逆时针旋转90度,从而达到由浅入深的效果。

private fun setShader(size: Int) {

val shader = SweepGradient(size.toFloat() / 2, size.toFloat() / 2,

mScanColors?: mDefaultScanColors, // 可通过setScanColors()来定制颜色

floatArrayOf(0F, 0.5F, 1F)) // 这里默认走平均分布

val matrix = Matrix()

// 逆时针旋转90度

matrix.setRotate(-90F, size.toFloat() / 2, size.toFloat() / 2)

shader.setLocalMatrix(matrix)

mSweepPaint.shader = shader

}

这里完成了测量与绘制的工作,那么我们在布局里引用以后,就会看到这样的效果:

这时,由于我们之前在测量的时候,将宽高最小值作为绘制的基准大小给予了RadarView,因此measuredWidth和measuredHeight是相等的,但是由于在布局中指定了match_parent属性,那么实际的控件宽高还是和父布局一致(在这里即占满屏幕宽高,由于宽比高小,所以看到绘制的图形会偏向上方;如果设置了高比宽小,那么绘制的图形就会位于左侧)。一般的雷达控件应该都是居中显示的,所以我在这里也重写了onLayout方法,来实现居中的效果。

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {

// 设置默认居中

var l = left

var r = right

var t = top

var b = bottom

when {

width > height -> {

// 宽度比高度大 那么要设置默认居中就得把left往右移 right往左移

l = (width - measuredWidth) / 2

r = width - l

layout(l, t, r, b)

}

height > width -> {

// 高度比宽度大 那么要设置默认居中就得把top往下移 bottom往上移

t = (height - measuredHeight) / 2

b = height - t

layout(l, t, r, b)

}

else -> super.onLayout(changed, left, top, right, bottom)

}

}

动画的实现

完成了绘制,接下来就是思考该如何让他动起来了。由绘制的代码不难想到,我这里考虑的是通过mStartAngle的变化来控制绘制的角度旋转,而ValueAnimator则正好能获取到每次更新时value的值,因此这里我选用了这个方案。

fun start() {

Log.i("RadarView", "animation start")

mIsAnimating = true

mAnimator.duration = 2000

mAnimator.repeatCount = ValueAnimator.INFINITE

mAnimator.addUpdateListener {

val angle = it.animatedValue as Float

mStartAngle = angle

// Log.i("RadarView", "mStartAngle = $mStartAngle and curValue = ${it.animatedValue}")

postInvalidate()

}

mAnimator.start()

}

这里就需要注意一个点,就是canvas在绘制时,后绘制的会覆盖在前绘制的图像上,所以需要注意绘制的顺序。当然,这里也可以把mOutlineRect的宽高设置为measuredWidth - mBorderWidth,那么就能保证绘制填充角度时,不会把边界覆盖。

至此,动画的效果便完成了。

目标点的加入

首先,前两点已经能满足大多的雷达扫描需求了。这里这个添加目标点(target)纯粹是我自己想加入的功能,因为觉得可以结合地图sdk的MapView来共同使用,目前也只是开发阶段,扩展性可能考虑得还不是特别充足,也还没应用到具体项目中。但是,总觉得自己想的功能也该试着去实践一下~

这里主要运用的圆的计算公式:

由于Android的坐标系的原点是在左上角,y轴过顶点向下延伸。由我们的绘制可知,此绘制图像在坐标系中的位置大概如下图所示:

那么,对应的公式就为:

要注意的是,这里r的计算会根据图/点的设置来动态计算,具体例子通过代码来进行分析。

// 随机落点

fun addTarget(size: Int, type: TYPE = TYPE.RANDOM) {

val list = ArrayList()

val r = measuredWidth.toFloat() / 2

val innerRect = Rect((r - r / mScaleFactor).toInt(), (r - r / mScaleFactor).toInt(),

(r + r / mScaleFactor).toInt(), (r + r / mScaleFactor).toInt())

// 圆的中心点

val circle = PointF(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2)

while (list.size < size) {

val ranX = Random.nextDouble(0.0, r * 2.0).toFloat()

val ranY = Random.nextDouble(0.0, r * 2.0).toFloat()

val ranPointF = PointF(ranX, ranY)

if (innerRect.contains(ranPointF.toPoint())) {

continue

}

// 圆公式

if (!mNeedBitmap &&

(ranX - circle.x).pow(2) + (ranY - circle.y).pow(2) <

(r - mTargetRadius - mBorderWidth).toDouble().pow(2.0)) {

// 普通点

addTargetFromType(type, list, ranX, ranY, r, ranPointF)

} else if (mNeedBitmap &&

(ranX - circle.x).pow(2) + (ranY - circle.y).pow(2) <

(r - mBorderWidth - max(mBitmap.width, mBitmap.height) / 2).toDouble().pow(2)) {

// 图

addTargetFromType(type, list, ranX, ranY, r, ranPointF)

} else {

continue

}

}

mTargetList = list

for (target in list) {

Log.i("RadarView", "target = [${target.x}, ${target.y}]")

}

invalidate()

}

可以看到,当target为普通点时,r的计算还要减去targetRadius,即目标点的半径,同时还要减去边界的宽度,如图所示:

当target为图时,由于宽高不定,故除了边界外,还要减去大的边,那么r的计算则为:

同时为了避免图片的尺寸过大,这里同样采取了一个默认值与一个缩放因子,从而保证图的完整性以及避免过大而引起的视觉丑化。

关于落点的位置,目前采取的是随机落点,如果应用到地图扫点的话,可以通过地图sdk内的距离计算工具再与RadarView的坐标做一个比例转换,从而达到雷达内显示该点具体方位。

关于落点的分布,目前提供了5种类型:分别是全象限随机、第一象限、第二象限、第三象限与第四象限随机。

Github

若须直接调用,可移步至 https://github.com/CarsonWoo/RadarView

完整代码

class RadarView : View {

enum class TYPE { RANDOM, FIRST, SECOND, THIRD, FOURTH }

private val mPaint by lazy { Paint(Paint.ANTI_ALIAS_FLAG) }

private val mSweepPaint by lazy { Paint(Paint.ANTI_ALIAS_FLAG) }

private val mOutlinePaint by lazy { Paint(Paint.ANTI_ALIAS_FLAG) }

private val mTargetPaint by lazy { Paint(Paint.ANTI_ALIAS_FLAG) }

private val mDefaultSize = 120// px

// limit the size of bitmap

private var mBitmapMaxSize = 0F

private var mBitmapWHRatio = 0F

private val mScaleFactor = 30F

private var mStartAngle = 0F

private val mSweepAngle = -60F

private var mScanColors: IntArray? = null

private val mDefaultScanColors = intArrayOf(Color.parseColor("#0F7F7F7F"),

Color.parseColor("#7F7F7F7F"),

Color.parseColor("#857F7F7F"))

private val mDefaultBackgroundColor = Color.WHITE

private var mBackgroundColor: Int = mDefaultBackgroundColor

private var mBorderColor: Int = Color.BLACK

private var mBorderWidth = 0F

private var mTargetColor: Int = Color.RED

private var mTargetRadius = 10F

private lateinit var mOutlineRect: Rect

private val mAnimator = ValueAnimator.ofFloat(0F, 360F)

private var mTargetList: ArrayList? = null

private var mIsAnimating = false

private var mNeedBitmap = false

private var mBitmap = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher)

constructor(context: Context): this(context, null)

constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet)

init {

mPaint.color = Color.GRAY

mPaint.strokeWidth = 10F

mPaint.style = Paint.Style.FILL_AND_STROKE

mPaint.strokeJoin = Paint.Join.ROUND

mPaint.strokeCap = Paint.Cap.ROUND

mSweepPaint.style = Paint.Style.FILL

mOutlinePaint.style = Paint.Style.FILL_AND_STROKE

mOutlinePaint.color = mBackgroundColor

mTargetPaint.style = Paint.Style.FILL

mTargetPaint.color = mTargetColor

mTargetPaint.strokeWidth = 10F

}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec)

val vWidth = measureDimension(widthMeasureSpec)

val vHeight = measureDimension(heightMeasureSpec)

val size = min(vWidth, vHeight)

setShader(size)

setMeasuredDimension(size, size)

setParamUpdate()

}

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {

// 设置默认居中

var l = left

var r = right

var t = top

var b = bottom

when {

width > height -> {

// 宽度比高度大 那么要设置默认居中就得把left往右移 right往左移

l = (width - measuredWidth) / 2

r = width - l

layout(l, t, r, b)

}

height > width -> {

// 高度比宽度大 那么要设置默认居中就得把top往下移 bottom往上移

t = (height - measuredHeight) / 2

b = height - t

layout(l, t, r, b)

}

else -> super.onLayout(changed, left, top, right, bottom)

}

}

private fun setShader(size: Int) {

val shader = SweepGradient(size.toFloat() / 2, size.toFloat() / 2,

mScanColors?: mDefaultScanColors,

floatArrayOf(0F, 0.5F, 1F))

val matrix = Matrix()

matrix.setRotate(-90F, size.toFloat() / 2, size.toFloat() / 2)

shader.setLocalMatrix(matrix)

mSweepPaint.shader = shader

}

fun setScanColors(colors: IntArray) {

this.mScanColors = colors

setShader(measuredWidth)

invalidate()

}

fun setRadarColor(@ColorInt color: Int) {

this.mBackgroundColor = color

this.mOutlinePaint.color = color

invalidate()

}

fun setRadarColor(colorString: String) {

if (!colorString.startsWith("#") || colorString.length != 7 || colorString.length != 9) {

Log.e("RadarView", "colorString parse error, please check your enter param")

return

}

val color = Color.parseColor(colorString)

setRadarColor(color)

}

fun setBorderColor(@ColorInt color: Int) {

this.mBorderColor = color

invalidate()

}

fun setBorderColor(colorString: String) {

if (!colorString.startsWith("#") || colorString.length != 7 || colorString.length != 9) {

Log.e("RadarView", "colorString parse error, please check your enter param")

return

}

val color = Color.parseColor(colorString)

setBorderColor(color)

}

fun setRadarGradientColor(colors: IntArray) {

val shader = SweepGradient(measuredWidth.toFloat() / 2,

measuredHeight.toFloat() / 2, colors, null)

mOutlinePaint.shader = shader

invalidate()

}

fun setBorderWidth(width: Float) {

this.mBorderWidth = width

invalidate()

}

private fun setParamUpdate() {

mOutlineRect = Rect(0, 0, measuredWidth, measuredHeight)

mBitmapMaxSize = measuredWidth.toFloat() / mScaleFactor

}

private fun measureDimension(spec: Int) = when (MeasureSpec.getMode(spec)) {

MeasureSpec.EXACTLY -> {

// exactly number or match_parent

MeasureSpec.getSize(spec)

}

MeasureSpec.AT_MOST -> {

// wrap_content

min(mDefaultSize, MeasureSpec.getSize(spec))

}

else -> {

mDefaultSize

}

}

override fun setBackground(background: Drawable?) {

// 取消传统背景设置

// super.setBackground(background)

}

override fun onDraw(canvas: Canvas?) {

super.onDraw(canvas)

// draw outside circle (background)

canvas?.drawCircle(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2, measuredWidth.toFloat() / 2, mOutlinePaint)

if (mBorderWidth > 0F && mOutlinePaint.shader == null) {

drawBorder(canvas)

}

canvas?.drawArc(mOutlineRect.toRectF(), mStartAngle, mSweepAngle, true, mSweepPaint)

if (!mTargetList.isNullOrEmpty() && !mIsAnimating) {

drawTarget(canvas)

}

// draw center circle

canvas?.drawCircle(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2, measuredWidth.toFloat() / 2 / mScaleFactor, mPaint)

}

private fun drawBorder(canvas: Canvas?) {

Log.i("RadarView", "drawBorder")

mOutlinePaint.style = Paint.Style.STROKE

mOutlinePaint.color = mBorderColor

mOutlinePaint.strokeWidth = mBorderWidth

canvas?.drawCircle(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2,

(measuredWidth.toFloat() - mBorderWidth) / 2, mOutlinePaint)

// 还原

mOutlinePaint.style = Paint.Style.FILL_AND_STROKE

mOutlinePaint.color = mBackgroundColor

}

private fun drawTarget(canvas: Canvas?) {

mTargetList?.let {

Log.e("RadarView", "draw target")

for (target in it) {

if (mNeedBitmap) {

canvas?.drawBitmap(mBitmap, target.x - mBitmap.width / 2,

target.y - mBitmap.height / 2, mTargetPaint)

} else {

canvas?.drawCircle(target.x, target.y, mTargetRadius, mTargetPaint)

}

}

}

}

fun setBitmapEnabled(enabled: Boolean, drawable: Drawable) {

// 这里是为了防止界面还未获取到宽高时 会导致onMeasure走不到 那么maxSize就会为0

post {

this.mNeedBitmap = enabled

this.mBitmapWHRatio = drawable.intrinsicWidth.toFloat() / drawable.intrinsicHeight.toFloat()

mBitmap = if (mBitmapWHRatio >= 1) {

// 宽比高大

drawable.toBitmap(

width = min(mBitmapMaxSize, drawable.intrinsicWidth.toFloat()).toInt(),

height = (min(mBitmapMaxSize, drawable.intrinsicWidth.toFloat()) / mBitmapWHRatio).toInt(),

config = Bitmap.Config.ARGB_8888)

} else {

// 高比宽大

drawable.toBitmap(

height = min(mBitmapMaxSize, drawable.intrinsicHeight.toFloat()).toInt(),

width = (min(mBitmapMaxSize, drawable.intrinsicHeight.toFloat()) * mBitmapWHRatio).toInt(),

config = Bitmap.Config.ARGB_8888

)

}

}

}

// 随机落点

fun addTarget(size: Int, type: TYPE = TYPE.RANDOM) {

val list = ArrayList()

val r = measuredWidth.toFloat() / 2

val innerRect = Rect((r - r / mScaleFactor).toInt(), (r - r / mScaleFactor).toInt(),

(r + r / mScaleFactor).toInt(), (r + r / mScaleFactor).toInt())

// 圆的中心点

val circle = PointF(measuredWidth.toFloat() / 2, measuredHeight.toFloat() / 2)

while (list.size < size) {

val ranX = Random.nextDouble(0.0, r * 2.0).toFloat()

val ranY = Random.nextDouble(0.0, r * 2.0).toFloat()

val ranPointF = PointF(ranX, ranY)

if (innerRect.contains(ranPointF.toPoint())) {

continue

}

// 圆公式

if (!mNeedBitmap &&

(ranX - circle.x).pow(2) + (ranY - circle.y).pow(2) <

(r - mTargetRadius - mBorderWidth).toDouble().pow(2.0)) {

// 在圆内

addTargetFromType(type, list, ranX, ranY, r, ranPointF)

} else if (mNeedBitmap &&

(ranX - circle.x).pow(2) + (ranY - circle.y).pow(2) <

(r - mBorderWidth - max(mBitmap.width, mBitmap.height) / 2).toDouble().pow(2)) {

addTargetFromType(type, list, ranX, ranY, r, ranPointF)

} else {

continue

}

}

mTargetList = list

for (target in list) {

Log.i("RadarView", "target = [${target.x}, ${target.y}]")

}

invalidate()

}

private fun addTargetFromType(type: TYPE, list: ArrayList, ranX: Float, ranY: Float,

r: Float, ranPointF: PointF) {

when (type) {

TYPE.RANDOM -> {

list.add(ranPointF)

}

TYPE.FOURTH -> {

if (ranX in r.toDouble()..2 * r.toDouble() && ranY in r.toDouble()..2 * r.toDouble()) {

list.add(ranPointF)

}

}

TYPE.THIRD -> {

if (ranX in 0.0..r.toDouble() && ranY in r.toDouble()..2 * r.toDouble()) {

list.add(ranPointF)

}

}

TYPE.SECOND -> {

if (ranX in 0.0..r.toDouble() && ranY in 0.0..r.toDouble()) {

list.add(ranPointF)

}

}

TYPE.FIRST -> {

if (ranX in r.toDouble()..2 * r.toDouble() && ranY in 0.0..r.toDouble()) {

list.add(ranPointF)

}

}

}

}

fun start() {

Log.i("RadarView", "animation start")

mIsAnimating = true

mAnimator.duration = 2000

mAnimator.repeatCount = ValueAnimator.INFINITE

mAnimator.addUpdateListener {

val angle = it.animatedValue as Float

mStartAngle = angle

Log.i("RadarView", "mStartAngle = $mStartAngle and curValue = ${it.animatedValue}")

postInvalidate()

}

mAnimator.start()

}

fun start(startVal: Float, endVal: Float) {

mIsAnimating = true

mAnimator.setFloatValues(startVal, endVal)

mAnimator.duration = 2000

mAnimator.repeatCount = ValueAnimator.INFINITE

mAnimator.addUpdateListener {

mStartAngle = it.animatedValue as Float

Log.i("RadarView", "mStartAngle = $mStartAngle and curValue = ${it.animatedValue}")

postInvalidate()

}

mAnimator.start()

}

fun stop() {

mIsAnimating = false

if (mAnimator.isRunning) {

mAnimator.cancel()

mAnimator.removeAllListeners()

}

mStartAngle = 0F

}

}

调用方式

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

radar_view.setBorderWidth(5F)

radar_view.setRadarColor(Color.TRANSPARENT)

radar_view.setBitmapEnabled(true, resources.getDrawable(R.mipmap.ic_launcher_round))

// radar_view.setScanColors(intArrayOf(Color.RED, Color.LTGRAY, Color.CYAN))

// radar_view.setRadarGradientColor(intArrayOf(Color.RED, Color.GREEN, Color.BLUE))

btn_start.setOnClickListener {

radar_view.start()

// workThreadAndCallback()

}

btn_stop.setOnClickListener {

radar_view.stop()

radar_view.addTarget(7)

}

}

总结

到此这篇关于Android实现雷达View效果的文章就介绍到这了,更多相关android 雷达View效果内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

android 实现 效果代码,Android实现雷达View效果的示例代码相关推荐

  1. python3图片转代码_python3图片转换二进制存入mysql示例代码

    python3图片转换二进制存入mysql示例代码 发布于 2014-09-29 18:00:01 | 198 次阅读 | 评论: 0 | 来源: 网友投递 Python编程语言Python 是一种面 ...

  2. android百度api配置,Android Studio 配置使用百度api (附带简单样例)(示例代码)

    还是和同学开发的那个课程作业项目的app, 要使用到百度地图的api 但是,官方文档貌似只有Eclipse的例子,对Android Studio似乎没有说明.  难道,是因为后者是 "Doo ...

  3. unity Android 剪贴板,Unity移动端的复制要这么写示例代码

    前言 Unity官网提供了详尽的文档和丰富的教学视频,昨天跟着视频做了一个简单的3d游戏"roll-a-ball".游戏涉及了许多Unity的基本知识,用来入门很不错. 本文主要给 ...

  4. android怎么用代码调图像,浅谈android中图片处理之图形变换特效Matrix(四)(示例代码)...

    今天,我们就来谈下android中图片的变形的特效,在上讲博客中我们谈到android中图片中的色彩特效来实现的.改变它的颜色主要通过ColorMatrix类来实现. 现在今天所讲的图片变形的特效主要 ...

  5. android开发分享到微信,Android开发之微信分享到好友,朋友圈(示例代码)

    3. 快速集成 第二步:配置AndroidManifest.xml 下面清单文件的配置是全部的,没有的平台就是不需要配置 1.添加权限 2.添加activity信息 (注意: tencent后面的ap ...

  6. android vitamio集成教程,集成Vitamio实现万能播放器(示例代码)

    简介: Vitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染.Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发者的青睐.到目 ...

  7. android 3d魔方 代码,css实现3d立体魔方的示例代码

    今天来做一个简单的3d魔方 先看效果图吧!把这个看会了,一些网上的3d的相册你就都会了 一.我们先准备好们的html代码 3d立体魔方 好了我们html代码就准备完成了,首先我们要有一个3d的思维,在 ...

  8. android自定义主题背景颜色,Android 自定义SeekBar 实现分段显示不同背景颜色的示例代码...

    在最近的开发工作中,要实现一个调色板的进度条,SeekBar要分成10段显示不同颜色,功夫不负有心人,终于实现了这个功能,下面分享给大家 示例图: 1.自定义SeekBar import androi ...

  9. html5车牌效果,html中车牌号省份简称输入键盘的示例代码

    这篇文章主要介绍了html中车牌号省份简称输入键盘的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧原理是先写出一个按键的 ...

最新文章

  1. (转)基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用
  2. 深圳人均GDP过一万美元随想
  3. 戴尔服务:为企业转型导航
  4. MFC中Mat实现打开关闭本地摄像头
  5. Jfinal 对象列表返回前台json数据
  6. Maven and Ant for Hybris
  7. 编译c语言程序时 程序中的注释部分将,C语言程序编译时,程序中的注释部分将 答案:不参加编译,也不会出现在目标程序中...
  8. perl学习笔记(9)
  9. 计算abc=a!+b!+c!
  10. oracle数据泵索引创建慢,IMPDP 很慢的原因探究
  11. gabor变换人脸识别的python实现,att_faces数据集平均识别率99%
  12. CST,CET,UTC,GMT,DST,Unix时间戳几种常见时间概述与关系(转)
  13. JAVA分页查询实现
  14. OR(odd ratios)
  15. js日期格式化yyyy-MM-dd
  16. 高性价比掌机Retroid Pocket 3:搭载展锐芯片T310,采用PowerVR GPU
  17. u盘数据恢复软件mac版下载与应用
  18. 能一次性管理10--20个群的微信群机器人助手到底有多好用!
  19. 中国计算机应用大会2021,2021中国计算机教育大会
  20. 金蝶K3与AUTOCAD2007兼容性,打开金蝶K3时候提示配置问题

热门文章

  1. 【Flink】Flink界面如何查看数据是否倾斜
  2. dubbo注册中心的细节
  3. java中static类的作用是什么意思_java中static关键字是什么意思
  4. php实现sql server数据导入到mysql数据库_SQL Server数据库导入MySQL数据库的体验_MySQL...
  5. 死磕18个Java8日期处理,工作必用!收藏起来~
  6. 【超全指南】Java 8 中使用 Optional 处理 null 对象
  7. 23种设计模式(4)-生成器模式
  8. oracle扩容bigfile,Oracle10g BIGFILE表空间带来的好处
  9. 服务状态已停止_虾米音乐今日宣布关停,新平台”音螺“相关商标已注册
  10. golang 两个一样的字符串不相等_分享一个姑娘双眼皮术后两个眼睛有点不一样,不知道该不该修复?...