定制化根布局(Kotlin實(shí)現(xiàn))

最近在整理項(xiàng)目里面的東西填硕,在項(xiàng)目中麦萤,我們?cè)诩虞d本地或者網(wǎng)絡(luò)數(shù)據(jù)的時(shí)候鹿鳖,會(huì)存在請(qǐng)求錯(cuò)誤,數(shù)據(jù)為空壮莹,沒(méi)有網(wǎng)絡(luò)等情況翅帜,因此我們的界面需要根據(jù)這些情況給用戶作出相應(yīng)的反饋,因此命满,下面我們就來(lái)封裝這樣的一個(gè)布局(它繼承自ConstraintLayout來(lái)實(shí)現(xiàn))

    private var mContext: Context? = null
    //提示信息
    private var mTipTextView: TextView? = null
    //提示圖標(biāo)
    private var mTipImageView: ImageView? = null

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

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        mContext = context
    }

首先涝滴,先定義作為提示信息的TextView和作為提示圖表的ImageView,在構(gòu)造方法里獲取到上下文對(duì)象

/**
 * 當(dāng)布局加載完畢
 */
override fun onFinishInflate() {
    super.onFinishInflate()
    //如果沒(méi)有在布局中設(shè)置id胶台,則在這里提供磨人設(shè)置
    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)
}

上面的代碼中歼疮,我們?cè)趏nFinishInflate()回調(diào)方法中作處理,因?yàn)樵谶@個(gè)時(shí)候诈唬,xml文件已經(jīng)轉(zhuǎn)換完畢韩脏,我們可以向布局中添加View了,在該方法中铸磅,首先赡矢,我們要判斷布局中是否設(shè)置了id,因?yàn)槲覀兪抢^承ConstraintLayout來(lái)實(shí)現(xiàn)的愚屁,所以我們要依靠布局的id來(lái)對(duì)添加的View進(jìn)行約束济竹,接著就是調(diào)用init()方法進(jìn)行初始化,在init()方法中添加兩個(gè)View霎槐,一個(gè)作為提示信息的TextView送浊,一個(gè)是作為提示圖標(biāo)的ImageView,同時(shí)將它們固定在布局的中心,現(xiàn)在View在布局中的位置已經(jīng)固定了丘跌,那么接下來(lái)我們就需要處理它們?cè)诓煌闆r下的顯示袭景,首先看下面這個(gè)方法

private fun hide() {
    //獲取組件數(shù)量
    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++;
    }
}

上面的方法的主要作用在于在需要顯示沒(méi)有網(wǎng)絡(luò)、數(shù)據(jù)為空或者請(qǐng)求錯(cuò)誤時(shí)闭树,在布局中的其它控件是不應(yīng)該出現(xiàn)的耸棒,所以我們根據(jù)id來(lái)留下作為提示信息的TextView和作為提示圖標(biāo)的ImageView,其它在這個(gè)布局中的子控件全部隱藏报辱,接下來(lái)就是根據(jù)不同的情況做出不同的顯示与殃,代碼如下:

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

/**
 * 重載方法(顯示錯(cuò)誤信息)
 */
public fun showError(errorMsg: String) {
    hide()
    mTipImageView?.setImageResource(mConfig.errorImgId)
    mTipTextView?.text = errorMsg
}

/**
 * 重載方法(顯示錯(cuò)誤信息)
 */
public fun showError(imgId: Int, errorMsg: String) {
    hide()
    mTipImageView?.setImageResource(imgId)
    mTipTextView?.text = errorMsg
}

/**
 * 沒(méi)有數(shù)據(jù)時(shí)顯示
 */
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
}

/**
 * 沒(méi)有網(wǎng)絡(luò)時(shí)顯示
 */
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
}

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

/**
 * 設(shè)置字體顏色
 */
public fun setTextColor(color: Int): RootLayout {
    mTipTextView?.setTextColor(color)
    return this
}

上面分別是請(qǐng)求錯(cuò)誤,數(shù)據(jù)為空碍现,沒(méi)有網(wǎng)絡(luò)時(shí)調(diào)用的方法幅疼,除此以外還有設(shè)置字體大小和顏色的方法,使用的Builder模式昼接,所以我們可以鏈?zhǔn)秸{(diào)用爽篷,到這里基本已經(jīng)完成了大部分的功能,應(yīng)該很簡(jiǎn)單吧慢睡,最后就是我們的配置類(lèi)逐工,配置類(lèi)的作用是能夠做更統(tǒng)一的設(shè)置铡溪,在Application中就可以對(duì)其進(jìn)行設(shè)置,下面是詳細(xì)代碼:

companion object {

    private val mConfig = Config()

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

    class Config {

        var errorMsg: String = "請(qǐng)求錯(cuò)誤"
            private set
        var emptyMsg = "數(shù)據(jù)為空"
            private set
        var networkMsg = "無(wú)法鏈接網(wǎng)絡(luò)"
            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
        }

    }
}

上面是對(duì)作為提示信息的TextView和作為提示圖標(biāo)的ImageView的配置泪喊,我們可以設(shè)置TextView的字體顏色棕硫,大小,可以設(shè)置在數(shù)據(jù)為空窘俺,沒(méi)有網(wǎng)絡(luò)饲帅,請(qǐng)求錯(cuò)誤這三種情況時(shí)的顯示圖標(biāo),到這里瘤泪,就是這個(gè)布局全部的代碼灶泵,應(yīng)該比較簡(jiǎn)單,這是作為項(xiàng)目整理的一個(gè)記錄对途,下面是效果圖

image

image

image

源碼地址:https://github.com/chenTovae/Widget/blob/master/app/src/main/java/com/chenh/customview/view/RootLayout.kt

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赦邻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子实檀,更是在濱河造成了極大的恐慌惶洲,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膳犹,死亡現(xiàn)場(chǎng)離奇詭異恬吕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)须床,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)铐料,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人豺旬,你說(shuō)我怎么就攤上這事钠惩。” “怎么了族阅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵篓跛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我坦刀,道長(zhǎng)愧沟,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任鲤遥,我火速辦了婚禮央渣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渴频。我一直安慰自己,他們只是感情好北启,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布卜朗。 她就那樣靜靜地躺著拔第,像睡著了一般。 火紅的嫁衣襯著肌膚如雪场钉。 梳的紋絲不亂的頭發(fā)上蚊俺,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音逛万,去河邊找鬼泳猬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宇植,可吹牛的內(nèi)容都是我干的得封。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼指郁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忙上!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起闲坎,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤疫粥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后腰懂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體梗逮,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年绣溜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了慷彤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涮毫,死狀恐怖瞬欧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情罢防,我是刑警寧澤艘虎,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站咒吐,受9級(jí)特大地震影響野建,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恬叹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一候生、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绽昼,春花似錦唯鸭、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)明肮。三九已至,卻和暖如春缭付,著一層夾襖步出監(jiān)牢的瞬間柿估,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工陷猫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秫舌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓绣檬,卻偏偏與公主長(zhǎng)得像足陨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子河咽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,280評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程钠右,因...
    小菜c閱讀 6,444評(píng)論 0 17
  • 每張照片背后都是一個(gè)故事飒房,攝影可以說(shuō)是對(duì)某一瞬間故事的記錄,時(shí)間在這一刻凝固媚值,每一個(gè)時(shí)刻狠毯,每一張照片,都代表了我們...
    劉黑黑閱讀 7,035評(píng)論 63 450
  • 這次VR體驗(yàn)的陰差陽(yáng)錯(cuò)褥芒,西安之行嚼松,我似乎夢(mèng)見(jiàn)過(guò),作為大藍(lán)夜锰扶,夢(mèng)見(jiàn)也是不奇怪的吧献酗,嗯~ 其實(shí)對(duì)VR體驗(yàn),并沒(méi)...
    神奇少女空寶貝閱讀 486評(píng)論 2 1
  • ——為表達(dá)對(duì)阿西莫夫的敬意以一個(gè)讀者的身份所做的拙劣的續(xù)寫(xiě) 第一章——第三個(gè)公設(shè) 會(huì)晤 葛蘭?崔維茲靜靜地望著舷窗...
    樹(shù)欲靜閱讀 1,482評(píng)論 0 3