Android筆記--自定義View之組合控件

Android-自定義View

分享是最好的記憶--
如需轉(zhuǎn)發(fā)請(qǐng)注明出處

[強(qiáng)調(diào)]:共同學(xué)習(xí) 共同進(jìn)步 不喜勿噴

內(nèi)容簡(jiǎn)介


  1. 前言
  2. 實(shí)現(xiàn)
  3. 總結(jié)

1. 前言


這次更新有2個(gè)目的
1. 復(fù)用控件,而不是每次都寫(xiě)冗余代碼
2. 好久沒(méi)有更新了(?? . ??)

在Android開(kāi)發(fā)當(dāng)中自定義View是一項(xiàng)不可或缺的技能碍遍,也是我們大部分小白以及小小白的軟肋轩勘。
??自定義View其實(shí)也不是很難斩箫,因?yàn)槲覀儾恍枰タ耸裁醇夹g(shù)難關(guān),只需要坐在巨人的肩膀上和簸,抱緊巨人的腦袋就行(?>ω<*?)
??自定義View分兩大類:
一 : 組合 : 也就是在現(xiàn)有的控件基礎(chǔ)上通過(guò)組合各種不同功能的控件來(lái)組合出功能更強(qiáng)大全民的新控件。
二 : 完全自定義:通過(guò)繼承View或者ViewGroup來(lái)自定義全新的View。??今天討論的自定義View是第一種方式届巩,即組合方式。如果想了解完全自定義或者更多自定義方面的知識(shí)份乒,推薦看扔物線大神以及張鴻翔大神的文章恕汇。

2. 實(shí)現(xiàn)


1. 確定需求

??功能列表中的Item是我們經(jīng)常用到的控件之一腕唧。它也許是這樣的:
item1.png

或者是這樣的:
item2.png

再或者是這樣的:
item3.png

??為了滿足這些情況,我們抽象出功能最豐富的Item瘾英;確定了需求之后開(kāi)始編碼枣接。

2. 編碼

1. 自定義屬性
??首先確定我們需要?jiǎng)討B(tài)設(shè)置的屬性;包括 :1-左邊圖片缺谴,2-3-左邊圖片的寬高但惶,4-大標(biāo)題5-大標(biāo)題文字大小湿蛔,6-大標(biāo)題文字顏色榆骚,7-副標(biāo)題8-副標(biāo)題文字大小煌集,9-副標(biāo)題文字顏色妓肢,10-右邊圖片11-12-右邊圖片寬高等12個(gè)屬性苫纤,當(dāng)然不止這些碉钠,這個(gè)可以根據(jù)自己的需求豐富,比如 Item 下面是否顯示陰影線條卷拘,右邊圖片是否顯示等喊废;
??那么在../res/attrs.xml中定義自定義屬性;

<declare-styleable name="UILibraryListItem">
        <attr name="leftImg" format="reference"/>
        <attr name="leftImg_width" format="dimension"/>
        <attr name="leftImg_height" format="dimension"/>
        <attr name="rightImg" format="reference"/>
        <attr name="rightImg_width" format="dimension"/>
        <attr name="rightImg_height" format="dimension"/>
        <attr name="title" format="string"/>
        <attr name="title_color" format="color"/>
        <attr name="title_size" format="dimension"/>
        <attr name="subTitle" format="string"/>
        <attr name="subTitle_color" format="color"/>
        <attr name="subTitle_size" format="dimension"/>
</declare-styleable>

這里有必要解釋一下屬性定義中的format

name format 描述
資源 reference 通過(guò)id來(lái)指定資源
顏色 color 設(shè)置顏色
尺寸 dimension 長(zhǎng)寬栗弟,字體大小等尺寸
字符串 String 設(shè)置文本
布爾值 boolean 通過(guò)布爾值設(shè)置
浮點(diǎn)值 float 設(shè)置浮點(diǎn)值
百分?jǐn)?shù) fraction 設(shè)置百分?jǐn)?shù)值
枚舉值 enum 設(shè)置枚舉值
位或運(yùn)算 flag 位或運(yùn)算
整型值 integer 設(shè)置整型

屬性定義時(shí)可以指定多種類型值

2.抽象組建
??這里說(shuō)的抽象組建是把該Item可能有的所有功能都寫(xiě)出來(lái)污筷;
../res/layout/item.xml中寫(xiě)出包含組建所有功能的樣式;

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        style="@style/UILibraryListItemBase"
        android:id="@+id/leftImg"
        android:layout_alignParentLeft="true"
        android:padding="8dp"
        />
    <TextView
        style="@style/UILibraryListItemBase"
        android:id="@+id/title"
        android:layout_toRightOf="@+id/leftImg"
        />
    <TextView
        style="@style/UILibraryListItemBase"
        android:id="@+id/subTitle"
        android:layout_toLeftOf="@+id/rightImg"
        android:layout_toRightOf="@+id/title"
        android:gravity="right"
        />
    <ImageView
        style="@style/UILibraryListItemBase"
        android:id="@+id/rightImg"
        android:layout_alignParentRight="true"
        android:padding="8dp"
        />
    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_alignBottom="@+id/leftImg"
        />
</RelativeLayout>

3.實(shí)現(xiàn)功能
選擇一個(gè)適當(dāng)?shù)腣iewGroup來(lái)繼承乍赫,實(shí)現(xiàn)Item;
我的樣式中rootView是個(gè)RelativeLayout瓣蛀,因此我繼承了RelativeLayout。具體實(shí)現(xiàn)如下:

package com.uilib.ui.listitem;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.uilibrary.R;
import com.uilib.ui.util.FindView;

/**
 * Created by Elyar.Anwar on 2017/8/10.
 */

public class UILibraryListItem extends RelativeLayout {

    /**
     * 選項(xiàng)控件的左邊圖片
     */
    private ImageView leftImageView;

    /**
     * 選項(xiàng)控件的右邊圖片
     */
    private ImageView rightImageView;

    /**
     * 選項(xiàng)控件的標(biāo)題
     */
    private TextView titleView;

    /**
     * 選項(xiàng)控件的副標(biāo)題
     */
    private TextView subTitleView;

    /**
     * 左邊圖片資源
     */
    private Drawable leftImage;

    /**
     * 左邊圖片資源寬度
     */
    private int leftImageWidth;

    /**
     * 左邊圖片資源高度
     */
    private int leftImageHeight;

    /**
     * 右邊圖片資源
     */
    private Drawable rightImage;

    /**
     * 右邊圖片資源寬度
     */
    private int rightImageWidth;

    /**
     * 右邊圖片資源高度
     */
    private int rightImageHeight;

    /**
     * 標(biāo)題文本
     */
    private String title;

    /**
     * 標(biāo)題文本顏色
     */
    private int titleTextColor;

    /**
     *標(biāo)題文本字體大小
     */
    private float titleTextSize;

    /**
     *副標(biāo)題文本
     */
    private String subTitle;

    /**
     *副標(biāo)題文本顏色
     */
    private int subTitleTextColor;

    /**
     *副標(biāo)題文本字體大小
     */
    private float subTitleTextSize;

    /**
     *上下文
     */
    private Context mContext;

    /**
     * 屬性結(jié)合
     */
    private AttributeSet attrs;

    public UILibraryListItem(Context context) {
        this(context,null);
    }

    public UILibraryListItem(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        this.mContext = context;
        this.attrs = attrs;
        init();
    }

    public UILibraryListItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        this.attrs = attrs;
        init();
    }

    /**
     * 初始化視圖
     */
    private void init() {
        View.inflate(mContext, R.layout.listitem, this);
        findView();//綁定視圖
        loadParams();//加載屬性值
        initView();//為視圖賦值
    }

    /**
     *  為控件賦值
     */
    private void initView() {
        if(leftImage!=null){
            leftImageView.setImageDrawable(leftImage);
        }
        leftImageView.getLayoutParams().width = leftImageWidth;
        leftImageView.getLayoutParams().height = leftImageHeight;

        if(rightImage!=null){
            rightImageView.setImageDrawable(rightImage);
        }
        rightImageView.getLayoutParams().width = rightImageWidth;
        rightImageView.getLayoutParams().height = rightImageHeight;

        if (!TextUtils.isEmpty(title)){
            titleView.setText(title);
            titleView.setTextColor(titleTextColor);
            titleView.setTextSize(titleTextSize);
        }
        if (!TextUtils.isEmpty(subTitle)){
            subTitleView.setText(subTitle);
            subTitleView.setTextColor(subTitleTextColor);
            subTitleView.setTextSize(subTitleTextSize);
        }
    }


    /**
     * 初始化控件的屬性
     */
    private void loadParams() {
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs,R.styleable.UILibraryListItem);
        leftImage = typedArray.getDrawable(R.styleable.UILibraryListItem_leftImg);
        leftImageHeight = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_leftImg_height,128);
        leftImageWidth = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_leftImg_width,128);

        rightImage = typedArray.getDrawable(R.styleable.UILibraryListItem_rightImg);
        rightImageHeight = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_rightImg_height,128);
        rightImageWidth = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_rightImg_width,128);

        title = typedArray.getString(R.styleable.UILibraryListItem_title);
        titleTextColor = typedArray.getColor(R.styleable.UILibraryListItem_title_color,Color.BLACK);
        titleTextSize = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_title_size,20);

        subTitle = typedArray.getString(R.styleable.UILibraryListItem_subTitle);
        subTitleTextColor = typedArray.getColor(R.styleable.UILibraryListItem_subTitle_color,Color.GRAY);
        subTitleTextSize = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_subTitle_size,14);
        typedArray.recycle();
    }

    /**
     * 關(guān)聯(lián)控件
     */
    private void findView() {
        leftImageView =  FindView.findView(this,R.id.leftImg);
        rightImageView = FindView.findView(this,R.id.rightImg);
        titleView = FindView.findView(this,R.id.title);
        subTitleView = FindView.findView(this,R.id.subTitle);
    }


}

4.引用并預(yù)覽
??引用時(shí)為了看出明顯效果我定義了2個(gè)Item雷厂;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:uilib="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <com.uilib.ui.listitem.UILibraryListItem
        android:id="@+id/it"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        uilib:leftImg="@drawable/icon_a"
        uilib:rightImg="@drawable/icon_b"
        uilib:subTitle="SubTitle"
        uilib:title="Title" />

    <com.uilib.ui.listitem.UILibraryListItem
        android:id="@+id/it2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        uilib:leftImg="@drawable/test_icon_allow"
        uilib:subTitle="SubTitle"
        uilib:subTitle_color="@color/red"
        uilib:title="Title" />
</LinearLayout>

于是完成結(jié)果如下:
2017-08-11_004205.png

可以根據(jù)自己的實(shí)際情況靈活改變樣式惋增,且僅僅在第四步引用處做出更改即可;

總結(jié)


自定義View之組合改鲫;
通過(guò)組合來(lái)自定義View能滿足我們大部分的需求诈皿,且相對(duì)容易。
總結(jié)其過(guò)程:
1.自定義屬性
2.抽象出樣式
3.編碼實(shí)現(xiàn)類
4.引用和預(yù)覽

我是ElyarAnwar像棘,在技術(shù)的道路上摸爬滾打稽亏;
熱愛(ài)生活,熱愛(ài)技術(shù)缕题;如果喜歡記得點(diǎn)贊截歉;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市避除,隨后出現(xiàn)的幾起案子怎披,更是在濱河造成了極大的恐慌,老刑警劉巖瓶摆,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凉逛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡群井,警方通過(guò)查閱死者的電腦和手機(jī)状飞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)书斜,“玉大人诬辈,你說(shuō)我怎么就攤上這事〖黾” “怎么了焙糟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)样屠。 經(jīng)常有香客問(wèn)我穿撮,道長(zhǎng),這世上最難降的妖魔是什么痪欲? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任悦穿,我火速辦了婚禮,結(jié)果婚禮上业踢,老公的妹妹穿的比我還像新娘栗柒。我一直安慰自己,他們只是感情好知举,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布瞬沦。 她就那樣靜靜地躺著,像睡著了一般雇锡。 火紅的嫁衣襯著肌膚如雪蛙埂。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,785評(píng)論 1 290
  • 那天遮糖,我揣著相機(jī)與錄音绣的,去河邊找鬼。 笑死欲账,一個(gè)胖子當(dāng)著我的面吹牛屡江,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赛不,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惩嘉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了踢故?” 一聲冷哼從身側(cè)響起文黎,我...
    開(kāi)封第一講書(shū)人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤惹苗,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后耸峭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體桩蓉,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年劳闹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了院究。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡本涕,死狀恐怖业汰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菩颖,我是刑警寧澤样漆,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站晦闰,受9級(jí)特大地震影響氛濒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹅髓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一舞竿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窿冯,春花似錦骗奖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至芜赌,卻和暖如春仰挣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缠沈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工膘壶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人洲愤。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓颓芭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柬赐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子亡问,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,757評(píng)論 25 707
  • 一三五 二四六 時(shí)光拂過(guò)發(fā)梢 梧桐葉落生生 時(shí)光的墻板上 寫(xiě)滿了 兩千一百多晝夜呢喃 人來(lái)人往的路口 抬頭 是你笑...
    往往以往閱讀 165評(píng)論 2 0
  • 源碼來(lái)自時(shí)序數(shù)據(jù)庫(kù)InfluxDB的高可用套件InfluxDB-relay.
    lwhile閱讀 232評(píng)論 0 0
  • 對(duì)越南的向往州藕,是源于峴港那間占婆博物館束世。 說(shuō)了好幾年,錯(cuò)過(guò)了好幾次床玻,終于成行毁涉。和從未想過(guò)一起出行的人出行(相關(guān)文章...
    黃小智子閱讀 407評(píng)論 0 0
  • 經(jīng)年故紙遺長(zhǎng)恨,轉(zhuǎn)眼成非 笨枯,轉(zhuǎn)眼成非薪丁,昨日深紅已半飛遇西。 絲弦和盡黃昏雨馅精,一縷相催,一縷相催 粱檀,漸有心思散作灰洲敢。
    baobei朵朵閱讀 255評(píng)論 0 0