Android开发笔记(九十二)策略模式

基本概念

策略模式是一种把算法和对象分离开的设计模式。


策略模式其实是多态的一种表现。在实现一个功能时,根据不同的业务需求有不同的算法,如果是简单操作,那么使用if else或者switch case即可完成分支处理。但是这么做的可扩展性太差,尤其算法比较复杂的时候更是如此;而且也不具备灵活性,难以按照用户需求实现细节定制。策略模式的出现就是为了解决这些问题,它的好处有:
1、消除了if else或者switch case的分支判断;
2、采用独立的算法类,易于根据新需求进行扩展;
3、方便开发者对算法细节做自定义处理;
4、允许随时设定策略,即可在构造时设置,也可用专门的set方法设置,还可在执行时设置算法;


Android中的使用场合

Android开发中用到策略模式的地方也不少,常见的有排序算法、字符串显示策略、动画插值器和估值器等等。


排序算法

java有自带了对两类数据结构的排序方法,一类是数组的排序,使用的是Arrays类的sort方法;另一类是队列的排序,使用的是Collections类的sort方法。sort方法中的参数就有对元素进行排序的算法类Comparator,可由开发者自定义算法比较两个元素的大小。其中有关java队列的介绍参见《 Android开发笔记(二十六)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开发笔记(七十七)图片缓存算法》。


字符串显示策略

可变字符串SpannableString在显示不同文字样式上,便运用了策略模式,具体做法是调用setSpan函数设置指定范围文字的样式,然后在TextView显示文本时根据字符串显示策略分别予以展示相应样式。有关可变字符串的介绍参见《 Android开发笔记(六)可变字符串》,下面是对可变字符串分段设置显示策略的代码例子:
		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开发笔记的完整目录

你可能感兴趣的:(android,排序,策略模式,strategy,插值器)