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

来源:互联网 发布:linux 脚本 while 编辑:程序博客网 时间:2024/05/14 09:52

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

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

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

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

这里写图片描述

相信大家一看就会明白,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,底部菜单这块已基本实现,下面来看看效果吧。

这里写图片描述

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

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

这里写图片描述

1 0
原创粉丝点击