android TabHost基础讲解

        看到这个题目,我想做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).

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值