Android5 Kotlin實現Loading

之前文章是使用 Toast 來替代網絡請求時加載的 Loading ,本文就自定義實現一個簡單的 Loading ,當然了,第三方開源庫里有很多漂亮的加載庫,我這只能算是拋磚引玉:

Loading的實現:

Loading 1.0

網上流傳的 Loading ,大都使用的 TweenRotateAnimation ,以前的項目中我也是參照網上Demo實現的,這里貼出 LoadingDialog 動畫實現代碼:

LoadingDialog:

private void initAnim() {
        mAnim = new RotateAnimation(0, 360, Animation.RESTART, 0.5f, Animation.RESTART, 0.5f);
        mAnim.setDuration(2000);
        mAnim.setRepeatCount(Animation.INFINITE);
        mAnim.setRepeatMode(Animation.RESTART);
        mAnim.setStartTime(Animation.START_ON_FIRST_FRAME);
    }


    @Override
    public void show() {//在要用到的地方調用這個方法
        iv_route.startAnimation(mAnim);
//        handler.sendEmptyMessage(CHANGE_TITLE_WHAT);
        super.show();
    }


    @Override
    public void dismiss() {
        mAnim.cancel();
        super.dismiss();
    }

當然了,這樣做能夠達到效果,但是,最近在看屬性動畫,于是在新的版本中,使用了 Property Animator 來實現,并使用 Kotlin 的特性,對 ActivityFragment 進行了擴展,方便調用,下面我們來看 Loading2.0

Loading2.0

首先讓我們來看看布局文件 loading_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent"
        android:orientation="vertical">
    <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@mipmap/bd"
            android:gravity="center">
        <ImageView
                android:id="@+id/imgIv"
                android:layout_gravity="center_horizontal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:src="@mipmap/progress_round"/>
    </RelativeLayout>
</LinearLayout>

Const定義了兩個常量

package com.vslimit.kotlindemo.util

/**
 * Created by vslimit on 16/12/24.
 */
class Const {
    companion object {
        val SHOW = 1
        val HIDE = 0
    }
}

現在定義 LoadingDialog 的樣式

<style name="CustomDialog" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
    </style>
    <style name="CustomProgressDialog" parent="@style/CustomDialog">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowNoTitle">true</item>
    </style>

實現自定義 LoadingDialog

package com.vslimit.kotlindemo.ui

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.app.Dialog
import android.content.Context
import android.widget.ImageView
import com.vslimit.kotlindemo.R

/**
 * Created by vslimit on 16/12/24.
 */
class LoadingDialog(context: Context) : Dialog(context, R.style.CustomProgressDialog) {

    private var imgIv: ImageView? = null

    init {
        setContentView(R.layout.loading_dialog)
        imgIv = findViewById(R.id.imgIv) as ImageView
    }

    private fun initAnim() {
        val animator = ObjectAnimator.ofFloat(imgIv, "rotation", 0f, 359f)
        animator.repeatCount = ValueAnimator.INFINITE
        animator.repeatMode = ValueAnimator.REVERSE
        animator.duration = 2000
        animator.start()
    }

    override fun show() {//在要用到的地方調用這個方法
        super.show()
        initAnim()
    }

    override fun dismiss() {
        super.dismiss()
    }

}

至此, LoadingDialog 已經實現,下面我們來看看在 ActivityFragment 是如何調用的:

BaseActivity 中定義 loadingDialog 并初始化:

var loadingDialog: LoadingDialog? = null

    open var handler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            //定義一個Handler,用于處理下載線程與UI間通訊
            if (!Thread.currentThread().isInterrupted) {
                when (msg.what) {
                    Const.SHOW -> loadingDialog!!.show()//顯示進度對話框
                    Const.HIDE -> loadingDialog!!.hide()//隱藏進度對話框,不可使用dismiss()、cancel(),否則再次調用show()時,顯示的對話框小圓圈不會動。
                }
            }
            super.handleMessage(msg)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(layoutResourceId)
        loadingDialog = LoadingDialog(this)
    }

在包 extensions 中實現 ActivityExtentions.ktFragmentExtentions.kt ,代碼如下:

ActivityExtentions.kt

package com.vslimit.kotlindemo.extensions

import com.vslimit.kotlindemo.activity.BaseActivity

/**
 * Created by vslimit on 16/12/24.
 */

fun BaseActivity.loading(msg: Int) = handler.sendEmptyMessage(msg)

FragmentExtentions.kt

package com.vslimit.kotlindemo.extensions

import com.vslimit.kotlindemo.activity.BaseActivity
import com.vslimit.kotlindemo.fragment.BaseFragment
import org.jetbrains.anko.support.v4.act

/**
 * Created by vslimit on 16/12/24.
 */

fun BaseFragment.loading(msg: Int) = (act as BaseActivity).loading(msg)

那么在 ActivityFragment 中就可以直接使用 loading(Const.SHOW)loading(Const.HIDE) 來加載和隱藏 loading

下面是在 VolleyFragment 中的應用:

fun init() {
        if (NetworkUtil.isNetwork(act)) {
            val listener = Listener<IPResult> { e, r ->
                e?.let { Bus.post(BaseEvent<IPResult>(error = e)) }
                r?.let { Bus.post(BaseEvent(response = r)) }
            }
            val url = "http://ip.taobao.com/service/getIpInfo.php?ip=63.223.108.42"
            Log.d("Url:::", "")
            App.queue!!.add(listener, url)
            //post 調用
            //App.queue!!.post(listener, url, hashMapOf("aaa" to "aaa", "bbb" to "bbb"))
            loading(Const.SHOW)
        } else {
            alert("網絡錯誤", "網絡未連接,請檢查網絡")
        }
    }

    fun onEventMainThread(event: BaseEvent<IPResult>) {
        val error = event.error
        result = event.response
        loading(Const.HIDE)
        if (error != null) {
            toast(error.toString(resources))
        } else {
            if (result!!.code == Result.SUCCESS) {
                async() {
                    uiThread {
                        resultTv.text = result!!.data!!.country
                    }
                }
            } else {
                toast(result!!.code)
            }
        }
    }

基于Kotlin的 LoadingDialog 的已經實現,當然了,如果想美化,可以進一步完善,效果如圖:

LoadingDialog.jpg

 

來自:http://www.jianshu.com/p/ce1e5edc5915

 

 本文由用戶 khwb3940 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!