备注:今天有空研究了一下fragmentTabHost实现底部菜单栏效果,点击和滑动的效果均已经实现,demo中注释掉的是仅仅点击情况下的效果,如果你点击和滑动两种情况都需要,那么请源码照搬,如果仅仅需要点击切换页面,那么可以把文中注释掉的demo释放,再将相关的viewPager方法注释掉就行。本文中实现的是类似于微信那样既可以点击,也可以滑动~~~
1.布局
1.1底部菜单每一个Tab的布局:tab_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingTop="4dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"
android:src="@drawable/tab_conversations"//是一个布局选择器,点击时展示自己需要的图片或背景
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/title"
android:text="首页"
android:gravity="center"
android:textSize="14sp"
android:textColor="@drawable/tab_title_color"//也是一个布局选择器
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
1.2 简单写一个背景选择器selector(其他类似):tab_conversations.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/ic_chat_01"></item> <item android:drawable="@drawable/ic_chat_02"></item> </selector>
1.3 activity的布局:activity_main.xml:(注:文中注释掉的是单纯的点击实现切换,需要的同鞋自行修改)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<FrameLayout
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!--<FrameLayout-->
<!--android:id="@+id/container_fragment"-->
<!--android:layout_width="fill_parent"-->
<!--android:layout_height="0dip"-->
<!--android:layout_weight="1" />-->
<!--<!–分割线–>-->
<!--<View-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="1px"-->
<!--android:background="#dcdcdc"-->
<!--/>-->
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black" >
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
2.适配器:FragmentTabAdapter.java:
public class FragmentTabAdapter extends FragmentPagerAdapter { private List<Fragment> mFragmentList; public FragmentTabAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void setData(List<Fragment> mFragmentList){ this.mFragmentList = mFragmentList; notifyDataSetChanged(); } }
3.MainActivity的写法:(再次强调:本文是实现了点击切换和滑动切换!!!仅仅实现点击切换的同鞋,释放文中注释掉的demo,并且注释viewPager相关的demo)
public class MainActivity extends AppCompatActivity { private FragmentTabHost mTabHost; private ViewPager mViewPager; private List<Fragment> mFragmentList; private FragmentTabAdapter mAdapter; private int currentPosition; private FragmentManager fragmentManager; private Class mClass[] = {ConversationFragment.class, ContactsFragment.class, SettingFragment.class}; private Fragment mFragment[] = {new ConversationFragment(),new ContactsFragment(),new SettingFragment()}; private String mTitles[] = {"会话", "联系人", "设置"}; private int mImages[] = { R.drawable.tab_conversations, R.drawable.tab_contacts, R.drawable.tab_setting, }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); setDataToUI(); initEventListener(); } private void initEventListener() { mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() { @Override public void onTabChanged(String tabId) { mViewPager.setCurrentItem(mTabHost.getCurrentTab()); } }); mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { TabWidget widget = mTabHost.getTabWidget(); int oldFocusability = widget.getDescendantFocusability(); widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); mTabHost.setCurrentTab(position); widget.setDescendantFocusability(oldFocusability); mTabHost.getTabWidget().getChildAt(position) .setBackgroundColor(Color.GRAY); } @Override public void onPageScrollStateChanged(int state) { } }); }
private void setDataToUI() { mTabHost.setup(this,getSupportFragmentManager(),R.id.view_pager); // mTabHost.setup(this,getSupportFragmentManager(),R.id.container_fragment); mTabHost.getTabWidget().setDividerDrawable(null); for (int i = 0;i < mClass.length;i++){ TabHost.TabSpec tabSpec = mTabHost.newTabSpec(mTitles[i]).setIndicator(getTabView(i)); mTabHost.addTab(tabSpec,mClass[i],null); mTabHost.setTag(i); Log.d("wang","mClass==========="+ mClass[i].toString()); mFragmentList.add(mFragment[i]); Log.d("wang","mFragmentList[i]==========="+ mFragment[i].toString()); mTabHost.getTabWidget().getChildAt(i).setBackgroundColor(Color.GRAY); } Log.d("wang","mFragmentLists==========="+ mFragmentList.size()); mAdapter.setData(mFragmentList); mViewPager.setAdapter(mAdapter); } private View getTabView(int i) { View view = LayoutInflater.from(this).inflate(R.layout.tab_item,null); ImageView image = (ImageView) view.findViewById(R.id.image); TextView title = (TextView) view.findViewById(R.id.title); image.setImageResource(mImages[i]); title.setText(mTitles[i]); return view; } private void initView() { mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); mViewPager = (ViewPager) findViewById(R.id.view_pager); mFragmentList = new ArrayList<Fragment>(); mAdapter = new FragmentTabAdapter(getSupportFragmentManager()); fragmentManager = getSupportFragmentManager(); } // 选择Fragment /* private void switchFragment(int target) { if (target != currentPosition) { Fragment targetFragment = mFragmentList.get(target);// 目标Fragment Fragment currentFragment = mFragmentList.get(currentPosition);// 当前Fragment if (!targetFragment.isAdded()) fragmentManager.beginTransaction().add(android.R.id.tabcontent, targetFragment).hide(currentFragment).commit(); else fragmentManager.beginTransaction().show(targetFragment).hide(currentFragment).commit(); // 记录当前fragment位置 currentPosition = target; } }*/
4.最后再简单贴一个fragment:其余fragment都一样
总结:这是自己为了练手和学习,自己亲自尝试勒一下,比较麻烦,如果需要快速开发的同学,想立马集成该框架,给大家推荐一个github上面的框架,个人感觉非常好用和简便,只需要往进填充数据即可,地址: https://github.com/chenpengfei88/TabContainerViewpublic class ConversationFragment extends Fragment { private View view; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //fangzhi每次FragmentTabHost切换fragment时会重新调用onCreateView()重新绘制UI。假如我们在onCreateView()中有网络操作,在切换的时候也会重复进行,这样当然不是我们希望的 if (view == null){ view = inflater.inflate(R.layout.conversation_main,container,false); } ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null){ parent.removeView(view); } return view; } }
5.最后看一下效果图:
源码下载