主流移动应用开发框架(2)——fragment+fragmenttabhost实现底部选项卡导航(可滑动切换)
来源:互联网 发布:linux安装make工具 编辑:程序博客网 时间:2024/05/18 13:08
Fragment对于我们来说可能并不陌生,在android3.0之后引进开发,对于处理平板大屏幕界面分布,fragment有着activity没有的优势,它“寄生”于activity解决了一个屏幕显示多个“分屏”的问题,管理同一个activity下多个“碎片”界面的布局显示及其数据交互。在3.0版本以下的开发环境,则需要导入V4到作为支持。
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 {@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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() {@Overridepublic void onClick(View v) { Intent intent = new Intent(MainActivity.this, FragmentTab.class); startActivity(intent);}});support.setOnClickListener(new OnClickListener() {@Overridepublic 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>
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 };@Overrideprotected 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() {@Overridepublic 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);}@Overridepublic 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 };@Overrideprotected 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() {@Overridepublic 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);}@Overrideprotected 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 implementsTabHost.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;}@Overridepublic 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();}@Overridepublic int getCount() {return mTabs.size();}@Overridepublic Fragment getItem(int position) {TabInfo info = mTabs.get(position);return Fragment.instantiate(mContext, info.clss.getName(),info.args);}@Overridepublic void onTabChanged(String tabId) {int position = mTabHost.getCurrentTab();mViewPager.setCurrentItem(position);((RadioButton) mTabRg.getChildAt(position)).setChecked(true);}@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {TabWidget widget = mTabHost.getTabWidget();int oldFocusability = widget.getDescendantFocusability();widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);mTabHost.setCurrentTab(position);widget.setDescendantFocusability(oldFocusability);}@Overridepublic 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。如有疑问,欢迎一起探讨。
4 0
- 主流移动应用开发框架(2)——fragment+fragmenttabhost实现底部选项卡导航(可滑动切换)
- android底部选项卡(二)FragmentTabHost +Fragment 实现
- 安卓开发--应用市场的界面制作(一)--viewpager+fragment实现可滑动的底部导航栏
- Android底部导航栏—FragmentTabHost+Fragment
- FragmentTabhost和Fragment实现底部导航栏
- FragmentTabHost+ViewPager+Fragment实现底部Tab导航
- FragmentTabHost+ViewPage实现底部导航窗口切换
- FragmentTabHost+Fragment实现底部菜单的切换
- Fragment实现底部选项卡切换效果
- Android底部导航栏——FragmentTabHost+ViewPager+Fragment
- 首页-底部Tab导航(菜单栏)的实现:FragmentTabHost+ViewPager+Fragment
- 首页-底部Tab导航(菜单栏)的实现:FragmentTabHost+ViewPager+Fragment
- Android典型界面设计——FragmentTabHost+Fragment实现底部tab切换
- FragmentTabHost实现底部导航栏和顶部滑动导航
- FragmentTabHost实现底部切换简单应用
- Android常见框架:启动页+ViewPager+Fragment+FragmentTabHost底部导航栏整合实现
- FragmentTabHost实现底部导航
- 底部导航栏:FragmentTabHost+Fragment
- hdu5120——Intersection
- WAMPServer介绍
- struts2开发一般流程
- 我的c++之路----匆匆而过的11月
- Vim 简介以及常用命令
- 主流移动应用开发框架(2)——fragment+fragmenttabhost实现底部选项卡导航(可滑动切换)
- VBA code of batch copy hyperlink address
- 第14周项目2.2 按同学姓名排序的成绩名单
- VS2010 MFC解决方案 工程更名工具 20150923_1500更新v1.3
- Nginx的学习资料
- C/C++中extern关键字详解
- C++ primer (第五版)课后题答案(九)
- 折腾二维数组
- android Content Provider 详解