Android-5 Kotlin实现Loading

作者: 知小酌 | 来源:发表于2016-12-25 20:40 被阅读998次

之前文章是使用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

LoadingDialog的代码详见:https://github.com/vslimit/kotlindemo

相关文章

网友评论

    本文标题:Android-5 Kotlin实现Loading

    本文链接:https://www.haomeiwen.com/subject/pbjrvttx.html