Android開発ノート(九十二)戦略モデル


基本概念戦略モードはアルゴリズムとオブジェクトを分離する設計モードである.
戦略パターンは実は多態の表現である.1つの機能を実装する場合、異なるビジネスニーズに応じて異なるアルゴリズムがあり、単純な操作であればif elseまたはswitch caseを使用してブランチ処理を完了することができる.しかし、このような拡張性はあまりにも悪く、特にアルゴリズムが複雑な場合はなおさらである.また、柔軟性も備えておらず、ユーザーのニーズに合わせて詳細なカスタマイズが困難です.ポリシー・モードの登場は、これらの問題を解決するためであり、そのメリットは次のとおりです.
1、if elseまたはswitch caseの分岐判断を解消した.
2、独立したアルゴリズムクラスを採用し、新しい需要に応じて拡張しやすい.
3、開発者がアルゴリズムの詳細をカスタマイズするのに便利である.
4、いつでもポリシーを設定することができ、構築時に設定することができ、専門のset方法で設定することもでき、実行時にアルゴリズムを設定することもできる.
Androidの使用場面Android開発でポリシーモードが使われるところも少なくなく、ソートアルゴリズム、文字列表示ポリシー、アニメーション補間器、推定器などが一般的です.
ソートアルゴリズムjavaには2種類のデータ構造に対するソート方法があり、1つは配列のソートであり、Arraysクラスのsort方法を使用している.もう1つのクラスはキューのソートであり、Collectionsクラスのsortメソッドを使用します.sortメソッドのパラメータには、要素をソートするアルゴリズムクラスComparatorがあり、開発者のカスタムアルゴリズムで2つの要素のサイズを比較することができます.ここでjavaキューについては、「Android開発ノート(26)Javaのコンテナクラス」を参照してください.次に、配列とキューをソートするコードの例を示します.
	public static void main(String[] arg) {
		
		String[] strArray = {"abc", "aaa", "abb", "tgy", "ctr"};
		System.out.println("before sort");
		for (int i=0; i<strArray.length; i++) {
			System.out.println("strArray["+i+"]="+strArray[i]);
		}
		Arrays.sort(strArray, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.compareTo(o2);
			}
		});
		System.out.println("after sort");
		for (int i=0; i<strArray.length; i++) {
			System.out.println("strArray["+i+"]="+strArray[i]);
		}
		
		ArrayList<Integer> intList = new ArrayList<Integer>();
		intList.add(10);
		intList.add(4);
		intList.add(7);
		intList.add(1);
		intList.add(3);
		System.out.println("before sort");
		for (int i=0; i<intList.size(); i++) {
			System.out.println("intList.get("+i+")="+intList.get(i));
		}
		Collections.sort(intList, new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return (o1>o2)?0:-1;
			}
		});
		System.out.println("after sort");
		for (int i=0; i<intList.size(); i++) {
			System.out.println("intList.get("+i+")="+intList.get(i));
		}
		
	}

次に、サンプル・コードの実行結果を示します.
before sort
strArray[0]=abc
strArray[1]=aaa
strArray[2]=abb
strArray[3]=tgy
strArray[4]=ctr
after sort
strArray[0]=aaa
strArray[1]=abb
strArray[2]=abc
strArray[3]=ctr
strArray[4]=tgy
before sort
intList.get(0)=10
intList.get(1)=4
intList.get(2)=7
intList.get(3)=1
intList.get(4)=3
after sort
intList.get(0)=1
intList.get(1)=3
intList.get(2)=4
intList.get(3)=7
intList.get(4)=10

ソートアルゴリズムと同様に、ピクチャキャッシュで使用されるキューアルゴリズム(淘汰アルゴリズム、置換アルゴリズムとも呼ばれる)もあります.例えば、先にFIFOを出して、後でLIFOを出して、最近最も長い間LRUを使用していない、最もよくLFUを使用しないなどです.画像キャッシュについては「Android開発ノート(七十七)画像キャッシュアルゴリズム」を参照してください.
文字列表示ポリシー可変文字列SpannablesStringは、異なる文字スタイルを表示する上で、setSpan関数を呼び出して指定範囲の文字のスタイルを設定し、TextViewでテキストを表示するときに文字列表示ポリシーに従ってそれぞれ対応するスタイルを表示するポリシーモードを使用します.可変文字列については、「Android開発ノート(6)可変文字列」を参照してください.以下は、可変文字列セグメントの表示ポリシーを設定するコードの例です.
		String str_url = "Let's go.";
		String itemText = "Hello world. " + str_url;
		SpannableString spanText = new SpannableString(itemText);
		int first_length = 5;
		int second_length = 12;
		
		spanText.setSpan(new RelativeSizeSpan(1.5f) , 0, first_length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		spanText.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, first_length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		
		spanText.setSpan(new RelativeSizeSpan(0.75f), first_length+1, second_length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		spanText.setSpan(new ForegroundColorSpan(Color.RED), first_length+1, second_length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		
		Spannable sp = (Spannable) Html.fromHtml("<a href=\"\">"+str_url+"</a>");
		CharSequence text = sp.toString();
		URLSpan[] urls = sp.getSpans(0, text.length(), URLSpan.class);
		for (URLSpan url : urls) {
			MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
			spanText.setSpan(myURLSpan, second_length+1, itemText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		}
		
		tv_hello.setText(spanText);

次に、一般的な文字列表示ポリシーをいくつか示します.
RelativeSizeSpan:文字の相対サイズ
AbsoluteSizeSpan:文字の絶対サイズ
ForegroundColorSpan:文字の前の景色
BackgroundColorSpan:テキスト背景色
StyleSpan:文字スタイル(通常、太字、斜体)
TypefaceSpan:フォント
ImageSpan:グラフィックミックス
URLSpan:ハイパーリンクスタイル
アニメーション補間器と推定器Androidはアニメーションの過程の変化値を計算し、異なる補間器アルゴリズムを採用して、アニメーションの変化の速度の速さと遅さを実現することができる.また、補間器の計算はデフォルトの開始値と終了値にすぎません.これをカスタムの開始と終了効果に変換するには、推定アルゴリズムを適用する必要があります.アニメーションおよび補間器と推定器の紹介については、「Android開発ノート(九十六)集合アニメーションと属性アニメーション」を参照してください.以下は、属性アニメーションに補間器と推定器アルゴリズムを適用するコードの例です.
	//        
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
	private void animatorValue() {
		ObjectAnimator anim1 = ObjectAnimator.ofInt(tv_object_text, "backgroundColor", 0xFFFF0000, 0xFFFFFFFF);
		anim1.setInterpolator(new AccelerateInterpolator());
		anim1.setEvaluator(new ArgbEvaluator());
		ObjectAnimator anim2 = ObjectAnimator.ofFloat(tv_object_text, "rotation", 0f, 360f);
		anim2.setInterpolator(new DecelerateInterpolator());
		anim2.setEvaluator(new FloatEvaluator());
		ObjectAnimator anim3 = ObjectAnimator.ofObject(tv_object_text, "clipBounds", new RectEvaluator(), new Rect(0,0,250,100), new Rect(0,0,100,50), new Rect(0,0,250,100));
		anim3.setInterpolator(new LinearInterpolator());
		ObjectAnimator anim4 = ObjectAnimator.ofInt(tv_object_text, "textColor", 0xFF000000, 0xFF0000FF);
		anim4.setInterpolator(new BounceInterpolator());
		anim4.setEvaluator(new IntEvaluator());
		
		AnimatorSet animSet = new AnimatorSet();
		AnimatorSet.Builder builder = animSet.play(anim1);
		builder.with(anim2).after(anim3).before(anim4);// anim3   ,       anim1、anim2,    anim4
		animSet.setDuration(6000);
		animSet.start();
	}

Android開発ノートの完全なディレクトリを確認します