一步步實(shí)現(xiàn)自定義View之播放暫??丶?/h1>
更新時(shí)間:2018年06月28日 15:51:18 作者:ckwccc
本文教大家一步步實(shí)現(xiàn)自定義View之播放暫??丶?,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
最近開始深入學(xué)習(xí)自定義View,通過模仿學(xué)習(xí),再配合Kotlin,寫了一些自定義控件,這次介紹的是類似于音樂播放暫停的一個(gè)控件
首先看一下效果圖:

下面先分析一下原理:

狀態(tài)1是播放狀態(tài),有兩個(gè)小矩形,外面是一個(gè)圓,它需要最終變換成狀態(tài)3的暫停狀態(tài)
狀態(tài)2是兩個(gè)小矩形變成如圖的黑色三角的一個(gè)過程
我們可以通過動(dòng)畫來實(shí)現(xiàn)它,兩個(gè)小矩形分別變成三角形的一半
同時(shí)再給畫布一個(gè)90度的旋轉(zhuǎn)
具體實(shí)現(xiàn):
1.繼承View
class PlayPauseView : View
2.重寫構(gòu)造函數(shù)
constructor(context: Context?) : this(context,null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs,0)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){
init(context!!,attrs!!)
}
一般的寫法都是講初始化代碼放在三個(gè)參數(shù)的構(gòu)造函數(shù)里,其它兩個(gè)構(gòu)造函數(shù)分別繼承自參數(shù)更多的一個(gè)本類的構(gòu)造函數(shù),所以這里用的是this關(guān)鍵字
3.初始化參數(shù)
首先我們需要先在values包的attrs文件中先聲明屬性
<declare-styleable name="PlayPauseView">
<attr name="barWidth" format="dimension"/>
<attr name="barHeight" format="dimension"/>
<attr name="barPadding" format="dimension"/>
<attr name="barColor" format="color"/>
<attr name="barBgColor" format="color"/>
<attr name="barClockWise" format="boolean"/>
<attr name="barPlayingState" format="boolean"/>
</declare-styleable>
然后在構(gòu)造函數(shù)中拿到這些參數(shù)
mBarWidth = typedArray.getDimension(R.styleable.PlayPauseView_barWidth,10 * getDensity())
mBarHeight = typedArray.getDimension(R.styleable.PlayPauseView_barHeight,30 * getDensity())
mPadding = typedArray.getDimension(R.styleable.PlayPauseView_barPadding,10 * getDensity())
//可以通過上面的三個(gè)參數(shù)計(jì)算出下面的參數(shù)值,所以不再通過xml設(shè)置
mBarSpace = mBarHeight - mBarWidth * 2
mRadius = mBarWidth + mBarSpace.div(2) + mPadding
mWidth = mRadius * 2
mWidth = mRadius * 2
mBarWidth 是小矩形的寬度,mBarHeight 是小矩形的高度,mPadding 是小矩形距離整個(gè)view的邊界距離(參考上圖中狀態(tài)1中左邊小矩形距離大矩形的距離,距離top和left應(yīng)該是一樣的,這個(gè)值就是mPadding )。
mBarSpace 是兩個(gè)小矩形之間的距離,mRadius 是狀態(tài)1中圓的半徑,mWidth 、mWidth 是狀態(tài)1中大矩形的寬高。(這些參數(shù)都是通過上面三個(gè)參數(shù)計(jì)算出來的)
同樣的在初始化這一步,初始化畫筆和兩個(gè)小矩形(半三角)Path
mBgPaint = Paint(Paint.ANTI_ALIAS_FLAG)
mBgPaint!!.color = mBgColor
mBgPaint!!.style = Paint.Style.FILL
mBarPaint = Paint(Paint.ANTI_ALIAS_FLAG)
mBarPaint!!.color = mBarColor
mBarPaint!!.style = Paint.Style.FILL
mLeftPath = Path()
mRightPath = Path()
同時(shí)通過動(dòng)畫使矩形變成三角的參數(shù) mProgress,在onDraw中會(huì)用到
4.測量控件
在onMeasure方法中測量控件的寬高,主要是在xml中wrap_content或者具體數(shù)值的時(shí)候
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val measureWidth = MeasureSpec.getSize(widthMeasureSpec)
val measureHeight = MeasureSpec.getSize(heightMeasureSpec)
when(widthMode){
MeasureSpec.EXACTLY ->{
mWidth = Math.min(measureWidth,measureHeight).toFloat()
mHeight = Math.min(measureWidth,measureHeight).toFloat()
setMeasuredDimension(mWidth.toInt(),mHeight.toInt())
}
MeasureSpec.AT_MOST -> {
mWidth = mRadius * 2
mHeight = mRadius * 2
setMeasuredDimension(mWidth.toInt(),mHeight.toInt())
}
MeasureSpec.UNSPECIFIED -> {
}
}
}
5.繪制
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
//需要重新設(shè)置,否則畫出來的圖形會(huì)保留上一次的
mLeftPath!!.rewind()
mRightPath!!.rewind()
mRadius = mWidth.div(2)
//先畫一個(gè)圓
canvas!!.drawCircle(mWidth.div(2),mHeight.div(2),mRadius,mBgPaint)
//核心代碼
//順時(shí)針
if(isClockWise){
mLeftPath!!.moveTo(mPadding + (mBarWidth + mBarSpace.div(2)) * mProgress ,mPadding)
mLeftPath!!.lineTo(mPadding ,mPadding + mBarHeight)
mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding + mBarHeight)
mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding)
mLeftPath!!.close()
mRightPath!!.moveTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding)
mRightPath!!.lineTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding + mBarHeight)
mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace ,mPadding + mBarHeight)
mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace - (mBarWidth + mBarSpace.div(2)) * mProgress,mPadding)
mRightPath!!.close()
}
//逆時(shí)針
else{
mLeftPath!!.moveTo(mPadding,mPadding)
mLeftPath!!.lineTo(mPadding + (mBarWidth + mBarSpace.div(2)) * mProgress,mPadding + mBarHeight)
mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding + mBarHeight)
mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding)
mLeftPath!!.close()
mRightPath!!.moveTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding)
mRightPath!!.lineTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding + mBarHeight)
mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace - (mBarWidth + mBarSpace.div(2)) * mProgress,mPadding + mBarHeight)
mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace,mPadding)
mRightPath!!.close()
}
var corner = 0
if(isClockWise){
corner = 90
}else{
corner = -90
}
val rotation = corner * mProgress
//旋轉(zhuǎn)畫布
canvas.rotate(rotation,mWidth.div(2),mHeight.div(2))
canvas.drawPath(mLeftPath!!,mBarPaint)
canvas.drawPath(mRightPath!!,mBarPaint)
}

通過這張圖來看一下核心代碼(順時(shí)針)
A點(diǎn)的坐標(biāo)(mPadding + (mBarWidth + mBarSpace.div(2)) * mProgress ,mPadding)
mPadding 是小矩形距離大矩形的距離,A點(diǎn)最終會(huì)到F點(diǎn),兩者相差一個(gè)矩形 + 兩個(gè)矩形間隔/2的距離(就是 mBarWidth + mBarSpace.div(2) 的距離),通過乘以一個(gè)從0到1的mProgress的變化即可
同理可得 D到F,B到E,C到E的變化坐標(biāo)
右側(cè)的矩形也是如此計(jì)算,如果是逆時(shí)針旋轉(zhuǎn),三角形是倒過來的,原理也是一樣的
6.動(dòng)畫
上面提到過我們需要一個(gè)從0到1的mProgress的變化(從播放到暫停),或者需要一個(gè)從1到0的mProgress(從暫停到播放)
動(dòng)畫核心代碼如下:
val valueAnimator = ValueAnimator.ofFloat(if (isPlaying) 1f else 0f, if (isPlaying) 0f else 1f)
valueAnimator.duration = 200
valueAnimator.addUpdateListener {
mProgress = it.animatedValue as Float
invalidate()
}
return valueAnimator
mProgress 不斷地變化,然后調(diào)用invalidate(),不斷地調(diào)用onDraw()方法
7.監(jiān)聽
setOnClickListener {
if(isPlaying){
pause()
mPlayPauseListener!!.pause()
}else{
play()
mPlayPauseListener!!.play()
}
}
private fun play() {
getAnimator().cancel()
setPlaying(true)
getAnimator().start()
}
private fun pause() {
getAnimator().cancel()
setPlaying(false)
getAnimator().start()
}
mPlayPauseListener是對外提供的接口,可以在Activity中拿到播放或者暫停的狀態(tài),以供我們下一步的操作
8.使用
最后附上這個(gè)自定義View目前有的屬性:
app:barHeight="30dp"http://矩形條的寬度
app:barWidth="10dp"http://矩形條的高度
app:barPadding="20dp"http://矩形條距離原點(diǎn)(邊界)的距離
app:barClockWise="true"http://是否是順時(shí)針轉(zhuǎn)動(dòng)
app:barPlayingState="false"http://默認(rèn)的狀態(tài),播放或者暫停
app:barBgColor="@color/colorRed"http://控件背景色
app:barColor="@color/black"http://按鈕顏色
在Activity或者Fragment中的使用:
val playPauseView = findViewById<PlayPauseView>(R.id.play_pause_view)
//控件的點(diǎn)擊事件
playPauseView.setPlayPauseListener(this)
//需要實(shí)現(xiàn)的方法
override fun play() {
Toast.makeText(this,"現(xiàn)在處于播放狀態(tài)",Toast.LENGTH_SHORT).show()
}
override fun pause() {
Toast.makeText(this,"現(xiàn)在處于暫停狀態(tài)",Toast.LENGTH_SHORT).show()
}
至此,這個(gè)自定義View大致上完成了,還有一些細(xì)節(jié)就不再這里細(xì)說了。如果你有興趣深入了解,可以看一下這里:自定義View集合中的PlayPauseView,如果能隨手點(diǎn)個(gè)Star也是極好的。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:- Android使用VideoView播放本地視頻和網(wǎng)絡(luò)視頻的方法
- Android使用WebView播放flash的方法
- 解決video標(biāo)簽在安卓webview下無法自動(dòng)播放問題
- 詳解Android App中使用VideoView來實(shí)現(xiàn)視頻播放的方法
- Android自定義播放器控件VideoView
- Android如何讓W(xué)ebView中的HTML5頁面實(shí)現(xiàn)視頻全屏播放
- Android編程實(shí)現(xiàn)WebView全屏播放的方法(附源碼)
- android使用videoview播放視頻
- Android編程使WebView支持HTML5 Video全屏播放的解決方法
相關(guān)文章
-
Android MPAndroidChart開源圖表庫之餅狀圖的代碼
MPAndroidChart是一款基于Android的開源圖表庫,MPAndroidChart不僅可以在Android設(shè)備上繪制各種統(tǒng)計(jì)圖表,而且可以對圖表進(jìn)行拖動(dòng)和縮放操作,應(yīng)用起來非常靈活 2018-05-05
-
Android中自定義的dialog中的EditText無法彈出輸入法解決方案
這篇文章主要介紹了Android中自定義的dialog中的EditText無法彈出輸入法解決方案,需要的朋友可以參考下 2017-04-04
-
Android 使用手機(jī)NFC的讀取NFC標(biāo)簽數(shù)據(jù)的方法
這篇文章主要介紹了Android 使用手機(jī)NFC的讀取NFC標(biāo)簽數(shù)據(jù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧 2018-07-07
-
Android開發(fā)壁紙的驗(yàn)證設(shè)置和確認(rèn)功能實(shí)現(xiàn)demo
android?wallpaper包括鎖屏壁紙和桌面壁紙,壁紙又區(qū)分靜態(tài)和動(dòng)態(tài)兩種。本文詳細(xì)介紹靜態(tài)壁紙?jiān)O(shè)置和確認(rèn),有需要的朋友可以借鑒參考下,希望能夠有所幫助 2022-04-04
-
Android應(yīng)用開發(fā)中RecyclerView組件使用入門教程
這篇文章主要介紹了Android應(yīng)用開發(fā)中RecyclerView組件使用的入門教程,RecyclerView主要針對安卓5.0以上的material design開發(fā)提供支持,需要的朋友可以參考下 2016-02-02
-
Android中Activity和Fragment傳遞數(shù)據(jù)的兩種方式
本篇文章主要介紹了Android中Activity和Fragment傳遞數(shù)據(jù)的兩種方式,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
2017-09-09
最新評論
最近開始深入學(xué)習(xí)自定義View,通過模仿學(xué)習(xí),再配合Kotlin,寫了一些自定義控件,這次介紹的是類似于音樂播放暫停的一個(gè)控件
首先看一下效果圖:
下面先分析一下原理:
狀態(tài)1是播放狀態(tài),有兩個(gè)小矩形,外面是一個(gè)圓,它需要最終變換成狀態(tài)3的暫停狀態(tài)
狀態(tài)2是兩個(gè)小矩形變成如圖的黑色三角的一個(gè)過程
我們可以通過動(dòng)畫來實(shí)現(xiàn)它,兩個(gè)小矩形分別變成三角形的一半
同時(shí)再給畫布一個(gè)90度的旋轉(zhuǎn)
具體實(shí)現(xiàn):
1.繼承View
class PlayPauseView : View
2.重寫構(gòu)造函數(shù)
constructor(context: Context?) : this(context,null) constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs,0) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr){ init(context!!,attrs!!) }
一般的寫法都是講初始化代碼放在三個(gè)參數(shù)的構(gòu)造函數(shù)里,其它兩個(gè)構(gòu)造函數(shù)分別繼承自參數(shù)更多的一個(gè)本類的構(gòu)造函數(shù),所以這里用的是this關(guān)鍵字
3.初始化參數(shù)
首先我們需要先在values包的attrs文件中先聲明屬性
<declare-styleable name="PlayPauseView"> <attr name="barWidth" format="dimension"/> <attr name="barHeight" format="dimension"/> <attr name="barPadding" format="dimension"/> <attr name="barColor" format="color"/> <attr name="barBgColor" format="color"/> <attr name="barClockWise" format="boolean"/> <attr name="barPlayingState" format="boolean"/> </declare-styleable>
然后在構(gòu)造函數(shù)中拿到這些參數(shù)
mBarWidth = typedArray.getDimension(R.styleable.PlayPauseView_barWidth,10 * getDensity()) mBarHeight = typedArray.getDimension(R.styleable.PlayPauseView_barHeight,30 * getDensity()) mPadding = typedArray.getDimension(R.styleable.PlayPauseView_barPadding,10 * getDensity()) //可以通過上面的三個(gè)參數(shù)計(jì)算出下面的參數(shù)值,所以不再通過xml設(shè)置 mBarSpace = mBarHeight - mBarWidth * 2 mRadius = mBarWidth + mBarSpace.div(2) + mPadding mWidth = mRadius * 2 mWidth = mRadius * 2
mBarWidth 是小矩形的寬度,mBarHeight 是小矩形的高度,mPadding 是小矩形距離整個(gè)view的邊界距離(參考上圖中狀態(tài)1中左邊小矩形距離大矩形的距離,距離top和left應(yīng)該是一樣的,這個(gè)值就是mPadding )。
mBarSpace 是兩個(gè)小矩形之間的距離,mRadius 是狀態(tài)1中圓的半徑,mWidth 、mWidth 是狀態(tài)1中大矩形的寬高。(這些參數(shù)都是通過上面三個(gè)參數(shù)計(jì)算出來的)
同樣的在初始化這一步,初始化畫筆和兩個(gè)小矩形(半三角)Path
mBgPaint = Paint(Paint.ANTI_ALIAS_FLAG) mBgPaint!!.color = mBgColor mBgPaint!!.style = Paint.Style.FILL mBarPaint = Paint(Paint.ANTI_ALIAS_FLAG) mBarPaint!!.color = mBarColor mBarPaint!!.style = Paint.Style.FILL mLeftPath = Path() mRightPath = Path()
同時(shí)通過動(dòng)畫使矩形變成三角的參數(shù) mProgress,在onDraw中會(huì)用到
4.測量控件
在onMeasure方法中測量控件的寬高,主要是在xml中wrap_content或者具體數(shù)值的時(shí)候
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) val widthMode = MeasureSpec.getMode(widthMeasureSpec) val heightMode = MeasureSpec.getMode(heightMeasureSpec) val measureWidth = MeasureSpec.getSize(widthMeasureSpec) val measureHeight = MeasureSpec.getSize(heightMeasureSpec) when(widthMode){ MeasureSpec.EXACTLY ->{ mWidth = Math.min(measureWidth,measureHeight).toFloat() mHeight = Math.min(measureWidth,measureHeight).toFloat() setMeasuredDimension(mWidth.toInt(),mHeight.toInt()) } MeasureSpec.AT_MOST -> { mWidth = mRadius * 2 mHeight = mRadius * 2 setMeasuredDimension(mWidth.toInt(),mHeight.toInt()) } MeasureSpec.UNSPECIFIED -> { } } }
5.繪制
override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) //需要重新設(shè)置,否則畫出來的圖形會(huì)保留上一次的 mLeftPath!!.rewind() mRightPath!!.rewind() mRadius = mWidth.div(2) //先畫一個(gè)圓 canvas!!.drawCircle(mWidth.div(2),mHeight.div(2),mRadius,mBgPaint) //核心代碼 //順時(shí)針 if(isClockWise){ mLeftPath!!.moveTo(mPadding + (mBarWidth + mBarSpace.div(2)) * mProgress ,mPadding) mLeftPath!!.lineTo(mPadding ,mPadding + mBarHeight) mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding + mBarHeight) mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding) mLeftPath!!.close() mRightPath!!.moveTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding) mRightPath!!.lineTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding + mBarHeight) mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace ,mPadding + mBarHeight) mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace - (mBarWidth + mBarSpace.div(2)) * mProgress,mPadding) mRightPath!!.close() } //逆時(shí)針 else{ mLeftPath!!.moveTo(mPadding,mPadding) mLeftPath!!.lineTo(mPadding + (mBarWidth + mBarSpace.div(2)) * mProgress,mPadding + mBarHeight) mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding + mBarHeight) mLeftPath!!.lineTo(mPadding + mBarWidth + mBarSpace.div(2) * mProgress,mPadding) mLeftPath!!.close() mRightPath!!.moveTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding) mRightPath!!.lineTo(mPadding + mBarWidth + mBarSpace - mBarSpace.div(2) * mProgress,mPadding + mBarHeight) mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace - (mBarWidth + mBarSpace.div(2)) * mProgress,mPadding + mBarHeight) mRightPath!!.lineTo(mPadding + mBarWidth * 2 + mBarSpace,mPadding) mRightPath!!.close() } var corner = 0 if(isClockWise){ corner = 90 }else{ corner = -90 } val rotation = corner * mProgress //旋轉(zhuǎn)畫布 canvas.rotate(rotation,mWidth.div(2),mHeight.div(2)) canvas.drawPath(mLeftPath!!,mBarPaint) canvas.drawPath(mRightPath!!,mBarPaint) }
通過這張圖來看一下核心代碼(順時(shí)針)
A點(diǎn)的坐標(biāo)(mPadding + (mBarWidth + mBarSpace.div(2)) * mProgress ,mPadding)
mPadding 是小矩形距離大矩形的距離,A點(diǎn)最終會(huì)到F點(diǎn),兩者相差一個(gè)矩形 + 兩個(gè)矩形間隔/2的距離(就是 mBarWidth + mBarSpace.div(2) 的距離),通過乘以一個(gè)從0到1的mProgress的變化即可
同理可得 D到F,B到E,C到E的變化坐標(biāo)
右側(cè)的矩形也是如此計(jì)算,如果是逆時(shí)針旋轉(zhuǎn),三角形是倒過來的,原理也是一樣的
6.動(dòng)畫
上面提到過我們需要一個(gè)從0到1的mProgress的變化(從播放到暫停),或者需要一個(gè)從1到0的mProgress(從暫停到播放)
動(dòng)畫核心代碼如下:
val valueAnimator = ValueAnimator.ofFloat(if (isPlaying) 1f else 0f, if (isPlaying) 0f else 1f) valueAnimator.duration = 200 valueAnimator.addUpdateListener { mProgress = it.animatedValue as Float invalidate() } return valueAnimator
mProgress 不斷地變化,然后調(diào)用invalidate(),不斷地調(diào)用onDraw()方法
7.監(jiān)聽
setOnClickListener { if(isPlaying){ pause() mPlayPauseListener!!.pause() }else{ play() mPlayPauseListener!!.play() } } private fun play() { getAnimator().cancel() setPlaying(true) getAnimator().start() } private fun pause() { getAnimator().cancel() setPlaying(false) getAnimator().start() }
mPlayPauseListener是對外提供的接口,可以在Activity中拿到播放或者暫停的狀態(tài),以供我們下一步的操作
8.使用
最后附上這個(gè)自定義View目前有的屬性:
app:barHeight="30dp"http://矩形條的寬度 app:barWidth="10dp"http://矩形條的高度 app:barPadding="20dp"http://矩形條距離原點(diǎn)(邊界)的距離 app:barClockWise="true"http://是否是順時(shí)針轉(zhuǎn)動(dòng) app:barPlayingState="false"http://默認(rèn)的狀態(tài),播放或者暫停 app:barBgColor="@color/colorRed"http://控件背景色 app:barColor="@color/black"http://按鈕顏色
在Activity或者Fragment中的使用:
val playPauseView = findViewById<PlayPauseView>(R.id.play_pause_view) //控件的點(diǎn)擊事件 playPauseView.setPlayPauseListener(this) //需要實(shí)現(xiàn)的方法 override fun play() { Toast.makeText(this,"現(xiàn)在處于播放狀態(tài)",Toast.LENGTH_SHORT).show() } override fun pause() { Toast.makeText(this,"現(xiàn)在處于暫停狀態(tài)",Toast.LENGTH_SHORT).show() }
至此,這個(gè)自定義View大致上完成了,還有一些細(xì)節(jié)就不再這里細(xì)說了。如果你有興趣深入了解,可以看一下這里:自定義View集合中的PlayPauseView,如果能隨手點(diǎn)個(gè)Star也是極好的。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用VideoView播放本地視頻和網(wǎng)絡(luò)視頻的方法
- Android使用WebView播放flash的方法
- 解決video標(biāo)簽在安卓webview下無法自動(dòng)播放問題
- 詳解Android App中使用VideoView來實(shí)現(xiàn)視頻播放的方法
- Android自定義播放器控件VideoView
- Android如何讓W(xué)ebView中的HTML5頁面實(shí)現(xiàn)視頻全屏播放
- Android編程實(shí)現(xiàn)WebView全屏播放的方法(附源碼)
- android使用videoview播放視頻
- Android編程使WebView支持HTML5 Video全屏播放的解決方法
相關(guān)文章
Android MPAndroidChart開源圖表庫之餅狀圖的代碼
MPAndroidChart是一款基于Android的開源圖表庫,MPAndroidChart不僅可以在Android設(shè)備上繪制各種統(tǒng)計(jì)圖表,而且可以對圖表進(jìn)行拖動(dòng)和縮放操作,應(yīng)用起來非常靈活2018-05-05Android中自定義的dialog中的EditText無法彈出輸入法解決方案
這篇文章主要介紹了Android中自定義的dialog中的EditText無法彈出輸入法解決方案,需要的朋友可以參考下2017-04-04Android 使用手機(jī)NFC的讀取NFC標(biāo)簽數(shù)據(jù)的方法
這篇文章主要介紹了Android 使用手機(jī)NFC的讀取NFC標(biāo)簽數(shù)據(jù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07Android開發(fā)壁紙的驗(yàn)證設(shè)置和確認(rèn)功能實(shí)現(xiàn)demo
android?wallpaper包括鎖屏壁紙和桌面壁紙,壁紙又區(qū)分靜態(tài)和動(dòng)態(tài)兩種。本文詳細(xì)介紹靜態(tài)壁紙?jiān)O(shè)置和確認(rèn),有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-04-04Android應(yīng)用開發(fā)中RecyclerView組件使用入門教程
這篇文章主要介紹了Android應(yīng)用開發(fā)中RecyclerView組件使用的入門教程,RecyclerView主要針對安卓5.0以上的material design開發(fā)提供支持,需要的朋友可以參考下2016-02-02Android中Activity和Fragment傳遞數(shù)據(jù)的兩種方式
本篇文章主要介紹了Android中Activity和Fragment傳遞數(shù)據(jù)的兩種方式,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09