android TabHost基础讲解

来源:互联网 发布:c 编程小游戏 编辑:程序博客网 时间:2024/05/16 19:45

        看到这个题目,我想做andorid开发有段时间的朋友对之在熟悉不过了,不过我之前开发Tab分栏的都是用ActivityGroup模拟实现的.其实原理上和TabHost差不多:都是用LocalActivityManager.startActivity(),获取目标的window将之转化为view,最后显示出来.

      其实最合理的是TabActivity+TabHost实现分栏效果,但是我之前一直没有用过,即使用的话,也是copy之paste之,主要是自己对其具体实现不了解,因此在这里我仔细看下下TabHost的实现过程,不过这个控件有点过时了,在SDK3.0后出现了Fragment将之代替.总之算是弥补下之前开发中的过失吧.

      源码分析:

      首先Activity要继承自TabActivity而TabActivity是继承自ActivityGroup这才是关键所在.

      而TabHost其实是继承自FrameLayout的子类.在开发中我们首先要获取当前的TabHost:getTabHost()

下面我们跟下源码:

TabActivity:

/**     * Returns the {@link TabHost} the activity is using to host its tabs.     *     * @return the {@link TabHost} the activity is using to host its tabs.     */    public TabHost getTabHost() {        ensureTabHost();        return mTabHost;    }
   private void ensureTabHost() {        if (mTabHost == null) {            this.setContentView(com.android.internal.R.layout.tab_content);        }    }

 /**     * Updates the screen state (current list and other views) when the     * content changes.     *      *@see Activity#onContentChanged()     */    @Override    public void onContentChanged() {        super.onContentChanged();        mTabHost = (TabHost) findViewById(com.android.internal.R.id.tabhost);        if (mTabHost == null) {            throw new RuntimeException(                    "Your content must have a TabHost whose id attribute is " +                    "'android.R.id.tabhost'");        }        mTabHost.setup(getLocalActivityManager());    }
执行过程大致流程:首先我们进行setContentView();这个时候就会回调PhoneWindow里面的setContentView()方法,然后在回调执行TabActivity中的onContentChange方法.

总之要说的是在我们getTabHost()时候就是获取到的我们自定义xml中的TabHost控件.只是过程有点绕了而已.

TabWidget继承是LinearLayout布局.

TabSpec 类:

public class TabSpec {        private String mTag;        private IndicatorStrategy mIndicatorStrategy;        private ContentStrategy mContentStrategy;        private TabSpec(String tag) {            mTag = tag;        }        /**         * Specify a label as the tab indicator.         */        public TabSpec setIndicator(CharSequence label) {            mIndicatorStrategy = new LabelIndicatorStrategy(label);            return this;        }        /**         * Specify a label and icon as the tab indicator.         */        public TabSpec setIndicator(CharSequence label, Drawable icon) {            mIndicatorStrategy = new LabelAndIconIndicatorStrategy(label, icon);            return this;        }        /**         * Specify a view as the tab indicator.         */        public TabSpec setIndicator(View view) {            mIndicatorStrategy = new ViewIndicatorStrategy(view);            return this;        }        /**         * Specify the id of the view that should be used as the content         * of the tab.         */        public TabSpec setContent(int viewId) {            mContentStrategy = new ViewIdContentStrategy(viewId);            return this;        }        /**         * Specify a {@link android.widget.TabHost.TabContentFactory} to use to         * create the content of the tab.         */        public TabSpec setContent(TabContentFactory contentFactory) {            mContentStrategy = new FactoryContentStrategy(mTag, contentFactory);            return this;        }        /**         * Specify an intent to use to launch an activity as the tab content.         */        public TabSpec setContent(Intent intent) {            mContentStrategy = new IntentContentStrategy(mTag, intent);            return this;        }        public String getTag() {            return mTag;        }    }


  /**     * Specifies what you do to create a tab indicator.     */    private static interface IndicatorStrategy {        /**         * Return the view for the indicator.         */        View createIndicatorView();    }


/**     * Specifies what you do to manage the tab content.     */    private static interface ContentStrategy {        /**         * Return the content view.  The view should may be cached locally.         */        View getContentView();        /**         * Perhaps do something when the tab associated with this content has         * been closed (i.e make it invisible, or remove it).         */        void tabClosed();    }

简单说明:

TabSpec一个普通的类,mTag,mIndicatorStrategy(他是一个接口:获得指示器的View),mContentStrategy(他也是个接口,获得content部分)

我们创建了一个TabSpec。

TabHost.TabSpec tabSpec = getTabHost().newTabSpec("");//创建一个指示器

设置Tab图标部分(重载函数):

1.setIndicator(CharSequence label);//引用系统的资源文件(无图片).

2.setIndicator(CharSequence label, Drawable icon)//引用系统的资源文件(包含图片);

3.setIndicator(View view);//引用自定义的资源文件,效果自己决定.

设置内容部分(重载函数):

1.setContent(int viewId);//这个viewid指的是你在tabcontent(布局文件FramLayout)中的孩子布局id.

2.setContent(TabContentFactory contentFactory);//实现这个TabContentFactory中的createTabContent方法,及返回的视图view. 

3.setContent(Intent intent);//通过LocalActivityManager加载itnent对应Activity将之转为view.

最后我们将创建好的TabHost.TabSpec--add到TabHost中.

根据传入不同的参数决定实现不同的接口.不明白的可以参看源码.


PS:上面onContentChanged这个回调函数中:mTabHost.setup(getLocalActivityManager());这句话才真正的对该控件的初始化也就是show出来.

最常用的是:setIndicator(View view)和setContent(Intent intent).

就写到这里,网上例子也很多,你们可以自行查找.这里只是简单说明下原理.



原创粉丝点击