編輯:關於android開發
以下內容是分析安卓源碼所得:
1: 使用默認樣式創建View的方式, 源碼文件 Button.Java
注:此文參考http://www.linzenews.com/ 中的內容所寫,如侵刪!
2: 需要聲明默認樣式的屬性, 源碼文件 attrs.xml
3:創建默認樣式, 源碼文件 styles.xml
4:在APP主題中,引用默認樣式 themes.xml (注意這步不能忘記)
源碼分析結束.
1:主題中引用 radioButton樣式
2:聲明默認樣式屬性
3:創建默認樣式
4:使用默認樣式創建View
這篇博客我們來介紹一下策略模式(Strategy Pattern,或者叫 Policy Pattern),也是行為型模式之一。通常在軟件開發中,我們為了一個功能可能會設計多種算法和策略,然後根據實際使用情況動態選擇對應的算法和策略,比如排序算法中的快速排序,冒泡排序等等,根據時間和空間的綜合考慮進行運行時選擇。
開閉原則和單一職責原則。
設計模式總目錄
java/android 設計模式學習筆記目錄
策略模式定義了一系列的算法,並將每一個算法封裝起來,而且使他們可以相互替換,讓算法獨立於使用它的客戶而獨立變化。
我們來看看策略模式的 uml 類圖:
據此我們可以寫出策略模式的通用代碼:
Stragety.class
public interface Stragety {
void algorithm();
}
ConcreteStragetyA.class 和 ConcreteStragetyB.class
public class ConcreteStragetyA implements Stragety{
@Override
public void algorithm() {
System.out.print("ConcreteStragetyA\n");
}
}
public class ConcreteStragetyB implements Stragety{
@Override
public void algorithm() {
System.out.print("ConcreteStragetyB\n");
}
}
默認策略類ConcreteStragetyDefault.class
public class ConcreteStragetyDefault implements Stragety{
@Override
public void algorithm() {
System.out.print("null stragety");
}
}
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();
}
}
代碼很簡單,一目了然,沒有if-else,沒有 switch-case。核心就是建立抽象,將不同的策略構建成一個個具體的策略實現,通過不同的策略實現算法替換,在簡化邏輯、結構的同時,增強系統的可讀性、穩定性和可擴展性,這對於較為復雜的業務邏輯顯得更為直觀,擴展也更加方便。
其實在 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);
......
}
}
Animation 類就是很典型用到策略模式的類,它裡面會有一個 Interpolator 插值器對象,用來在執行動畫的時候達到所需要的速度變化效果,系統提供的插值器有 LinearInterpolator(線性插值器,動畫的執行速度相等),AccelerateDecelerateInterpolator (加速減速插值器,動畫的執行起始加速,結尾減速),DecelerateInterpolator(減速插值器,速度隨著動畫的執行變慢),以及回彈插值器等等,感興趣的上網查閱一下相關資料即可(我曾經在android下拉刷新框架用過插值器的相關類,是一個很有用的類)。
這裡我就仍然以 wiki 上的代碼為例,商場在不同時段會有打折促銷活動,顧客在不同的時段分別進行購買,最後得出一個價格:
BillingStragety.class
interface BillingStrategy {
public double getActPrice(double rawPrice);
}
NormalStrategy.class 和 HappyHourStragety.class
// Normal billing strategy (unchanged price)
class NormalStrategy implements BillingStrategy {
@Override
public double getActPrice(double rawPrice) {
return rawPrice;
}
}
// Strategy for Happy hour (50% discount)
class HappyHourStrategy implements BillingStrategy {
@Override
public double getActPrice(double rawPrice) {
return rawPrice * 0.5;
}
}
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;
}
}
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();
}
}
不同時段買的東西,最後得出一個價錢,多種算法動態切換,用戶不用去關心具體的內部細節。
策略模式主要是用來分離算法,在相同的行為抽象下有不同的具體實現策略。這個模式很好的演示了開閉原則:定義抽象,增加新的策略只需要增加新的類,然後在運行中動態更換即可,沒有影響到原來的邏輯,從而達到了很好的可擴展性。
缺點也很明顯,這當然也是很多設計模式的通病:類的增多,隨著策略的增加,子類也會變得繁多。
Kotlin與Android SDK 集成(KAD 05),kotlinandroid作者:Antonio Leiva 時間:Dec 19, 2016 原文鏈接:http
自定義左下角弧形旋轉菜單欄 要做這種效果 1- 整個自定義控件其實就是一個ArcMenu .(半圓形那一圈),左下角的圖標沒有加入進控件中。 2
Android 系統版本&API對照表,android系統版本最新Android系統版本與API等級對應關系表 數據來源:http://d.android.c
Android立體旋轉動畫實現與封裝(支持以X、Y、Z三個軸為軸心旋轉),android立體旋轉本文主要介紹Android立體旋轉動畫,或者3D旋轉,下圖是我自己實現的一