Android自定義Drawable

Android自定義Drawable。

===============================================

一個state list drawable在根據View的狀態來顯示不同的圖片是非常有用的.例如,我們可以為一個按鈕的背景定義一個按下狀態和非按下狀態的狀態圖片列表,按鈕就會根據不同的狀態改變圖片.我們也可以通過自定義的圖片狀態列表使其變得更加的有用。

下面是一個郵件客戶端,它分別標識瞭已讀郵件和未讀郵件。

這裡寫圖片描述

上面的列表使用瞭一個ListView,每個列表項使用瞭一個RelativeLayout,在這個RelativeLayout中包含有一個ImageView和一個TextView,當顯示每項的時候,你可以手工的轉換兩張圖片,並且一次的設置背景顏色。但是通過定義一個自定義狀態,你可以更加簡單和方便的進行管理。

第一步:聲明自定義的狀態屬性。

自定義狀態是聲明在attrs.xml文件中,這個文件在應用的res/values目錄下。

第二步:在圖片狀態列表中使用自定義的狀態。

在我們的例子中,有兩個狀態圖片列表。

一個是用做背景改變的列表項:

一個是消息狀態圖標改變的列表項:

為瞭能夠使用自定義的狀態,需要使用應用的包名聲明一個新的XML命名空間,並且使用新的命名空間作為自定義狀態屬性的前綴。

第三步:合入自定義的狀態來更新View的drawable狀態

每個View都提供瞭一些現存的可以使用的狀態,例如CheckBox有選中狀態,通過重寫View.onCreateDrawableState() ,自定義View可以註入它自己的狀態,然後我們就可以使用這個狀態 。

在我們上面的例子中,包含有ImageView和TextView的RelativeLayout實現維持瞭一個未讀狀態,它可以設置和更新View的drawable狀態,這樣我們就可以看到已讀和未讀兩種狀態的郵件項。

public class MessageListItemView extends RelativeLayout {

private static final int[] STATE_MESSAGE_UNREAD = {R.attr.state_message_unread};

private boolean messageUnread;

// Constructors, view loading etc…

@Override

protected int[] onCreateDrawableState(int extraSpace) {

// If the message is unread then we merge our custom message unread state into

// the existing drawable state before returning it.

if (messageUnread) {

// We are going to add 1 extra state.

final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);

mergeDrawableStates(drawableState, STATE_MESSAGE_UNREAD);

return drawableState;

} else {

return super.onCreateDrawableState(extraSpace);

}

}

public void setMessageUnread(boolean messageUnread) {

if (this.messageUnread != messageUnread) {

this.messageUnread = messageUnread;

// Refresh the drawable state so that it includes the message unread

// state if required.

refreshDrawableState();

}

}

}

我們知道,上面隻是在MessageListItemView裡面添加瞭自定義的狀態,我們改變的隻是MessageListItemView的狀態,相應的觸發瞭它背景顏色的改變。但是,ImageView包含在它的裡面,MessageListItemView的狀態是如何改變ImageView的狀態的呢?

因為ImageView是我們自定義佈局的一個子View,我們可以使用View.setDuplicateParentStateEnabled()告訴它去復制父佈局的狀態,這樣父佈局的狀態就可以傳遞給包含瞭這個自定義狀態的子佈局中。

You May Also Like