Android使用默認樣式建立View的幾個姿式

 

如下內容是分析安卓源碼所得:java

1: 使用默認樣式建立View的方式, 源碼文件 Button.Java 
這裏寫圖片描述android

注:此文參考http://www.linzenews.com/ 中的內容所寫,如侵刪!算法

2: 須要聲明默認樣式的屬性, 源碼文件 attrs.xml 
這裏寫圖片描述設計模式

3:建立默認樣式, 源碼文件 styles.xml 
這裏寫圖片描述安全

4:在APP主題中,引用默認樣式 themes.xml (注意這步不能忘記) 
這裏寫圖片描述app

源碼分析結束.框架


如下是我我的的使用經驗:ide

1:主題中引用 radioButton樣式 
這裏寫圖片描述源碼分析

2:聲明默認樣式屬性 
這裏寫圖片描述學習

3:建立默認樣式 
這裏寫圖片描述

4:使用默認樣式建立View 
這裏寫圖片描述

這篇博客咱們來介紹一下策略模式(Strategy Pattern,或者叫 Policy Pattern),也是行爲型模式之一。一般在軟件開發中,咱們爲了一個功能可能會設計多種算法和策略,而後根據實際使用狀況動態選擇對應的算法和策略,好比排序算法中的快速排序,冒泡排序等等,根據時間和空間的綜合考慮進行運行時選擇。 
  針對這種狀況,一個常規的方法是將多種算法寫在一個類中,每個方法對應一個具體的排序算法,或者寫在一個方法中,經過 if…else 或者 switch…case 條件來選擇具體的排序算法。這兩種方法咱們都成爲硬編碼,雖然很簡單,可是隨着算法數量的增長,這個類就會變得愈來愈臃腫,維護的成本就會變高,修改一處容易致使其餘地方的錯誤,增長一種算法就須要修改封裝算法類的源代碼,即違背了開閉原則單一職責原則。 
  若是將這些算法或者策略抽象出來,提供一個統一的接口,不一樣的算法或者策略有不一樣的實現類,這樣在程序客戶端就能夠經過注入不一樣的實現對象來實現算法或者策略的動態替換,這種模式的可擴展性、可維護性也就更高,這就是下面講到的策略模式。 
  

設計模式總目錄

  java/android 設計模式學習筆記目錄

特色

  策略模式定義了一系列的算法,並將每個算法封裝起來,並且使他們能夠相互替換,讓算法獨立於使用它的客戶而獨立變化。 
  策略模式的使用場景:

  • 針對同一類型問題的多種處理方式,僅僅是具體行爲有差異時;
  • 須要安全地封裝多種同一類型的操做時;
  • 出現同一抽象類有多個子類,而又須要使用 if-else 或者 switch-case 來選擇具體子類時。

 

UML類圖

  咱們來看看策略模式的 uml 類圖: 
  這裏寫圖片描述 
策略模式有三個角色:

  • Context:用來操做策略的上下文環境;
  • Stragety:策略的抽象;
  • ConcreteStrategy:具體的策略實現。

  據此咱們能夠寫出策略模式的通用代碼: 
Stragety.class

 

public interface Stragety {
    void algorithm();
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

ConcreteStragetyA.class 和 ConcreteStragetyB.class

public class ConcreteStragetyA implements Stragety{
    @Override
    public void algorithm() {
        System.out.print("ConcreteStragetyA\n");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
public class ConcreteStragetyB implements Stragety{
    @Override
    public void algorithm() {
        System.out.print("ConcreteStragetyB\n");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

默認策略類ConcreteStragetyDefault.class

public class ConcreteStragetyDefault implements Stragety{
    @Override
    public void algorithm() {
        System.out.print("null stragety");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Context.class 和測試代碼

public class Context {

    private Stragety stragety;

    public Context() {
        stragety = new ConcreteStragetyDefault();
    }

    public void algorithm() {
        stragety.algorithm();
    }

    public void setStragety(Stragety stragety) {
        if (stragety == null) {
            throw new IllegalArgumentException("argument must not be null!!!");
        }
        this.stragety = stragety;
    }

    public static void main(String args[]) {
        Context context = new Context();
        context.setStragety(new ConcreteStragetyA());
        context.algorithm();
        context.setStragety(new ConcreteStragetyB());
        context.algorithm();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

代碼很簡單,一目瞭然,沒有if-else,沒有 switch-case。核心就是創建抽象,將不一樣的策略構建成一個個具體的策略實現,經過不一樣的策略實現算法替換,在簡化邏輯、結構的同時,加強系統的可讀性、穩定性和可擴展性,這對於較爲複雜的業務邏輯顯得更爲直觀,擴展也更加方便。

示例與源碼

Android 源碼中策略模式

  其實在 Android 源碼中策略模式使用的次數也是不少,你們常見的動畫中就有使用到策略模式:

public abstract class Animation implements Cloneable {
    /** * The interpolator used by the animation to smooth the movement. */
    Interpolator mInterpolator;
    ....
    /** * Sets the acceleration curve for this animation. Defaults to a linear * interpolation. * * @param i The interpolator which defines the acceleration curve * @attr ref android.R.styleable#Animation_interpolator */
    public void setInterpolator(Interpolator i) {
        mInterpolator = i;
    }
    ....
    /** * Gets the transformation to apply at a specified point in time. Implementations of this * method should always replace the specified Transformation or document they are doing * otherwise. * * @param currentTime Where we are in the animation. This is wall clock time. * @param outTransformation A transformation object that is provided by the * caller and will be filled in by the animation. * @return True if the animation is still running */
    public boolean getTransformation(long currentTime, Transformation outTransformation) {
        ......

            final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
            applyTransformation(interpolatedTime, outTransformation);
        ......
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

Animation 類就是很典型用到策略模式的類,它裏面會有一個 Interpolator 插值器對象,用來在執行動畫的時候達到所須要的速度變化效果,系統提供的插值器有 LinearInterpolator(線性插值器,動畫的執行速度相等),AccelerateDecelerateInterpolator (加速減速插值器,動畫的執行起始加速,結尾減速),DecelerateInterpolator(減速插值器,速度隨着動畫的執行變慢),以及回彈插值器等等,感興趣的上網查閱一下相關資料便可(我曾經在android下拉刷新框架用過插值器的相關類,是一個頗有用的類)。

wiki example

  這裏我就仍然以 wiki 上的代碼爲例,商場在不一樣時段會有打折促銷活動,顧客在不一樣的時段分別進行購買,最後得出一個價格: 
BillingStragety.class

interface BillingStrategy {
    public double getActPrice(double rawPrice);
}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

NormalStrategy.class 和 HappyHourStragety.class

// Normal billing strategy (unchanged price)
class NormalStrategy implements BillingStrategy {
    @Override
    public double getActPrice(double rawPrice) {
        return rawPrice;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
// Strategy for Happy hour (50% discount)
class HappyHourStrategy implements BillingStrategy {
    @Override
    public double getActPrice(double rawPrice) {
        return rawPrice * 0.5;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Customer.class

class Customer {

    private List<Double> drinks;
    private BillingStrategy strategy;

    public Customer(BillingStrategy strategy) {
        this.drinks = new ArrayList<Double>();
        this.strategy = strategy;
    }

    public void add(double price, int quantity) {
        drinks.add(strategy.getActPrice(price * quantity));
    }

    // Payment of bill
    public void printBill() {
        double sum = 0;
        for (Double i : drinks) {
            sum += i;
        }
        System.out.println("Total due: " + sum);
        drinks.clear();
    }

    // Set Strategy
    public void setStrategy(BillingStrategy strategy) {
        this.strategy = strategy;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

main

public class StrategyPatternWiki {

    public static void main(String[] args) {
        Customer firstCustomer = new Customer(new NormalStrategy());

        // Normal billing
        firstCustomer.add(1.0, 1);

        // Start Happy Hour
        firstCustomer.setStrategy(new HappyHourStrategy());
        firstCustomer.add(1.0, 2);

        // New Customer
        Customer secondCustomer = new Customer(new HappyHourStrategy());
        secondCustomer.add(0.8, 1);
        // The Customer pays
        firstCustomer.printBill();

        // End Happy Hour
        secondCustomer.setStrategy(new NormalStrategy());
        secondCustomer.add(1.3, 2);
        secondCustomer.add(2.5, 1);
        secondCustomer.printBill();

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

不一樣時段買的東西,最後得出一個價錢,多種算法動態切換,用戶不用去關心具體的內部細節。

總結

  策略模式主要是用來分離算法,在相同的行爲抽象下有不一樣的具體實現策略。這個模式很好的演示了開閉原則:定義抽象,增長新的策略只須要增長新的類,而後在運行中動態更換便可,沒有影響到原來的邏輯,從而達到了很好的可擴展性。 
  優勢:

  • 結構清晰明瞭、使用簡單直觀;
  • 耦合度相對而言較低,擴展方便;
  • 操做封裝也更爲完全,數據更爲安全。

  缺點也很明顯,這固然也是不少設計模式的通病:類的增多,隨着策略的增長,子類也會變得繁多。

相關文章
相關標籤/搜索