在工作中,我们或许会遇到不同角色登录时候,因为不同的角色,所以也就有不同的权限,那么他所看到的角色菜单也就完全不一样,效果如下:
不多说,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 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 CREATOR = new Creator() {
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 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 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
周五了,回家!