美文网首页
FragmentTabHost+Fragment随意配置菜单数量

FragmentTabHost+Fragment随意配置菜单数量

作者: 罗罗罗罗罗sky | 来源:发表于2016-07-08 19:07 被阅读621次

    在工作中,我们或许会遇到不同角色登录时候,因为不同的角色,所以也就有不同的权限,那么他所看到的角色菜单也就完全不一样,效果如下:

    ![QQ截图20160708180418.png](https://img.haomeiwen.com/i2310529/dc88de673cd788d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    不多说,Code如下:

    package com.micro.Uncertain;
    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;
    
    public class FragmentTabHost extends TabHost implements TabHost.OnTabChangeListener {    
        private final ArrayList<TabInfo> mTabs = new ArrayList<>(); //Tab集合
        private FrameLayout mRealTabContent;
        private Context mContext;  
        private FragmentManager mFragmentManager; 
        private int mContainerId;
        private OnTabChangeListener mOnTabChangeListener;
        private TabInfo mLastTab;
        private boolean mAttached;
    
      /***  TabInfo结构体  ***/
      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;
            } 
       }  
    
      //可在createTabContent设置创建Tab内容区域View的相关属性
      static class DummyTabFactory implements 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; 
           }   
     }   
    
      //保存View相关的State
     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 Creator<SavedState> CREATOR = new Creator<SavedState>() {  
              public SavedState createFromParcel(Parcel in) {  
                  return new SavedState(in); 
               }   
             public SavedState[] newArray(int size) {  
                  return new SavedState[size]; 
               }   
         };   
     } 
    
     //构造方法
       public FragmentTabHost(Context context) { 
           super(context, null);  
          initFragmentTabHost(context, null);
        }   
    
       public FragmentTabHost(Context context, AttributeSet attrs) { 
           super(context, attrs);  
          initFragmentTabHost(context, attrs); 
       }  
    
       //初始化Fragment  TabHost 并设置TabChangeListener
        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 (findViewById(android.R.id.tabs) == null) {  
              LinearLayout ll = new LinearLayout(context);
              ll.setOrientation(LinearLayout.VERTICAL); 
              addView(ll, new 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)); 
           }
        } 
    
       @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); 
           super.setup();  
           mContext = context; 
           mFragmentManager = manager; 
           ensureContent();  
      }    
    
    public void setup(Context context, FragmentManager manager, int containerId) { 
           ensureHierarchy(context);  
           super.setup();   
           mContext = context;   
           mFragmentManager = manager; 
           mContainerId = containerId; 
           ensureContent();    
          mRealTabContent.setId(containerId);  
          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;  
      }    
    
    //添加Tab
    public void addTab(TabSpec tabSpec, Class<?> clss, Bundle args) {
            tabSpec.setContent(new DummyTabFactory(mContext));   
         String tag = tabSpec.getTag();   
         TabInfo info = new TabInfo(tag, clss, args); 
           if (mAttached) { 
               info.fragment = mFragmentManager.findFragmentByTag(tag);  
              if (info.fragment != null && !info.fragment.isDetached()) {   
                 FragmentTransaction ft = mFragmentManager.beginTransaction();
                    ft.hide(info.fragment);    
                ft.commit();       
         } 
           } 
           mTabs.add(info); 
           addTab(tabSpec);  
      }   
    
     @Override  
      protected void onAttachedToWindow() {
            super.onAttachedToWindow(); 
           String currentTab = getCurrentTabTag(); 
           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) {    
                       if (tab.tag.equals(currentTab)) {    
                        mLastTab = tab;      
                   } else {       
                       if (ft == null) { 
                           ft = mFragmentManager.beginTransaction();    
                    }        
                   ft.hide(tab.fragment); 
                   }          
           }   
         }   
           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);   
         }    
    }  
    
     //Tab变化
      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) {    
                     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 {    
                    ft.show(newTab.fragment);  
                  }       
         }           
            mLastTab = newTab;  
          }    
        return ft;  
      }
    }
    

    相信从上面的代码也可以大致了解了FragmentTabHost。由于Fragment的出现,TabHost的过时,它相当于替换了TabHost,它会对所添加的fragment进行管理,保存栈信息和恢复栈信息等一切操作,比如我的fragment内部有三个子fragment,我退出该fragment的时候开启的是第二个子fragment,下次我再进入该fragment的时候依然会开启第二个子fragment,且看 FragmentTabHost源码中对保存,相信已经留意到了上面代码中的onRestoreInstanceState()函数和onSaveInstanceState()函数。闲话少说我们继续来看我们主页面MainActivity中的实现:

    package com.micro.Uncertain;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TabHost;
    import android.widget.TextView;
    import com.google.gson.Gson;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity extends AppCompatActivity {
        private static final int MAX_BOTTOM = 5; 
        private FragmentTabHost tabhost;
        private List<FuncEntity> funcEntities;//底部菜单
        private String menuStr="{\"funcList\":[{\"name\":\"报表\",\"code\":\"dky_2\"},{\"name\":\"商城\",\"code\":\"dky_3\"},{\"name\":\"分销\",\"code\":\"dky_5\"},{\"name\":\"任务\",\"code\":\"dky_4\"}]}"; 
    
       @Override   
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main); 
            tabhost = (FragmentTabHost) findViewById(android.R.id.tabhost);
            tabhost.setup(this, getSupportFragmentManager(), R.id.fl_content); 
            UserLoginEntity entity = new Gson().fromJson(menuStr, UserLoginEntity.class); 
            if (entity!=null)  
              {       
                funcEntities=entity.funcList;    
            }    
             initBottomTab(); 
        }   
    
      /**     * 初始化底部菜单     */   
          private void initBottomTab() { 
           List<TabEntity> entities = new ArrayList<>(); 
           TabEntity tabEntity = null; 
           for (int i = 0; i < funcEntities.size(); i++) {  
              if (i >= MAX_BOTTOM) {
                    break; 
            }  
            FuncEntity entity = funcEntities.get(i);  
              switch (entity.code) { 
                   case Constants.DKY_1: 
                       tabEntity = new TabEntity(StoreFragment.class, R.drawable.bottom_sotre_selector, getString(R.string.store));
                        break;
                    case Constants.DKY_2:
                        tabEntity = new TabEntity(ReportFragement.class, R.drawable.bottom_report_selector, getString(R.string.report_form)); 
                       break; 
                   case Constants.DKY_3:  
                      tabEntity = new TabEntity(MallFragment.class, R.drawable.bottom_mall_selector, getString(R.string.mall));   
                     break;       
                    case Constants.DKY_4:
                        tabEntity = new TabEntity(TaskFragment.class, R.drawable.bottom_task_selector, getString(R.string.task)); 
                       break;   
                     case Constants.DKY_5:   
                     tabEntity = new TabEntity(DistributionFragment.class, R.drawable.bottom_distirbution_selector, getString(R.string.distribution)); 
                       break;              
                      case Constants.DKY_6:  
                      tabEntity = new TabEntity(PurchaseFragment.class, R.drawable.bottom_purchase_selector, getString(R.string.purchase));  
                      break; 
               }     
             entities.add(tabEntity);
            }      
     
       for (TabEntity entity : entities) { 
               TabHost.TabSpec tabSpec = tabhost.newTabSpec(entity.getBottomContent()); 
               tabSpec.setIndicator(initIndicator(entity));
                tabhost.addTab(tabSpec, entity.getFragment(), null);
            }        
           tabhost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE); 
           setCurrentIndex("0"); 
       } 
     
      /**     
      * 选择index    
      *    
      * @param index
      */
    
        private void setCurrentIndex(String index) { 
           for (int i = 0, size = funcEntities.size() > MAX_BOTTOM ? MAX_BOTTOM : funcEntities.size(); i < size; i++) {     
           if (funcEntities.get(i).code.equals(index)) {
                    tabhost.setCurrentTab(i);
                    break;    
               }
            } 
       } 
    
       /**
         * 初始化底部bottom    
         * 
         * @param entity 
         * @return 
        */  
      private View initIndicator(TabEntity entity) {  
          View view = getLayoutInflater().inflate(R.layout.tab_view, null);
            ImageView tab_image = (ImageView) view.findViewById(R.id.tab_image);  
           TextView tab_text = (TextView) view.findViewById(R.id.tab_text);  
           tab_image.setBackgroundResource(entity.getIcon()); 
            tab_text.setText(entity.getBottomContent());  
           return view; 
       }
    }
    

    以上就是主页中的代码,可以根据得到的menuStr来解析判断当前的菜单的数量,当然也要对其底部菜单的数量进行一个限制,因为数量太大之后,初始化的个数相对来说也就越多,在其底部显示比较紧密。
    实现底部菜单数量随意配置,当然不止这一种方法,比如自定义底部菜单为自定义Linearlayout,通过菜单数量addView()方法实现,再给View添加点击事件,通过View的index和Fragment绑定,Fragment使用add或者replace实现:
    源代码:https://pan.baidu.com/s/1kVGXz6Z
    周五了,回家!

    相关文章

      网友评论

          本文标题:FragmentTabHost+Fragment随意配置菜单数量

          本文链接:https://www.haomeiwen.com/subject/brrrjttx.html