FragmentTabHost的使用

FragmentTabHost使用:

public class MainActivity extends BaseActivity implements View.OnClickListener {
    private LayoutInflater layoutInflater;
    private FragmentTabHost mTabHost;
    //定义数组存放Fragment
    private final Class fragmentArray[] = {IndexFragment.class, SortFragment.class, CarFragment.class, MyFragment.class};
   //定义数组存放图片(存放的是图片选择器包含连个状态 pressselected)
    private int mImageViewArray[] = {R.drawable.selector_rb_index, R.drawable.selector_rb_index, R.drawable.selector_rb_index, R.drawable.selector_rb_index};
    //Tab选项卡的文字
    private String mTextviewArray[] = {"首页", "分类", "购物车", "我的"};


    @Override
    protected int getContentView() {
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {
        mTabHost = (FragmentTabHost) findViewById(R.id.fragment_tabhost);
        layoutInflater = LayoutInflater.from(this);

    }

    @Override
    protected void initData() {
        initFragment();
    }


    @Override
    protected void setListener() {


    }

    /**
     * 初始化Fragment
     */
    private void initFragment() {
        mTabHost.setup(this, getSupportFragmentManager(), R.id.fl_content);//设置替换哪个布局
        int fragmentCount = fragmentArray.length;
        for (int i = 0; i < fragmentCount; i++) {
            //为每一个Tab按钮设置图标、文字和内容
            TabHost.TabSpec tabSpec = mTabHost.newTabSpec(mTextviewArray[i]).setIndicator(getTabItemView(i));
            //Tab按钮添加进Tab选项卡中
            mTabHost.addTab(tabSpec, fragmentArray[i], null);
            mTabHost.getTabWidget().setDividerDrawable(null);//设置每个TabView的控件
//            View view = mTabHost.getTabWidget().getChildAt(i);
//            view.setId(i);
//            view.setOnClickListener(this);// 此事件会消费,原生的点击事件,所以得自己处理
        }

    }

    /**
     * 设置每个Item的布局
     *
     * @return
     */
    private View getTabItemView(int index) {
        View view = layoutInflater.inflate(R.layout.item_tab_view, null);
        ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
        imageView.setImageResource(mImageViewArray[index]);
        TextView textView = (TextView) view.findViewById(R.id.textview);
        textView.setText(mTextviewArray[index]);
        return view;
    }
activity_man布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>

    <android.support.v4.app.FragmentTabHost
        android:id="@+id/fragment_tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />


</RelativeLayout>
FragmentTabHost缺点

点击按钮的切换tab的时候,它会把之前的那个Fragment销毁掉,现在显示的这个重新的创建
解决方法:用下面的 TabFragmentHost,这个点击按钮切换tab的时候,只会创建一次
解决办法:
重写 FragmentTabHost
package com.qiyuan.congmingtou.fragment;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TabWidget;

import java.util.ArrayList;

/**
 * Special TabHost that allows the use of {@link Fragment} objects for its tab
 * content. When placing this in a view hierarchy, after inflating the hierarchy
 * you must call {@link #setup(Context, FragmentManager, int)} to complete the
 * initialization of the tab host.
 * 
 * <p>
 * Here is a simple example of using a FragmentTabHost in an Activity:
 * 
 * {@sample
 * development/samples/Support4Demos/src/com/example/android/supportv4/app/
 * FragmentTabs.java complete}
 * 
 * <p>
 * This can also be used inside of a fragment through fragment nesting:
 * 
 * {@sample
 * development/samples/Support4Demos/src/com/example/android/supportv4/app/
 * FragmentTabsFragmentSupport.java complete}
 */
public class TabFragmentHost extends TabHost implements
      TabHost.OnTabChangeListener {
   private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
   private FrameLayout mRealTabContent;
   private Context mContext;
   private FragmentManager mFragmentManager;
   private int mContainerId;
   private TabHost.OnTabChangeListener mOnTabChangeListener;
   private TabInfo mLastTab;
   private boolean mAttached;

   static final class TabInfo {
      private final String tag;
      private final Class<?> clss;
      private final Bundle args;
      private Fragment fragment;

      TabInfo(String _tag, Class<?> _class, Bundle _args) {
         tag = _tag;
         clss = _class;
         args = _args;
      }
   }

   static class DummyTabFactory implements TabHost.TabContentFactory {
      private final Context mContext;

      public DummyTabFactory(Context context) {
         mContext = context;
      }

      @Override
      public View createTabContent(String tag) {
         View v = new View(mContext);
         v.setMinimumWidth(0);
         v.setMinimumHeight(0);
         return v;
      }
   }

   static class SavedState extends BaseSavedState {
      String curTab;

      SavedState(Parcelable superState) {
         super(superState);
      }

      private SavedState(Parcel in) {
         super(in);
         curTab = in.readString();
      }

      @Override
      public void writeToParcel(Parcel out, int flags) {
         super.writeToParcel(out, flags);
         out.writeString(curTab);
      }

      @Override
      public String toString() {
         return "FragmentTabHost.SavedState{"
               + Integer.toHexString(System.identityHashCode(this))
               + " curTab=" + curTab + "}";
      }

      public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
         public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
         }

         public SavedState[] newArray(int size) {
            return new SavedState[size];
         }
      };
   }

   public TabFragmentHost(Context context) {
      // Note that we call through to the version that takes an AttributeSet,
      // because the simple Context construct can result in a broken object!
      super(context, null);
      initFragmentTabHost(context, null);
   }

   public TabFragmentHost(Context context, AttributeSet attrs) {
      super(context, attrs);
      initFragmentTabHost(context, attrs);
   }

   private void initFragmentTabHost(Context context, AttributeSet attrs) {
      TypedArray a = context.obtainStyledAttributes(attrs,
            new int[] { android.R.attr.inflatedId }, 0, 0);
      mContainerId = a.getResourceId(0, 0);
      a.recycle();

      super.setOnTabChangedListener(this);
   }

   private void ensureHierarchy(Context context) {
      // If owner hasn't made its own view hierarchy, then as a convenience
      // we will construct a standard one here.
      if (findViewById(android.R.id.tabs) == null) {
         LinearLayout ll = new LinearLayout(context);
         ll.setOrientation(LinearLayout.VERTICAL);
         addView(ll, new FrameLayout.LayoutParams(
               ViewGroup.LayoutParams.MATCH_PARENT,
               ViewGroup.LayoutParams.MATCH_PARENT));

         TabWidget tw = new TabWidget(context);
         tw.setId(android.R.id.tabs);
         tw.setOrientation(TabWidget.HORIZONTAL);
         ll.addView(tw, new LinearLayout.LayoutParams(
               ViewGroup.LayoutParams.MATCH_PARENT,
               ViewGroup.LayoutParams.WRAP_CONTENT, 0));

         FrameLayout fl = new FrameLayout(context);
         fl.setId(android.R.id.tabcontent);
         ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));

         mRealTabContent = fl = new FrameLayout(context);
         mRealTabContent.setId(mContainerId);
         ll.addView(fl, new LinearLayout.LayoutParams(
               LinearLayout.LayoutParams.MATCH_PARENT, 0, 1));
      }
   }

   /**
    * @deprecated Don't call the original TabHost setup, you must instead call
    *             {@link #setup(Context, FragmentManager)} or
    *             {@link #setup(Context, FragmentManager, int)}.
    */
   @Override
   @Deprecated
   public void setup() {
      throw new IllegalStateException(
            "Must call setup() that takes a Context and FragmentManager");
   }

   public void setup(Context context, FragmentManager manager) {
      ensureHierarchy(context); // Ensure views required by super.setup()
      super.setup();
      mContext = context;
      mFragmentManager = manager;
      ensureContent();
   }

   public void setup(Context context, FragmentManager manager, int containerId) {
      ensureHierarchy(context); // Ensure views required by super.setup()
      super.setup();
      mContext = context;
      mFragmentManager = manager;
      mContainerId = containerId;
      ensureContent();
      mRealTabContent.setId(containerId);

      // We must have an ID to be able to save/restore our state. If
      // the owner hasn't set one at this point, we will set it ourself.
      if (getId() == View.NO_ID) {
         setId(android.R.id.tabhost);
      }
   }

   private void ensureContent() {
      if (mRealTabContent == null) {
         mRealTabContent = (FrameLayout) findViewById(mContainerId);
         if (mRealTabContent == null) {
            throw new IllegalStateException(
                  "No tab content FrameLayout found for id "
                        + mContainerId);
         }
      }
   }

   @Override
   public void setOnTabChangedListener(OnTabChangeListener l) {
      mOnTabChangeListener = l;
   }

   public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
      tabSpec.setContent(new DummyTabFactory(mContext));
      String tag = tabSpec.getTag();

      TabInfo info = new TabInfo(tag, clss, args);

      if (mAttached) {
         // If we are already attached to the window, then check to make
         // sure this tab's fragment is inactive if it exists. This shouldn't
         // normally happen.
         info.fragment = mFragmentManager.findFragmentByTag(tag);
         if (info.fragment != null && !info.fragment.isDetached()) {
            FragmentTransaction ft = mFragmentManager.beginTransaction();
            // ft.detach(info.fragment);
            ft.hide(info.fragment);
            ft.commit();
         }
      }

      mTabs.add(info);
      addTab(tabSpec);
   }

   @Override
   protected void onAttachedToWindow() {
      super.onAttachedToWindow();

      String currentTab = getCurrentTabTag();

      // Go through all tabs and make sure their fragments match
      // the correct state.
      FragmentTransaction ft = null;
      for (int i = 0; i < mTabs.size(); i++) {
         TabInfo tab = mTabs.get(i);
         tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);
         // if (tab.fragment != null && !tab.fragment.isDetached()) {
         if (tab.fragment != null) {
            if (tab.tag.equals(currentTab)) {
               // The fragment for this tab is already there and
               // active, and it is what we really want to have
               // as the current tab. Nothing to do.
               mLastTab = tab;
            } else {
               // This fragment was restored in the active state,
               // but is not the current tab. Deactivate it.
               if (ft == null) {
                  ft = mFragmentManager.beginTransaction();
               }
               // ft.detach(tab.fragment);
               ft.hide(tab.fragment);
            }
         }
      }

      // We are now ready to go. Make sure we are switched to the
      // correct tab.
      mAttached = true;
      ft = doTabChanged(currentTab, ft);
      if (ft != null) {
         ft.commitAllowingStateLoss();
         mFragmentManager.executePendingTransactions();
      }
   }

   @Override
   protected void onDetachedFromWindow() {
      super.onDetachedFromWindow();
      mAttached = false;
   }

   @Override
   protected Parcelable onSaveInstanceState() {
      Parcelable superState = super.onSaveInstanceState();
      SavedState ss = new SavedState(superState);
      ss.curTab = getCurrentTabTag();
      return ss;
   }

   @Override
   protected void onRestoreInstanceState(Parcelable state) {
      SavedState ss = (SavedState) state;
      super.onRestoreInstanceState(ss.getSuperState());
      setCurrentTabByTag(ss.curTab);
   }

   @Override
   public void onTabChanged(String tabId) {
      if (mAttached) {
         FragmentTransaction ft = doTabChanged(tabId, null);
         if (ft != null) {
            ft.commit();
         }
      }
      if (mOnTabChangeListener != null) {
         mOnTabChangeListener.onTabChanged(tabId);
      }
   }

   private FragmentTransaction doTabChanged(String tabId,
         FragmentTransaction ft) {
      TabInfo newTab = null;
      for (int i = 0; i < mTabs.size(); i++) {
         TabInfo tab = mTabs.get(i);
         if (tab.tag.equals(tabId)) {
            newTab = tab;
         }
      }
      if (newTab == null) {
         throw new IllegalStateException("No tab known for tag " + tabId);
      }
      if (mLastTab != newTab) {
         if (ft == null) {
            ft = mFragmentManager.beginTransaction();
         }
         if (mLastTab != null) {
            if (mLastTab.fragment != null) {
               // detach替换为hide,隐藏Fragment
               // ft.detach(mLastTab.fragment);
               ft.hide(mLastTab.fragment);
            }
         }
         if (newTab != null) {
            if (newTab.fragment == null) {
               newTab.fragment = Fragment.instantiate(mContext,
                     newTab.clss.getName(), newTab.args);
               ft.add(mContainerId, newTab.fragment, newTab.tag);
            } else {
               // attach替换为show,显示Fragment
               // ft.attach(newTab.fragment);
               ft.show(newTab.fragment);
            }
         }

         mLastTab = newTab;
      }
      return ft;
   }
}

 
FragmentTabHost还有一个缺点:就是切换tab的时候的事件,是点击后触发的。如果用户再切换tab的时候,需要做判断,这个体验就不是很好了。

解决办法

/**
 * 初始化Fragment
 */
private void initFragment() {
    mTabHost.setup(this, getSupportFragmentManager(), R.id.fl_content);//设置替换哪个布局
    int fragmentCount = fragmentArray.length;
    for (int i = 0; i < fragmentCount; i++) {
        //为每一个Tab按钮设置图标、文字和内容
        TabHost.TabSpec tabSpec = mTabHost.newTabSpec(mTextviewArray[i]).setIndicator(getTabItemView(i));
        //Tab按钮添加进Tab选项卡中
        mTabHost.addTab(tabSpec, fragmentArray[i], null);
        mTabHost.getTabWidget().setDividerDrawable(null);//设置每个TabView的控件
        View view = mTabHost.getTabWidget().getChildAt(i);
        view.setId(i);
        view.setOnClickListener(this);// 此事件会消费,原生的点击事件,所以得自己处理
    }

}
/**
 * 设置当前的Tab
 */
public void setCurrentTab(int index) {
    mTabHost.setCurrentTab(index);

}
  @Override
    public void onClick(View v) {
        setCurrentTab(v.getId());
//        switch (v.getId()){
//            case 0:
//                break;
//        }
    }

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值