Android自定義屬性以及組合View

概念

自定義組合View是指android給我們提供的View本身功能不夠用,但是可以把幾個(gè)View粘合起來形成一個(gè)獨(dú)立的類,對(duì)外部提供統(tǒng)一的職能,內(nèi)部View之間的邏輯實(shí)現(xiàn)可以隱藏,使之整體看起來就像是一個(gè)新的View。另外,還可以通過自定義屬性功能,使得我們的組合View直接在XML布局文件中方便的使用

實(shí)現(xiàn)

定義一個(gè)基類,之后的組合View都繼承自它

public abstract class BaseCustomView extends RelativeLayout {
    /**
     * 自定義view屬性命名空間
     */
    private static final String NAMESPACE = "http://schemas.android.com/apk/res-auto";

    //重載構(gòu)造函數(shù) 通過new構(gòu)建對(duì)象時(shí)會(huì)調(diào)用此處
    //View.java中原文:Simple constructor to use when creating a view from code
    public BaseCustomView(Context context) {
        super(context);
        initView();
    }

    //在XML中構(gòu)建時(shí)會(huì)調(diào)用此處,也是我們自定義屬性的構(gòu)造函數(shù),style默認(rèn)用app的主題
    //View.java中原文:Constructor that is called when inflating a view from XML
    //...This version uses a default style of 0, so the only attribute values 
    //applie are those in the Context's Theme and the given AttributeSet
    public BaseCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, getStyleable());
        initAttributes(a);
        initView();
        a.recycle();
    }

    public BaseCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    /**
     * 初始化布局
     */
    private void initView() {
        View view = View.inflate(getContext(), getLayout(), this);
        ButterKnife.bind(this, view);
        initData(view);
    }

    //返回 R.styleable.xxx styleable是自定義的一組declare-styleable
    protected abstract int[] getStyleable();

    //根據(jù)獲取到的屬性數(shù)組在代碼中初始化屬性值
    protected abstract void initAttributes(TypedArray a);

    //獲取自定義組合View的布局 R.layout.xxx
    protected abstract int getLayout();

    //初始化一些默認(rèn)數(shù)據(jù)
    protected abstract 
  • 一個(gè)簡單的例子

一般我們?cè)趹?yīng)用中會(huì)有很多類似的View,比如設(shè)置界面的View都可以抽取出來獨(dú)立成章,簡化代碼方便維護(hù)下邊是一個(gè)簡單的例子,實(shí)現(xiàn)了一個(gè)比較通用的設(shè)置條目,XML中沒有設(shè)置相關(guān)資源的時(shí)候就隱藏相應(yīng)內(nèi)部View,否之顯示出來。一個(gè)空的效果顯示如下:

示例
public class SettingItemView extends BaseCustomView {
    private String mLeftString;
    private String mEndString;
    private Drawable mLeftImage;
    private Drawable mEndImage;
    private int mLeftColor;

    public SettingItemView(Context context) {
        super(context);
    }

    public SettingItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected int[] getStyleable() {
        return R.styleable.SettingItemView;
    }

    @Override
    protected void initAttributes(TypedArray a) {
        mLeftString = a.getString(R.styleable.SettingItemView_textLeft);
        mEndString = a.getString(R.styleable.SettingItemView_textEnd);
        mLeftImage = a.getDrawable(R.styleable.SettingItemView_imageLeft);
        mEndImage = a.getDrawable(R.styleable.SettingItemView_imageEnd);
        mLeftColor = a.getColor(R.styleable.SettingItemView_colorLeft, getResources().getColor(R
                .color.text_color));
    }

    @Override
    protected int getLayout() {
        return R.layout.ui_setting_item;
    }

    @Override
    protected void initData(View view) {
        setLeftText(mLeftString);
        setEndText(mEndString);
        setLeftImage(mLeftImage);
        setEndImage(mEndImage);
        tv_left.setTextColor(mLeftColor);
    }

    public void setLeftImage(Drawable image) {
        iv_left.setImageDrawable(image);
    }

    /**
     * 當(dāng)沒有設(shè)置圖片資源時(shí)隱藏之
     *
     * @param image
     */
    public void setEndImage(Drawable image) {
        if (image != null) {
            iv_end.setVisibility(VISIBLE);
            iv_end.setImageDrawable(image);
        }
    }

    public void setLeftText(String text) {
        tv_left.setText(text);
    }

    /**
     * 當(dāng)沒有設(shè)置文字時(shí)隱藏之
     *
     * @param text
     */
    public void setEndText(String text) {
        if (!TextUtils.isEmpty(text)) {
            tv_end.setVisibility(VISIBLE);
            tv_end.setText(text);
        } 
    }
}
  • 新建一個(gè)屬性文件attrs.xml
    添加以下自定義屬性(一些通用的可以抽取出來供其它使用):
<!--common-->
    <attr name="textLeft" format="string"/>
    <attr name="textEnd" format="string"/>
    <attr name="imageLeft" format="reference"/>
    <attr name="imageEnd" format="reference"/>

<!--SettingItemView-->
<declare-styleable name="SettingItemView">
    <attr name="textLeft"/>
    <attr name="textEnd"/>
    <attr name="imageLeft"/>
    <attr name="imageEnd"/>
    <attr name="colorLeft" format="color"/>
</declare-styleable>

關(guān)于styleable屬性類型可以搜索一下有很多資料,就不展開說了
布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/rl_root"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_height">

    <View
        android:id="@+id/line"
        android:layout_width="match_parent"
        android:layout_height="0.1dp"
        android:background="#ffd2d2d2"
        android:layout_alignParentBottom="true"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/item_height"
        android:orientation="horizontal"
        android:layout_above="@id/line">

        <ImageView
            android:id="@+id/iv_left"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:visibility="gone"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:layout_weight="1"
            android:visibility="gone"/>

        <ImageView
            android:id="@+id/iv_end"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:visibility="gone"/>

        <TextView
            android:id="@+id/tv_end"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:visibility="gone"/>

    </LinearLayout>
</RelativeLayout>
  • 應(yīng)用
    在布局中應(yīng)用剛才寫的組合View就像普通View一樣就好了,別忘了在跟布局中添加一行
 xmlns:item="http://schemas.android.com/apk/res-auto"

這樣新屬性就可以以item的命名空間調(diào)用了

<所在包名.SettingItemView
android:id="@+id/siv_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
item:imageLeft="@drawable/xxx"
item:textLeft="test"/>

遷移自CSDN
2015年12月12日 11:02:33
http://blog.csdn.net/u013262051/article/details/50273451

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,741評(píng)論 25 709
  • 參考文章。http://blog.csdn.net/xmxkf/article/details/51468648h...
    codeHoward閱讀 1,185評(píng)論 0 4
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,039評(píng)論 4 61
  • 本書已經(jīng)是第9版了,我們知道這意味著什么。曾經(jīng)讓我們驚訝的是在一次會(huì)議上,一位年輕的教授說從我們的書中獲益,本書的...
    蘇語嫣閱讀 245評(píng)論 0 0
  • 閑扯淡: 其實(shí)本人對(duì)算法一直懷著萬分敬仰的態(tài)度,因?yàn)樵谖倚睦锼惴ㄒ恢笔悄欠N高級(jí)科學(xué)研究者玩的東西,后來學(xué)了算法后,...
    wintersal閱讀 621評(píng)論 0 50

友情鏈接更多精彩內(nèi)容