You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
import android.graphics.drawable.BitmapDrawable
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.support.v4.view.ViewCompat
import android.util.Log
import android.view.View
import com.mrwang.imageframe.BitmapLoadUtils
import com.mrwang.imageframe.ImageCache
import java.lang.ref.SoftReference
/**
* Created by young on 2018/2/8.
*/
class FrameAnim {
companion object {
fun create(): FrameAnim {
return FrameAnim()
}
}
interface AnimEndCallBack{
fun onAnimEnd()
}
interface AnimLoopedCallBack{
fun onAnimLooped(loopedCount:Int)
}
/**
* 遥控器
*/
interface Controller {
fun start()
fun isPaused(): Boolean
fun pause()
fun resume()
fun destroy()
}
private inner class ControllerImpl(val ext: FrameAnim) : Controller {
override fun start() {
ext.start()
}
override fun destroy() {
ext.destroy()
}
override fun isPaused(): Boolean {
return ext.paused
}
override fun pause() {
ext.pause()
}
override fun resume() {
ext.resume()
}
}
private val TAG = javaClass.simpleName
private var target: View? = null
private var list: List<Int>? = null
private var duration: Long = 300
private var index = 0
private val decodeThread = DecodeThread()
private var decodeHandler: Handler? = null
private val uiHandler = Handler(Looper.getMainLooper())
private var bitmapDrawable: BitmapDrawable? = null
private var isInitLoad = true
private var loop = true
private var loopedCount = 0
private var paused = false
private var destroyed = false
private val controller: Controller = ControllerImpl(this)
private var animEndCallBack:AnimEndCallBack? = null
private var animLoopedCallBack:AnimLoopedCallBack? = null
private val autoDestroy:IAutoDestroy = object : IAutoDestroy {
override fun autoDestroy() {
destroy()
}
}
fun target(target: View): FrameAnim {
this.target = target
return this
}
fun resources(list: List<Int>): FrameAnim {
this.list = list
return this
}
fun duration(duration: Long): FrameAnim {
this.duration = duration
return this
}
fun loop(lp: Boolean): FrameAnim {
this.loop = lp
return this
}
fun callBackForAnimEnd(endCallBack: AnimEndCallBack): FrameAnim {
this.animEndCallBack = endCallBack
return this
}
fun callBackForAnimLooped(loopedCallBack: AnimLoopedCallBack): FrameAnim {
this.animLoopedCallBack = loopedCallBack
return this
}
fun controller():Controller{
return controller
}
fun start(): Controller {
if (target == null) {
Log.w(TAG, "The target is Null")
throw IllegalArgumentException("The target must not be Null")
}
if (list == null || list!!.isEmpty()) {
Log.w(TAG, "The resources is Empty")
throw IllegalArgumentException("The resources must not be Null or Empty")
}
val ctx = target!!.context
ctx.registerAutoDestroy(autoDestroy)
if (decodeHandler!=null){
Log.e(TAG, "Task already started")
return controller
}
if (paused) {
Log.e(TAG, "Task is paused, Please use resume() to continue")
return controller
}
decodeThread.start()
if (decodeHandler == null) {
decodeHandler = Handler(decodeThread.looper)
}
load()
return controller
}
private fun pause() {
if (decodeHandler == null) {
throw IllegalStateException("Have u forgot to invoke the ``fun start()``")
}
paused = true
decodeHandler!!.removeCallbacksAndMessages(null)
uiHandler.removeCallbacksAndMessages(null)
}
private fun resume() {
if (decodeHandler == null) {
throw IllegalStateException("Have u forgot to invoke the ``fun start()``")
}
paused = false
load()
}
fun destroy() {
if (destroyed){
return
}
destroyed = true
decodeThread.quit()
uiHandler.removeCallbacks(uiCallBack)
println("Component has destroyed")
}
private var uiCallBack: Runnable? = null
private val imageCache = ImageCache()
private fun load() {
val resources = list!!
if (index >= resources.size && loop) {
index = 0
loopedCount++
animLoopedCallBack?.onAnimLooped(loopedCount)
} else if (index >= resources.size && !loop) {
Log.d(TAG, "The End")
println("The End")
animEndCallBack?.onAnimEnd()
return
}
if (bitmapDrawable != null) {
imageCache.mReusableBitmaps.add(SoftReference(bitmapDrawable!!.bitmap))
}
val resId = resources[index]
decodeHandler!!.post {
val start = System.currentTimeMillis()
val resource = target!!.resources
bitmapDrawable = BitmapLoadUtils.decodeSampledBitmapFromRes(resource, resId, 0,
0,
imageCache, true)
val end = System.currentTimeMillis()
val decodeConsuming = end - start
val delay = duration - decodeConsuming
val actDelay = if (delay > 0) delay else 0
val finalDelay = if (isInitLoad) 0 else actDelay
isInitLoad = false
uiCallBack = Runnable {
ViewCompat.setBackground(target, bitmapDrawable)
index++
load()
}
uiHandler.postDelayed(uiCallBack, finalDelay)
}
}
inner class DecodeThread : HandlerThread("DecodeThread")
}
自动处理生命周期:
interface IAutoDestroy {
fun autoDestroy()
}
class LifeFragment : Fragment() {
private val set: MutableSet<IAutoDestroy> = mutableSetOf()
fun register(autoDestroy: IAutoDestroy) {
set.add(autoDestroy)
}
override fun onDestroy() {
super.onDestroy()
for (autoDestroy in set) {
autoDestroy.autoDestroy()
}
}
}
fun Context.registerAutoDestroy(autoDestroy: IAutoDestroy) {
if (this is FragmentActivity) {
var exist = supportFragmentManager.findFragmentByTag("Hello")
if (exist == null) {
exist = LifeFragment()
supportFragmentManager.beginTransaction().add(exist, "Hello").commit()
}
if (exist is LifeFragment) {
exist.register(autoDestroy)
}
}else {
Log.e("registerAutoDestroy", "The context type do not support fragment")
}
}
The text was updated successfully, but these errors were encountered:
用Kotlin实现的另外一种方式的思路。看一下是否有参考价值
用法:
主要功能类如下:
自动处理生命周期:
The text was updated successfully, but these errors were encountered: