Android平台通过ActivityGroup实现类似IOS的UINavigationController

android程序中最基本的组成部分是activity,一个程序有多个activity,当启动一个新的activity的时候,新的activity会出现在屏幕上覆盖旧的activity;当这个activity finish()的时候,之前的activity重新显示出来.

简单的说,这是一个类似于栈的结构,即原有activity A1:[A1]

现在新开activity A2:[A1 A2]

当A2finish的时候,再显示A1:[A1]

这符合栈的特点,即后入先出,也符合一般人的思考逻辑,及返回键返回到之前的页面.

但是这样的结构有一个局限性,这样启动的activity都是我们通过Activity.startActivity(intent)这种方式启动的,是属于全屏的.

当我们只是想在一个页面的某个部分去启动一个activity,而且还保持这种层次结构,应该如何进行呢?

在ios平台上最基本的元素是ViewController和Controller对应的View,因此ios平台上提供了一个以UIVIEW为元素的栈来时限这样的功能,称为UINavigationController.这里不讨论它的使用,有兴趣的同学可以自己去学习.这里重点说明一下如何用ActivityGroup来实现类似的功能.


[java] view plain copy
  1. packagecom.zz;
  2. importjava.util.Stack;
  3. importjava.util.UUID;
  4. importandroid.app.ActivityGroup;
  5. importandroid.content.Intent;
  6. importandroid.os.Bundle;
  7. importandroid.view.KeyEvent;
  8. importandroid.view.View;
  9. importandroid.widget.LinearLayout;
  10. /**
  11. *各个Tab对应的Activity的父类
  12. *
  13. *@authorzhouzhe@lenovo-cw.com
  14. */
  15. publicabstractclassActivityStackextendsActivityGroup{
  16. /**一个activity的栈用来存放缓存的View*/
  17. Stack<StackElement>stack;
  18. @Override
  19. protectedvoidonCreate(BundlesavedInstanceState){
  20. super.onCreate(savedInstanceState);
  21. stack=newStack<StackElement>();
  22. }
  23. /**
  24. *一个抽象方法,返回一个LinearLayout实际上是一个区域用来展示栈内的view
  25. *
  26. *@return
  27. *@authorzhouzhe@lenovo-cw.com
  28. *@time2012-2-20
  29. */
  30. abstractLinearLayoutgetMainView();
  31. /**
  32. *用来向栈顶添加一个元素并显示
  33. *
  34. *@paramintent
  35. *跟启动activity的intent一样
  36. *@authorzhouzhe@lenovo-cw.com
  37. *@time2012-2-20
  38. */
  39. voidaddView(Intentintent){
  40. //生成一个字符串,作为启动activity的key,后面在移除了view以后,要通过这个key来finish对应的activity
  41. Stringstr=UUID.randomUUID().toString();
  42. getMainView().removeAllViews();
  43. Viewview=getLocalActivityManager().startActivity(str,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
  44. //注意layoutParams,否则会造成无法充满的问题
  45. getMainView().addView(view,newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT));
  46. getMainView().requestFocus();
  47. //生成一个栈内缓存对象,主要包括activity对应的view和对应的key,并压入栈中
  48. StackElementcomponent=newStackElement(str,view);
  49. stack.add(component);
  50. }
  51. /**
  52. *弹栈操作
  53. *
  54. *@return
  55. *@authorzhouzhe@lenovo-cw.com
  56. *@time2012-2-20
  57. */
  58. intpop(){
  59. //先判断是否已经是栈顶元素了
  60. intsize=stack.size();
  61. StackElementelement=null;
  62. if(size>1){
  63. //如果不是,获取到栈顶元素,并销毁.然后再获取当前的栈顶元素,显示到activityGroup
  64. element=stack.pop();
  65. getLocalActivityManager().destroyActivity(element.getTag(),true);
  66. element=stack.peek();
  67. }elseif(size==1){
  68. //如果是栈顶元素,直接显示
  69. element=stack.peek();
  70. }
  71. getMainView().removeAllViews();
  72. getMainView().addView(element.getView());
  73. getMainView().requestFocus();
  74. returnstack.size();
  75. }
  76. /**
  77. *清空Stack,仅保留最底层的view
  78. */
  79. voidclearStack(){
  80. intsize=stack.size();
  81. if(size>1){
  82. for(inti=0;i<size-1;i++){
  83. stack.pop();
  84. }
  85. }
  86. }
  87. voidclearAll(){
  88. intsize=stack.size();
  89. if(size>0){
  90. for(inti=0;i<size;i++){
  91. StackElementelement=stack.pop();
  92. getLocalActivityManager().destroyActivity(element.getTag(),true);
  93. }
  94. }
  95. }
  96. @Override
  97. protectedvoidonDestroy(){
  98. super.onDestroy();
  99. }
  100. @Override
  101. publicbooleandispatchKeyEvent(KeyEventevent){
  102. //对键盘事件的处理,如果当前activityGroup中已经载入了activity,则分发给子activity处理,如果没有则自己处理.
  103. if(getCurrentActivity()!=null){
  104. returngetCurrentActivity().dispatchKeyEvent(event);
  105. }else{
  106. returnsuper.dispatchKeyEvent(event);
  107. }
  108. }
  109. }

这是一个比较简单的类,简单说明一下流程.

activityGroup载入activity,A1的时候,使用addView方法,压入栈中.在加载A2的时候,还是调用activityStack的addView方法,移除A1,加入A2并压入栈中.在finish A2的时候,不能直接finish,这样整个activityGroup都被finish掉了.要调用activityStack的pop方法,移除栈顶元素,销毁,显示移除后的栈顶元素.同时要注意分发键盘的back事件,同样是要用pop方法取代默认的finish方法,这样即可完成一个类似于uinavigationcontroller的栈.


有兴趣的同学看一下吧.

源代码 http://download.csdn.net/detail/zz880329/4076318

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值