主流移动应用开发框架(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>


其中跳转到两个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 };@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
原创粉丝点击