本人原创,转载请注明:http://blog.csdn.net/fzh0803/archive/2011/06/21/6559239.aspx
上节分析了TabHost,这节接着分析TabWidget.
TabWidget比较简单,它继承自LinearLayout,用来放标签。它覆盖了addView(View child)来实现添加一个标签。在没有指定view的LayoutParams时它默认给标签加上高度充满TabWidget,宽度上根据标签个数平分的LayoutParams,这样,如果在添加标签时没有设定LayoutParams的时候就会看到标签平均分布的情况。然后再根据有没有dividerDrawable来判断是否添加,这个dividerDrawable应该是标签之间的那个图片。TabWidget规定的较固定,使用起来的时候有可能很不美观,实际上看到网上有人说用TabActivity还不如用Gallery,这句话有一定道理,如果不需要把一个activity作为一个view嵌入进去的话使用Gallery的确更美观更炫,但存在就有道理,我想TabActivity真正存在的原因就是为了embeded activity,即把activity做为一个view加入到另一个actvity中,而又有LocalActivityManger来控制activity的生命周期所以不必操心生命周期问题。由于TabWidget的布局较为固定,所以可能会导致看起来不美观,有需要根据需求定制自己的TabWidget的需要(比如我自己就在TabWidget中间加入空隙,使它看起来有标签被分组了的效果),在修改的时候需要注意两个函数:getChildTabViewAt(int index)和getTabCount(),由于系统本身的view排布要么全部是标签,要么一个dividerDrawable加一个标签的排布,所以这两个函数实现较为简单,如果定制自己的TabWidget的话可能需要修改这两个函数,会稍微复杂点。
LocalActivityManager的话主要看一个函数startActivity(String id, Intent intent),因为String型的id是用来标识一个activity的,所以在addTab()的时候不能让tab tag重。因为TabActivity中当点击内容是activity的标签时就会调用startActivity()来获取view,而在启动的时候根据Intent的Flags处理有所不同,所以设置IntentFlags的时候需要注意,(以下此段来自个人翻译,英语水平差如又错误请见谅)如果在调用startActivty()的时候这个id 下已经有一个activity被启动了的话,那么根据不同情况它要么被destroy然后再重新创建一个然后启动,要么就直接使用它。原文和翻译如下:
/**
* Start a new activity running in the group. Every activity you start
* must have a unique string ID associated with it -- this is used to keep
* track of the activity, so that if you later call startActivity() again
* on it the same activity object will be retained.
*
*启动一个运行在group的新的activity.每一个启动的actvity必须拥有
*一个唯一的string ID,它被用来记录activity的踪迹,所以如果下次
*再次调用startActivity() 的时候,相同的activity 对象将被保留下来。
*
* <p>When there had previously been an activity started under this id,
* it may either be destroyed and a new one started, or the current
* one re-used, based on these conditions, in order:</p>
*
*如果在这个id下已经有一个activity启动了的话,那根据不同情况
*它要么被destroyed掉然后启动一个新的,要么当前存在的这个
*被重新使用,按以下顺序:
* <ul>
* <li> If the Intent maps to a different activity component than is
* currently running, the current activity is finished and a new one
* started.
*
*如果intent映射到跟当前运行的不同的 activity commponent(包名)
*的话,当前的activity会被结束掉然后一个新的会被启动。
*
* <li> If the current activity uses a non-multiple launch mode (such
* as singleTop), or the Intent has the
* {@link Intent#FLAG_ACTIVITY_SINGLE_TOP} flag set, then the current
* activity will remain running and its
* {@link Activity#onNewIntent(Intent) Activity.onNewIntent()} method
* called.
*
* 如果当前的activity用了不是多运行的模式(比如 singleTop),
* 或者intent 设置了 FLAG_ACTIVITY_SINGLE_TOP,那么当前的activity
* 仍旧会继续运行并且会调用 Activity.onNewIntent().
*
* <li> If the new Intent is the same (excluding extras) as the previous
* one, and the new Intent does not have the
* {@link Intent#FLAG_ACTIVITY_CLEAR_TOP} set, then the current activity
* will remain running as-is.
* <li> Otherwise, the current activity will be finished and a new
* one started.
* </ul>
*
* 如果新的intent(不包括 extras)和以前的完全一样,并且没有设置
* FLAG_ACTIVITY_CLEAR_TOP ,那么当前的 actvity 仍然会继续运行。
*否则(其他情况下),当前的activity会被结束掉然后启动一个新的activity。