主流移动应用开发框架(2)——fragment+fragmenttabhost实现底部选项卡导航(可滑动切换)
2014-11-30 10:55
981 查看
Fragment对于我们来说可能并不陌生,在android3.0之后引进开发,对于处理平板大屏幕界面分布,fragment有着activity没有的优势,它“寄生”于activity解决了一个屏幕显示多个“分屏”的问题,管理同一个activity下多个“碎片”界面的布局显示及其数据交互。在3.0版本以下的开发环境,则需要导入V4到作为支持。
fragment的具体使用方法在这里并没有详细介绍,而主要要介绍是底部选项卡导航的实现,我们先看看效果图
实现参考了github上面的一些例子和网友的一些demo,附上自己的demo下载链接 点击打开链接
主界面代码
主界面布局代码
其中跳转到两个activity,一个是不支持滑动FragmentTab.java,一个是支持滑动FragmentTabSupportSlip.java
FragmentTab.java代码
对应布局xml
FragmentTabSupportSlip.java代码
其实现是通过viewpager设置fragment,底部采用单选按钮,通过样式控制实现效果图,单选按钮的监听实现切换fragment/而且在viewpager的监听器setOnCheckChangeListenter中也监听了单选按钮的所有监听了功能。
对应布局xml
里面对应跳转的四个fragment类对应tabFragmentOne.java TabFragmentTwo.java TabFragmentThree.java TabFragmentFour.java 布局比较简单,在onCreateView直接加载,具体见demo。如有疑问,欢迎一起探讨。
fragment的具体使用方法在这里并没有详细介绍,而主要要介绍是底部选项卡导航的实现,我们先看看效果图
实现参考了github上面的一些例子和网友的一些demo,附上自己的demo下载链接 点击打开链接
主界面代码
package com.example.fragmenttabhost; import com.example.fragmentbottommenu.R; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; /** * * @author yummy * email:yummyl.lau@gmail.com * 主菜单界面 */ public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button nosupport = (Button) findViewById(R.id.nosupport); Button support = (Button) findViewById(R.id.support); nosupport.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, FragmentTab.class); startActivity(intent); } }); support.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, FragmentTabSupportSlip.class); startActivity(intent); } }); } }
主界面布局代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:layout_centerInParent="true" android:id="@+id/nosupport" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="不支持滑动的菜单"/> <Button android:layout_below="@+id/nosupport" android:id="@+id/support" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="支持滑动的菜单" /> </RelativeLayout>
其中跳转到两个activity,一个是不支持滑动FragmentTab.java,一个是支持滑动FragmentTabSupportSlip.java
FragmentTab.java代码
package com.example.fragmenttabhost; import com.example.fragmentbottommenu.R; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTabHost; import android.view.Menu; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TabHost.TabSpec; /** * * @author yummy * email:yummyl.lau@gmail.com * */ public class FragmentTab extends FragmentActivity { private FragmentTabHost mTabHost; private RadioGroup mTabRg; private final Class[] fragments = { TabFragmentOne.class, TabFragmentTwo.class, TabFragmantThree.class, TabFragmentThree.class }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tab); initView(); } private void initView() { mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); // 得到fragment的个数 int count = fragments.length; for (int i = 0; i < count; i++) { // 为每一个Tab按钮设置图标、文字和内容 TabSpec tabSpec = mTabHost.newTabSpec(i + "").setIndicator(i + ""); // 将Tab按钮添加进Tab选项卡中 mTabHost.addTab(tabSpec, fragments[i], null); } mTabRg = (RadioGroup) findViewById(R.id.tab_rg_menu); mTabRg.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.tab_rb_1: mTabHost.setCurrentTab(0); break; case R.id.tab_rb_2: mTabHost.setCurrentTab(1); break; case R.id.tab_rb_3: mTabHost.setCurrentTab(2); break; case R.id.tab_rb_4: mTabHost.setCurrentTab(3); break; default: break; } } }); mTabHost.setCurrentTab(0); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }其实现是通过tabhost设置fragment,底部采用单选按钮,通过样式控制实现效果图,单选按钮的监听实现切换fragment。
对应布局xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:id="@+id/realtabcontent" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> <RadioGroup android:id="@+id/tab_rg_menu" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/mmfooter_bg" android:orientation="horizontal" > <RadioButton android:id="@+id/tab_rb_1" style="@style/tab_rb_style" android:checked="true" android:drawableTop="@drawable/tab_selector_weixing" android:text="微信" /> <RadioButton android:id="@+id/tab_rb_2" style="@style/tab_rb_style" android:drawableTop="@drawable/tab_selector_tongxunlu" android:text="通讯录" /> <RadioButton android:id="@+id/tab_rb_3" style="@style/tab_rb_style" android:drawableTop="@drawable/tab_selector_faxian" android:text="发现" /> <RadioButton android:id="@+id/tab_rb_4" style="@style/tab_rb_style" android:drawableTop="@drawable/tab_selector_wo" android:text="我" /> </RadioGroup> <android.support.v4.app.FragmentTabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" > <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0" /> </android.support.v4.app.FragmentTabHost> </LinearLayout>
FragmentTabSupportSlip.java代码
package com.example.fragmenttabhost; import java.util.ArrayList; import com.example.fragmentbottommenu.R; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentTabHost; import android.support.v4.view.ViewPager; import android.view.View; import android.view.ViewGroup; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.TabHost; import android.widget.TabHost.TabSpec; import android.widget.TabWidget; /** * * @author yummy * email:yummyl.lau@gmail.com * */ public class FragmentTabSupportSlip extends FragmentActivity { private FragmentTabHost mTabHost; private RadioGroup mTabRg; private ViewPager mViewPage; TabsAdapter mTabsAdapter; private final Class[] fragments = { TabFragmentOne.class, TabFragmentTwo.class, TabFragmantThree.class, TabFragmentThree.class }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tab_supportslip); initView(); if (savedInstanceState != null) { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); } } private void initView() { mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); mTabHost.setup(this, getSupportFragmentManager()); mViewPage = (ViewPager) findViewById(R.id.pager); mTabRg = (RadioGroup) findViewById(R.id.tab_rg_menu); mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPage, mTabRg); // 得到fragment的个数 int count = fragments.length; for (int i = 0; i < count; i++) { // 为每一个Tab按钮设置图标、文字和内容 TabSpec tabSpec = mTabHost.newTabSpec(i + "").setIndicator(i + ""); // 将Tab按钮添加进Tab选项卡中 mTabHost.addTab(tabSpec, fragments[i], null); mTabsAdapter.addTab(mTabHost.newTabSpec(i + "") .setIndicator(i + ""), fragments[i], null); } //定义滑动的监听 mTabRg.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.tab_rb_1: mTabHost.setCurrentTab(0); break; case R.id.tab_rb_2: mTabHost.setCurrentTab(1); break; case R.id.tab_rb_3: mTabHost.setCurrentTab(2); break; case R.id.tab_rb_4: mTabHost.setCurrentTab(3); break; default: break; } } }); // mTabHost.setCurrentTab(0); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("tab", mTabHost.getCurrentTabTag()); } /** * This is a helper class that implements the management of tabs and all * details of connecting a ViewPager with associated TabHost. It relies on a * trick. Normally a tab host has a simple API for supplying a View or * Intent that each tab will show. This is not sufficient for switching * between pages. So instead we make the content part of the tab host 0dp * high (it is not shown) and the TabsAdapter supplies its own dummy view to * show as the tab content. It listens to changes in tabs, and takes care of * switch to the correct paged in the ViewPager whenever the selected tab * changes. */ public static class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener { private final Context mContext; private final TabHost mTabHost; private final ViewPager mViewPager; private final RadioGroup mTabRg; private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); static final class TabInfo { private final String tag; private final Class<?> clss; private final Bundle args; 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; } } public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager, RadioGroup tabRg) { super(activity.getSupportFragmentManager()); mContext = activity; mTabHost = tabHost; mViewPager = pager; mTabRg = tabRg; mTabHost.setOnTabChangedListener(this); mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); } 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); mTabs.add(info); mTabHost.addTab(tabSpec); notifyDataSetChanged(); } @Override public int getCount() { return mTabs.size(); } @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); return Fragment.instantiate(mContext, info.clss.getName(), info.args); } @Override public void onTabChanged(String tabId) { int position = mTabHost.getCurrentTab(); mViewPager.setCurrentItem(position); ((RadioButton) mTabRg.getChildAt(position)).setChecked(true); } @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); } @Override public void onPageScrollStateChanged(int state) { } } }
其实现是通过viewpager设置fragment,底部采用单选按钮,通过样式控制实现效果图,单选按钮的监听实现切换fragment/而且在viewpager的监听器setOnCheckChangeListenter中也监听了单选按钮的所有监听了功能。
对应布局xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <RadioGroup android:id="@+id/tab_rg_menu" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/mmfooter_bg" android:orientation="horizontal" > <RadioButton android:id="@+id/tab_rb_1" style="@style/tab_rb_style" android:checked="true" android:drawableTop="@drawable/tab_selector_weixing" android:text="微信" /> <RadioButton android:id="@+id/tab_rb_2" style="@style/tab_rb_style" android:drawableTop="@drawable/tab_selector_tongxunlu" android:text="通讯录" /> <RadioButton android:id="@+id/tab_rb_3" style="@style/tab_rb_style" android:drawableTop="@drawable/tab_selector_faxian" android:text="发现" /> <RadioButton android:id="@+id/tab_rb_4" style="@style/tab_rb_style" android:drawableTop="@drawable/tab_selector_wo" android:text="我" /> </RadioGroup> <android.support.v4.app.FragmentTabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone" > <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0" /> </android.support.v4.app.FragmentTabHost> </LinearLayout>
里面对应跳转的四个fragment类对应tabFragmentOne.java TabFragmentTwo.java TabFragmentThree.java TabFragmentFour.java 布局比较简单,在onCreateView直接加载,具体见demo。如有疑问,欢迎一起探讨。
相关文章推荐
- FragmentTabHost+ViewPage实现底部导航窗口切换
- 基于Agile Lite开发框架实现底部导航切换页面
- 主流移动应用开发框架(1)——实现左右滑隐藏菜单的开源框架AndroidResideMenu二次开发
- FragmentTabHost实现底部导航栏和顶部滑动导航
- 安卓开发--应用市场的界面制作(一)--viewpager+fragment实现可滑动的底部导航栏
- 使用选项卡TabWidget与TabHost实现底部或者顶部四个分类按钮 点击切换对应的fragment
- Android 利用ViewPager实现底部圆点导航左右滑动效果以及Fragment页面切换
- 安卓开发笔记——TabHost组件(一)(实现底部菜单导航)
- 【Android UI设计与开发】第08期:底部菜单栏(三)Fragment+FragmentTabHost实现仿新浪微博底部菜单栏
- 安卓开发复习笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)
- 安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)
- 仿鲁大师界面(实现启动动画和TabHost选项卡切换时滑动动画)
- 【移动开发】Android中的底部菜单框架(Fragment) 推荐
- Fragment实现底部菜单栏以及选项卡之间的切换
- TabHost+ViewPager实现 点击选项卡和滑动界面都可以切换页面
- 【Android UI设计与开发】第08期:底部菜单栏(三)Fragment+FragmentTabHost实现仿新浪微博底部菜单栏
- Fragment实现底部选项卡切换效果
- 【简单项目框架一】Fragment实现的底部导航
- Fragment 搭建框架 实现 导航 切换
- Fragment实现底部选项卡切换效果