Android项目开发实战之使用Fragment和FragmentTabHost搭建底部菜单(一)

学习在于实用,只有把自己学到的东西真正的融入到我们的开发中,并且使用的得心应手,那才是真正的掌握。而想把技术使用的得心应手并不是一蹴而就的,需要不断的巩固自己的知识体系,需要大量的实战练习,当然还不能缺少你的专研和耐心。

但是很多小伙伴们并不一定学过的知识都掌握了,而且相信很多伙伴们即使学习一种技术也还是停留在读过,看过,学习过,并没有真正的实战过,所以当时学习的技术觉得自己真正的学会了,搞懂了,而且信心满满的觉得自己可以不必在练习了,这是不对的,因为一时的学习并没有立马转变成为你的技能,而是需要多次的巩固,再次的练习,继而能够拓展出新花样,那才证明你真正的掌握了。

所以创建了这个系列的博文,该博文主要是以一个完整的项目作为实战,以项目的进展作为向导,分析每个功能的实现,以及针对这个功能的我思我想,当然博主也是个小菜鸟,真实的意图是想通过这个小项目来记录自己的学习过程,并且,恳求各位大神,在每个功能实现的过程中,请在评论中贡献您的想法,或是觉得我所使用的方法或逻辑并不是恰当的、最好的,那么请把想法写进评论中,既作为您对该功能实现的看法,也可以提供我思路,给我们一起提升的机会,在这拜谢各位大大。

博主一直以来很喜欢动漫,可以说是酷爱了,所以这次就想以一个动漫的APP做为项目的开发,并请了一位非设计专业同事看了几部其他动漫APP利用闲暇时间,给整理出来一些共同点且是大多功能以后大家都会遇到的东西,简易的画个了原图,非常感谢这位同事,下面上图看看我们的原形需求。

Android项目开发实战之使用Fragment和FragmentTabHost搭建底部菜单(一)_第1张图片

相信大家一看就会明白,APP确实还是挺简单的,但是所需要的功能以后大家可能都会碰到,那时你会怎么设计呢?怎么找出共同点呢?

好,原图已上,让我们来看看整体设计吧,首先大家可以看到整个APP有很多相似之处,比如说顶端有两个选择项,中间是不同的布局,下面又是相同的底部菜单。所以我们可能自然而然的就想到,统一的底部菜单 + 中间FrameLayout布局 + toolBar就可以搞定了,是不是很简单呢。

今天我们就先来实现APP底部菜单栏的UI显示,底部菜单UI展现,以我们的需求可以通过好几种方式实现,比如使用:TabHost + ActivityGroup(已过时),Fragment + RadioGroup,Fragment + FragmentTabHost等几种选择,由于ActivityGroup已过时,TabHost 也逐渐被Fragment 所取代,所以项目我们选择Fragment + FragmentTabHost来实现我们的底部菜单。

Fragment 和 FragmentTabHost 都是android.support.v4.app包下的类,所以我们再使用是首先要先导入正确的包,而在XML文件中我们需要如下使用:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>

我们定义垂直方向的LinearLayout布局,FrameLayout用来显示我们的只要内容,FragmentTabHost用来在底部显示菜单。

ok,布局文件已配置好了,下面可考虑怎么加载到Acitivity中,在这之前,我习惯先创建一个Application,里面封装一个全局的Context变量,如:

public class MyApplication extends Application{ private static Context mContext;//全局获取context @Override public void onCreate() { super.onCreate(); mContext = getApplicationContext(); } /** * 获取全局context */ public static Context getContext(){ return mContext; } }

还有先定义一个BaseActivity作为其他Activity的父类,并且把获取全部的资源方法封装进去。

public class BaseActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public static Context getContext(){ return SanHuiAppsAnimationApplication.getContext(); } public static int getLayoutId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "layout", context.getPackageName()); } public static int getStringId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "string", context.getPackageName()); } public static int getDrawableId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "drawable", context.getPackageName()); } public static int getStyleId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "style", context.getPackageName()); } public static int getId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "id", context.getPackageName()); } public static int getMenuId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "menu", context.getPackageName()); } public static int getColorId(Context context, String paramString) { return context.getResources().getIdentifier(paramString, "color", context.getPackageName()); } public static int getLayoutId(String paramString) { return getLayoutId(getContext(), paramString); } public static int getStringId(String paramString) { return getStringId(getContext(), paramString); } public static int getDrawableId(String paramString) { return getDrawableId(getContext(), paramString); } public static int getStyleId(String paramString) { return getStyleId(getContext(), paramString); } public static int getId(String paramString) { return getId(getContext(), paramString); } public static int getMenuId(String paramString) { return getMenuId(getContext(), paramString); } public static int getColorId(String paramString) { return getColorId(getContext(), paramString); } public static int getAnimId(String paramString) { return getContext().getResources().getIdentifier(paramString, "anim", getContext().getPackageName()); } public static int getAttrId(String paramString) { return getContext().getResources().getIdentifier(paramString, "attr", getContext().getPackageName()); } public static int getInterpolator(String name) { return getContext().getResources().getIdentifier(name, "interpolator", getContext().getPackageName()); } public static int getDimenId(String paramString) { return getContext().getResources().getIdentifier(paramString, "dimen", getContext().getPackageName()); } }

好,准备工作已完成,,现在来看看怎么把我们的刚才的main.xml添加到MainActivity中,并实现底部菜单的切换。

public class MainActivity extends FragmentActivity{ private FragmentTabHost mFragmentTabHost; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(BaseActivity.getLayoutId("activity_main")); mFragmentTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); //初始化FragmentTabHost mFragmentTabHost.setup(this,getSupportFragmentManager(),BaseActivity.getId("realtabcontent")); addTabView("Collection", BaseActivity.getDrawableId("main_tab_item_collection"), CollectionFragment.class); addTabView("Animation", BaseActivity.getDrawableId("main_tab_item_animation"), AnimationFragment.class); addTabView("Game", BaseActivity.getDrawableId("main_tab_item_game"), GameFragment.class); addTabView("Mine", BaseActivity.getDrawableId("main_tab_item_mine"), MineFragment.class); } public void addTabView(String viewTag, int iconId, Class<?> cls) { View viewTabWidget = getTabWidget(iconId); TabHost.TabSpec tabSpec = mFragmentTabHost.newTabSpec(viewTag); tabSpec.setIndicator(viewTabWidget); mFragmentTabHost.addTab(tabSpec,cls,null); } public View getTabWidget(int iconId) { View viewTabWidget = LayoutInflater.from(this).inflate(BaseActivity.getLayoutId("activity_main_tabwidget"), null); ImageView view = (ImageView) viewTabWidget.findViewById(BaseActivity.getId("tab_label")); view.setImageResource(iconId); return viewTabWidget; } } 

其实很简单,首先,是通过获取资源文件并绑定FragmentTabHost,其中值得注意的是:
mFragmentTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);这个是从android.R.id.tabhost获取,main.xml也是这么给出的id,不要搞混了。

然后,通过得到所支持的FragmentManager来初始化FragmentTabHost,并绑定用于显示正文的Fragment。

再次,我们通过addTabView()方法把底部菜单所需要的View展示出来,这里使用的是TabHost.TabSpec,它需要一个标示几个参数,一个是tag标示,一个是用于底部菜单显示的view等,可以自己选择设置。这里的菜单View我是用xml文件selector选择器来自动选择的,因为四个底部菜单所用一样,这里就只贴出一个供参考:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/main_tab_collection" android:state_selected="false"/>
    <item android:drawable="@mipmap/main_tab_collection_h" android:state_selected="true"/>
</selector>

最后,我们通过mFragmentTabHost.addTab(tabSpec,cls,null);把底部菜单和与之相关联的Fragment关联起来,从而达到在我们点击底部菜单时显示与之相对应的正文内容。

ok,底部菜单这块已基本实现,下面来看看效果吧。

Android项目开发实战之使用Fragment和FragmentTabHost搭建底部菜单(一)_第2张图片

好了,大家也看到了效果,那么就请大家在评论区发表下意见,或许你的实现方式更好呢,共同学习才能更快进步,谢谢大家。

更多资讯请关注微信平台,有博客更新会及时通知。爱学习爱技术。

Android项目开发实战之使用Fragment和FragmentTabHost搭建底部菜单(一)_第3张图片

你可能感兴趣的:(Android开发,android菜单,android实战)