定製化根佈局(Kotlin實現)

chenToV發表於2017-10-10

最近在整理專案裡面的東西,在專案中,我們在載入本地或者網路資料的時候,會存在請求錯誤,資料為空,沒有網路等情況,因此我們的介面需要根據這些情況給使用者作出相應的反饋,因此,下面我們就來封裝這樣的一個佈局(它繼承自ConstraintLayout來實現)

    private var mContext: Context? = null
    //提示資訊
    private var mTipTextView: TextView? = null
    //提示圖示
    private var mTipImageView: ImageView? = null

    constructor(context: Context) : super(context) {
        mContext = context
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        mContext = context
    }複製程式碼

首先,先定義作為提示資訊的TextView和作為提示圖表的ImageView,在構造方法裡獲取到上下文物件

/**
 * 當佈局載入完畢
 */
override fun onFinishInflate() {
    super.onFinishInflate()
    //如果沒有在佈局中設定id,則在這裡提供磨人設定
    if (id == -1) {
        id = R.id.root_layout
    }
    //初始化
    init()
}

/**
 * 初始化
 */
private fun init() {
    mTipImageView = ImageView(mContext)
    mTipImageView?.id = R.id.tip_imageview
    mTipImageView?.scaleType = ImageView.ScaleType.CENTER_CROP
    mTipImageView?.visibility = View.VISIBLE
    val lpImg = ConstraintLayout.LayoutParams(
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40F, mContext?.resources?.displayMetrics).toInt(),
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40F, mContext?.resources?.displayMetrics).toInt())
    lpImg.leftToLeft = id
    lpImg.rightToRight = id
    lpImg.topToTop = id
    lpImg.bottomToBottom = id

    mTipTextView = TextView(mContext)
    mTipTextView?.id = R.id.tip_textview
    mTipTextView?.textSize = mConfig.txtSize
    mTipTextView?.setTextColor(mConfig.txtColor)
    val lpTxt = ConstraintLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
    lpTxt.topToBottom = mTipImageView?.id!!
    lpTxt.leftToLeft = id
    lpTxt.rightToRight = id
    lpTxt.topMargin = 10

    addView(mTipImageView, lpImg)
    addView(mTipTextView, lpTxt)
}複製程式碼

上面的程式碼中,我們在onFinishInflate()回撥方法中作處理,因為在這個時候,xml檔案已經轉換完畢,我們可以向佈局中新增View了,在該方法中,首先,我們要判斷佈局中是否設定了id,因為我們是繼承ConstraintLayout來實現的,所以我們要依靠佈局的id來對新增的View進行約束,接著就是呼叫init()方法進行初始化,在init()方法中新增兩個View,一個作為提示資訊的TextView,一個是作為提示圖示的ImageView,同時將它們固定在佈局的中心,現在View在佈局中的位置已經固定了,那麼接下來我們就需要處理它們在不同情況下的顯示,首先看下面這個方法

private fun hide() {
    //獲取元件數量
    val childCount = childCount
    var i = 0;
    while (i < childCount) {
        if ((getChildAt(i).id != mTipImageView?.id) && (getChildAt(i).id != mTipTextView?.id)) {
            getChildAt(i).visibility = View.GONE
        }
        i++;
    }
}複製程式碼

上面的方法的主要作用在於在需要顯示沒有網路、資料為空或者請求錯誤時,在佈局中的其它控制元件是不應該出現的,所以我們根據id來留下作為提示資訊的TextView和作為提示圖示的ImageView,其它在這個佈局中的子控制元件全部隱藏,接下來就是根據不同的情況做出不同的顯示,程式碼如下:

/**
 * 顯示錯誤資訊
 */
public fun showError() {
    hide()
    mTipImageView?.setImageResource(mConfig.errorImgId)
    mTipTextView?.text = mConfig.errorMsg
}

/**
 * 過載方法(顯示錯誤資訊)
 */
public fun showError(errorMsg: String) {
    hide()
    mTipImageView?.setImageResource(mConfig.errorImgId)
    mTipTextView?.text = errorMsg
}

/**
 * 過載方法(顯示錯誤資訊)
 */
public fun showError(imgId: Int, errorMsg: String) {
    hide()
    mTipImageView?.setImageResource(imgId)
    mTipTextView?.text = errorMsg
}

/**
 * 沒有資料時顯示
 */
public fun showEmpty() {
    hide()
    mTipImageView?.setImageResource(mConfig.emptyImgId)
    mTipTextView?.text = mConfig.emptyMsg
}

public fun showEmpty(emptyMsg: String) {
    hide()
    mTipImageView?.setImageResource(mConfig.emptyImgId)
    mTipTextView?.text = emptyMsg
}

public fun showEmpty(imgId: Int, emptyMsg: String) {
    hide()
    mTipImageView?.setImageResource(imgId)
    mTipTextView?.text = emptyMsg
}

/**
 * 沒有網路時顯示
 */
public fun showNetwork() {
    hide()
    mTipImageView?.setImageResource(mConfig.networkImgId)
    mTipTextView?.text = mConfig.networkMsg
}

public fun showNetwork(metworkMsg: String) {
    hide()
    mTipImageView?.setImageResource(mConfig.networkImgId)
    mTipTextView?.text = metworkMsg
}

public fun showNetwork(imgId: Int, metworkMsg: String) {
    hide()
    mTipImageView?.setImageResource(imgId)
    mTipTextView?.text = metworkMsg
}

/**
 * 設定字型大小
 */
public fun setTextSize(value: Float): RootLayout {
    mTipTextView?.textSize = value
    return this
}

/**
 * 設定字型顏色
 */
public fun setTextColor(color: Int): RootLayout {
    mTipTextView?.setTextColor(color)
    return this
}複製程式碼

上面分別是請求錯誤,資料為空,沒有網路時呼叫的方法,除此以外還有設定字型大小和顏色的方法,使用的Builder模式,所以我們可以鏈式呼叫,到這裡基本已經完成了大部分的功能,應該很簡單吧,最後就是我們的配置類,配置類的作用是能夠做更統一的設定,在Application中就可以對其進行設定,下面是詳細程式碼:

companion object {

    private val mConfig = Config()

    /**
     * 獲取配置類
     */
    public fun getConfig(): Config = mConfig

    class Config {

        var errorMsg: String = "請求錯誤"
            private set
        var emptyMsg = "資料為空"
            private set
        var networkMsg = "無法連結網路"
            private set
        var errorImgId = R.mipmap.error
            private set
        var emptyImgId = R.mipmap.empty
            private set
        var networkImgId = R.mipmap.no_network
            private set
        var txtSize = 14F
            private set
        var txtColor = Color.parseColor("#999999")                      private set

        public fun setTextSize(value: Float): Config {
            txtSize = value
            return this
        }

        public fun setTextColor(color: Int): Config {
            txtColor = color
            return this
        }

        public fun setErrorTipMsg(errorMsg: String): Config {
            this.errorMsg = errorMsg
            return this
        }

        public fun setEmptyTipMsg(emptyMsg: String): Config {
            this.emptyMsg = emptyMsg
            return this
        }

        public fun setNetworkTipMsg(networkMsg: String): Config {
            this.networkMsg = networkMsg
            return this
        }

        public fun setErrorTipIcon(iconId: Int): Config {
            errorImgId = iconId
            return this
        }

        public fun setEmptyTipIcon(iconId: Int): Config {
            emptyImgId = iconId
            return this
        }

        public fun setNetworkTipIcon(iconId: Int): Config {
            networkImgId = iconId
            return this
        }

    }
}複製程式碼

上面是對作為提示資訊的TextView和作為提示圖示的ImageView的配置,我們可以設定TextView的字型顏色,大小,可以設定在資料為空,沒有網路,請求錯誤這三種情況時的顯示圖示,到這裡,就是這個佈局全部的程式碼,應該比較簡單,這是作為專案整理的一個記錄,下面是效果圖



原始碼地址:github.com/chenTovae/W…

相關文章