Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Using Styles and Themes in Android(在Android中使用主題和樣式)

Using Styles and Themes in Android(在Android中使用主題和樣式)

編輯:關於Android編程

Basics XML Attributes(基本的XML屬性)

If you’ve written an Android app, you’ve seen them. They look like this:

如果你寫過一個Android應用,那你一定見過他們。他們看起來像下面這樣:

The attribute compiler: AAPT(屬性編譯器:AAPT)

AAPT is the Android Assets Packaging Tool.AAPT is a kitchen sink of a tool. It parses the manifest, packages assets and resources, and validates the xml.It is one of the things that parses your resources.

AAPT 是Android的資產打包工具,類似廚房水槽。它的作用主要是轉換manifest清單文件、app的資產和和資源文件,並且使xml文件有效。它是一種轉換資源的工具。

  • It is written in C/C++(它是用c/c++語言編寫的)

  • Uses eXpat as the parser(它使用eXpat作為轉換器)

  • Is amazingly complex(它非常復雜)

  • XML resources end up as compressed binary XML, in the APK(XML資源最終會被壓縮成二進制數據在APK包中)

Where do predefined attributes come from?(系統預定義的屬性是從哪來的?)

Documented in subclasses of View, e.g.:

對於這個問題的回答在下面這篇文章的view的子欄目裡有記錄:

http://developer.android.com/reference/android/view/View.html

Defined in:(定義在下面這個文件裡)

$ANDROID_HOME/frameworks/base/core/res/res/values/attrs.xml

Designed for extension: Views ignore attributes they don’t understand.

為了擴展,view會忽略那些他們不懂的屬性。

Not so fast…

先別急...

The Android API is whitelisted. That includes attribute names.

Android API 是有白名單的。它包含了屬性名。

You can only use, e.g.,

你只能用下面這個

android:actionModeFindDrawable

…if it is whitelisted in:

如果他在下面這個文件中是白名單的話

$ANDROID_HOME/frameworks/base/api/.{xml, txt}

…And it isn’t.

然而它並不是。

I don’t know exactly why… The white-list explains why the symbol is not available from Java, not why it isn’t visible toaapt

我真的不知道為什麼會這樣...白名單解釋了為什麼標識符不能通過java獲取到,但不能解釋為什麼aapt裡看不到它。

How to Package a Widget(如何打包一個控件)

You’ll see a fair amount of this:

你會看到一大坨這樣的東西:

public abstract class FooView extends BarView {
    private final int bgColor;
    private final int fgColor;
    private final int margin;
    private final int padding;

    protected FooView(
        int bgColor, int fgColor,
        int margin, int padding)
    {
        this.bgColor = bgColor;
        this.fgColor = fgColor;
        this.margin = margin;
        this.padding = padding;
    }
public class MyFooView extends BaseView {
    public FooView(Context context) {
        super(Color.RED, Color.GREEN, 7, 3);
    }

 

Using Custom Attributes(使用自定義屬性)

A much better approach, obviously, is to define new attributes and use them to configure your custom widget.

很顯然,一個更好的辦法是定義新的屬性並用它們來配置你的自定義控件。

It’s a 3 step process (a waltz):

這需要以下三部曲(類似華爾茲):

\
  • define the attributes(定義屬性)

  • parse them in your widget(在你的控件代碼中解析這些屬性)

  • use them in your widget layout.(在你的布局文件中使用他們)

Defining Custom Attributes(定義自定義屬性)

Create a new resource file in thevaluesdirectory,attrs.xml:

在values文件夾下創建一個名為attrs.xml的新資源文件:

\

Declare your attributes in adeclare-stylableelement, in the new file.Thedeclare-styleableelement isnota namespace. The attributes names must be globally unique!

在這個新文件中,在一個declare-stylable節點下聲明你的屬性。這個declare-stylable節點不是一個命名空間。你所定義的屬性名稱必須是全局唯一的。


    
    
    
    
    
    
        
        
        
        
    

 

Custom Attribute Formats(自定義屬性格式)

There are, currently, ten formats. They are undocumented but they are defined in theaaptsource, here:

目前有10種格式可選。他們雖然未被正式明文規定,但他們卻在aapt中被定義了,在這裡:

$ANDROID_HOME/frameworks/base/tools/aapt/ResourceTable.cpp
  • reference

  • string

  • color

  • dimension

  • boolean

  • integer

  • float

  • fraction

  • enum

  • flag

Using Attribute Formats(使用屬性格式)

Formats can be or-ed together.

不同格式可以用“或”符號連在一起使用。

Most of them already accept references, so addingreferenceis usually redundant.Note the syntax of the enumerated type, anattrcontainingenumelements:

大多數屬性已經接受了引用格式,所以再添加引用格式通常是多此一舉的。注意枚舉類型的語法,一個attr節點可以包含多個枚舉元素:


    
    

 

Parsing Custom Attributes(解析自定義屬性)

public TagView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);                                // #1
    TypedArray atts = context.getTheme().obtainStyledAttributes(attrs, R.styleable.tag_view, defStyle, 0);
    try {
        final int n = atts.getIndexCount();
        for (int i = 0; i < n; i++) {
            try {
                int attr = atts.getIndex(i);
                switch (attr) {
                    case R.styleable.tag_view_tag_view_text_color:
                        textColor = atts.getColor(attr, textColor); // #3
                        break;
                    //// other cases...
                }
            }
            catch (UnsupportedOperationException e) {
                Log.w(TAG, "Failed parsing attribute: " + atts.getString(i), e);
            }
            catch (NotFoundException e) {
                Log.w(TAG, "Failed parsing attribute: " + atts.getString(i), e);
            }
        }
    }
    finally { atts.recycle(); }                                     // #4
}

Be sure to let the super classes parse its attributes! Call the super constructor.

1.一定要讓父類解析它的屬性!要調用父類的構造函數。   2.While it is possible to get the attributes out of the AttributeSet, it is unnecessarily difficult. Styles have not been applied and @ references have not been resolved. 2.雖然可以從AttributeSet中得到屬性,但是沒有必要搞的這麼困難。樣式還沒有被應用,而且引用也尚未被解析。   3.The TypedArray has getters for the above mentioned formats, plus a few more: 3.對於上述格式TypedArray有專門的get方法來獲取,甚至還有其他一些get方法: 1.getDrawable 2.getDimensionPixelOffset 3.etc…   4.Be sure to recycle the TypedArray when you are through with it. 4.TypedArray用完之後一定記得要及時回收

 

More Parsing Custom Attributes(更多關於解析自定義屬性)

A handy idiom, here, is:

這有一個很方便的習慣性寫法:

attribute = defaultVal;
//...
case case R.styleable.tag:
    attribute = atts.getAttribute(attr, attribute);
//...
finalAttribute = attribute;

If there are a lot of attributes, you might want to consider using a builder.

如果有很多屬性要解析,您可能需要考慮使用一個builder。

 

Using Custom Attributes(使用自定義屬性)

Add a new namespace to your layout and then use your new attributes like an others.

在你的布局文件中添加一個新的命名空間,然後像使用其他系統屬性那樣使用你的自定義屬性。

xmlns:tagview="http://schemas.android.com/apk/res/

Note that you addyourpackage namespace, even if the attributes are defined in a library project!

注意在引用你的自定義屬性時你需要加上剛才定義的命名空間,即使你的屬性是定義在一個類庫中!

 

Introducing Styles(樣式的介紹)

Styles bring a cascading-style-sheet-like capability to the Android UI. The syntax is very simple.

樣式給Android 的 UI帶來了類似網頁設計中CSS樣式表那樣的能力。樣式使用語法也很簡單。

Translate:

android:attribute="value"

…in a layout, to:

value

…in astyleresource.

它把布局文件中的android:attribute="value" 翻譯成了資源文件中的value

Apply it using astyleattribute:

像下面這樣應用它:

Note that thestyleattribute is not in theandroidnamespace.

注意這個樣式屬性不在“android”命名空間中。

 

Basic Styles(基礎樣式)

For instance, reorganize this:

例如長得像下面這些那樣:

as this:

and this:

 

Style Inheritance(樣式繼承)

These two style definitions are (roughly) equivalent:

這兩種樣式定義方式的效果是一樣的:

 

Using Styles(使用樣式)

 

The wins should be obvious.

優勢應該是顯而易見的。

  • A designer sets up standard styles for an application and applies them, as appropriate, to layouts.

  • 程序設計者為應用程序設計標准樣式,並使他們適用於恰當的布局。

  • Factoring out styles makes the application less brittle.

  • 把樣式提取出來能使應用程序不那麼脆弱。

  • Like any other defined resource, styles are subject to resource qualifiers. Your app can look good on both a phone and a TV.

  • 像任何其他定義的資源一樣,樣式受到資源限定符的支配。你的應用可以在手機和電視上看起來不錯。
  • Inheriting from - and then overriding - Android types is quite useful. You have to use the "parent" attribute: the "dot" trick won’t work:
  • 繼承然後復寫Android類型是非常有用的。你必須使用“parent”屬性,而用“點”的那個方法是行不通的:

 

Slight aside: Resource Drawables(輕微的旁白:Drawable資源)

If you haven’t met Resource Drawables, you should.

如果你還沒有碰到過Drawable 資源,你會碰到的。

Perhaps the quickest thing you can do to customize the appearance of an application, is to give buttons custom backgrounds.

也許做給app定制外觀最快的一件事就是給按鈕搞個自定義背景。

Like this:

 


        

        

        

 

Where do predefined styles come from?(預定義的樣式是哪來的?)

Android Styles are documented in:

android 的所有樣式都記錄在這裡面:

http://developer.android.com/reference/android/R.style.html

Defined in:定義在這裡:

$ANDROID_HOME/frameworks/base/core/res/res/values/styles.xml

 

Dots (".") in the definition are translated into underscores ("_") for Java symbols and in the documentation.

在文檔中,定義中的點(“.”)被轉換成了下劃線(“_”)。

…and, again, though, their visiblity controlled in:

不過,他們的可見性被控制在下面這個文件裡:

 

$ANDROID_HOME/frameworks/base/api/.{xml, txt}

 

Introducing Themes(主題的介紹)

 

A theme is a collection of named references.

主題其實就是一堆已命名的引用。

Think of a function dispatch table…

聯想一下函數調度表…

Here’s a tiny exerpt fromTheme.Holo

這裡是Theme.Holo的一小部分

 


@android:style/Theme.Holo.Dialog.Alert
@android:style/AlertDialog.Holo
false
@android:drawable/ic_dialog_alert_holo_dark

It creates aliases for two styles, an (boolean) enum, and a drawable.

它為兩種樣式分別創建了別名,一個是boolean類型的枚舉,一個是drawable的。

 

Themes backfit Android’s appearance(主題支撐Android的外觀)

 

 

Themes can be assigned to individual application components. Android uses the theme to control its appearance.

主題可以分配給單獨的某個app組件。Android系統使用主題來控制其外觀。

Assigning a theme with overridden attributes to a component will customize the appearance of UI objects in the component?—?even those not managed by the component?—?without any other code!

給一個組件指定帶復寫屬性的主題,將會重新定義這個組件的UI控件的外觀——即使是那些不是由該組件來管理的ui控件——這個過程並不需要任何其他代碼!

 




 

Using foreign attributes Themed Styles(使用外部屬性主題樣式)

 

You can refer to an element of a theme, using question mark ("?") syntax.

通過使用問號(“?”)的語法形式,你可以引用一個主題的樣式元素。

The styleTheme.Holodefines a stylebuttonStyle. In your layout, you can say:

在Theme.Holo這個主題中定義了一個buttonStyle的樣式,你可以在你的布局中這樣引用:

 

 

BE CAREFUL: question mark syntax will allow you to create things that will not run!

注意了:問號語法將允許你創建的一些不會運行的東西!

The referenced attribute must be part of a theme.

被引用的屬性必須是一個主題的一部分。

 

Themes and Resource Qualifiers(主題和資源限定符)

 

Themes are an even more powerful way adjust the appearance of your application, to different devices.

主題還是一個調整app的外觀以適應不同設備的強有力工具。

Most important, you can use them to adjust to multiple versions of Android!

最重要的是,您可以使用它們來適應多個版本的安卓系統!

 

\

Building Custom Themes(構造自定義主題)

  • Define theme attributes(定義主題裡的屬性)

  • Create a parent theme that defines the attributes(創建一個定義了屬性的父主題)

  • Use "?" syntax to refer to the theme styles.(使用“?”語法來引用這些主題樣式)

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved