[Android] Android 使用 FragmentTabHost + Fragment 实现 微信 底部菜单

阳光穿透心脏的1/2处 2021-10-01 06:48 434阅读 0赞

Android 使用 FragmentTabHost + Fragment 实现 微信 底部菜单

利用FragmentTabHost实现底部菜单,在该底部菜单中,包括了4个TabSpec,每个TabSpec中包含了一个View,而View中包含了一个ImageView和一个TextView。

一、先演示下效果:

微信底部导航栏效果

二、TabHost基本介绍

TabWidget : 该组件就是TabHost标签页中上部 或者 下部的按钮, 可以点击按钮切换选项卡;

TabSpec : 代表了选项卡界面, 添加一个TabSpec即可添加到TabHost中;

-- 创建选项卡 : newTabSpec(String tag), 创建一个选项卡;

-- 添加选项卡 : addTab(tabSpec);

三、使用步骤

1、定义布局 : 在XML文件中使用 FragmentTabHost 组件, 并在其中定义一个FrameLayout选项卡内容;

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. tools:context=".ui.activity.MainActivity">
  8. <FrameLayout
  9. android:id="@+id/real_content"
  10. android:layout_width="match_parent"
  11. android:layout_height="0dp"
  12. android:layout_weight="1"/>
  13. <android.support.v4.app.FragmentTabHost
  14. android:id="@android:id/tabhost"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:background="#ffffff">
  18. <FrameLayout
  19. android:id="@android:id/tabcontent"
  20. android:layout_width="0dp"
  21. android:layout_height="0dp"
  22. android:layout_weight="0" />
  23. </android.support.v4.app.FragmentTabHost>
  24. </LinearLayout>

需要注意的是,FragmentTabHost的id是需要使用 安卓自带的id,“@android:id/tabhost”,而FragmentTabHost中的FrameLayout也需要使用 安卓自带的id,tabcontent。另外一点是,这个文件中有两个FrameLayout,因为实现的是底部菜单,所以在FragmentTabHost中的FrameLayout是设置为0的,而FragmentTabHost真正需要显示的内容是在上面的FrameLayout中进行显示的。

2、定义 Indicator中的View 文件main_tab_indicator.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. android:gravity="center"
  6. android:orientation="vertical">
  7. <ImageView
  8. android:id="@+id/iv_tab_icon"
  9. android:layout_width="24dp"
  10. android:layout_height="24dp"
  11. android:layout_marginTop="5dp"
  12. android:src="@drawable/main_tab_btn_news" />
  13. <TextView
  14. android:id="@+id/tv_tab_text"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:gravity="center"
  18. android:text="首页"
  19. android:textColor="@color/main_tab_text_color"
  20. android:textSize="10sp" />
  21. </LinearLayout>

一张图片,一个文本

3、定义Tab MainTabItem.java

  1. package com.jack.appnews.widget;
  2. public class MainTabItem {
  3. private int Image;
  4. private int Text;
  5. private Class Fragment;
  6. public MainTabItem(int image, int text, Class fragment) {
  7. Image = image;
  8. Text = text;
  9. Fragment = fragment;
  10. }
  11. public int getImage() {
  12. return Image;
  13. }
  14. public void setImage(int image) {
  15. Image = image;
  16. }
  17. public int getText() {
  18. return Text;
  19. }
  20. public void setText(int text) {
  21. Text = text;
  22. }
  23. public Class getFragment() {
  24. return Fragment;
  25. }
  26. public void setFragment(Class fragment) {
  27. Fragment = fragment;
  28. }
  29. }

4、在MainActivity中编写逻辑

核心逻辑如下 (代码中有说明,共5步)

  1. //1)实例化4个Tab类的对象
  2. mTabs.add(new MainTabItem(R.drawable.main_tab_btn_news, R.string.main_tab_news, NewsListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_video, R.string.main_tab_video, VideoListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_image, R.string.main_tab_image, ImageListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_mine, R.string.main_tab_mine, MineFragment.class)); //2)调用 setup 方法 mTabHost.setup(this, getSupportFragmentManager(), R.id.real_content); //3)添加 Tab for (MainTabItem tab : mTabs) { TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText())).setIndicator(getTabItemView(tab)); mTabHost.addTab(tabSpec, tab.getFragment(), null); } //4)去除掉底部菜单图表之间的分割线 if (android.os.Build.VERSION.SDK_INT > 10) { mTabHost.getTabWidget().setShowDividers(0); } //5)事件绑定 mTabHost.setOnTabChangedListener(this);

完整代码: MainActivity.java

  1. package com.jack.appnews.ui.activity;
  2. import android.support.v4.app.FragmentTabHost;
  3. import android.view.View;
  4. import android.widget.ImageView;
  5. import android.widget.TabHost;
  6. import android.widget.TextView;
  7. import com.jack.appnews.R;
  8. import com.jack.appnews.ui.BaseActivity;
  9. import com.jack.appnews.ui.fragment.ImageListFragment;
  10. import com.jack.appnews.ui.fragment.MineFragment;
  11. import com.jack.appnews.ui.fragment.NewsListFragment;
  12. import com.jack.appnews.ui.fragment.VideoListFragment;
  13. import com.jack.appnews.widget.MainTabItem;
  14. import java.util.ArrayList;
  15. import butterknife.BindView;
  16. public class MainActivity extends BaseActivity implements TabHost.OnTabChangeListener { @BindView(android.R.id.tabhost) FragmentTabHost mTabHost; private long exitTime = 0; private ArrayList<MainTabItem> mTabs = new ArrayList<>(4); @Override protected int inflateLayoutId() { return R.layout.activity_main; } @Override protected void initViews() { initTabHost(); } protected void initTabHost() { //1)实例化4个Tab类的对象 mTabs.add(new MainTabItem(R.drawable.main_tab_btn_news, R.string.main_tab_news, NewsListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_video, R.string.main_tab_video, VideoListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_image, R.string.main_tab_image, ImageListFragment.class)); mTabs.add(new MainTabItem(R.drawable.main_tab_btn_mine, R.string.main_tab_mine, MineFragment.class)); //2)调用 setup 方法 mTabHost.setup(this, getSupportFragmentManager(), R.id.real_content); //3)添加 Tab for (MainTabItem tab : mTabs) { TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText())).setIndicator(getTabItemView(tab)); mTabHost.addTab(tabSpec, tab.getFragment(), null); } //4)去除掉底部菜单图表之间的分割线 if (android.os.Build.VERSION.SDK_INT > 10) { mTabHost.getTabWidget().setShowDividers(0); } //5)事件绑定 mTabHost.setOnTabChangedListener(this); } /** * 设置Indicator中的View * * @param tab * @return */ private View getTabItemView(MainTabItem tab) { View view = getLayoutInflater().inflate(R.layout.main_tab_indicator, null); ImageView Tab_img = (ImageView) view.findViewById(R.id.iv_tab_icon); TextView Tab_txt = (TextView) view.findViewById(R.id.tv_tab_text); Tab_img.setBackgroundResource(tab.getImage()); Tab_txt.setText(tab.getText()); return view; } @Override public void onTabChanged(String tabId) { final int size = mTabHost.getTabWidget().getTabCount(); for (int i = 0; i < size; i++) { View v = mTabHost.getTabWidget().getChildAt(i); if (i == mTabHost.getCurrentTab()) { v.setSelected(true); } else { v.setSelected(false); } } supportInvalidateOptionsMenu(); } @Override public void onBackPressed() { if ((System.currentTimeMillis() - exitTime) > 2000) { exitTime = System.currentTimeMillis(); } else { finish(); System.exit(0); } } }

四、源代码地址

Talk is cheap. Show me the code

话不多说,代码在这里下载!

https://github.com/wukong1688/Android-BaseTabHost

这是我用FragmentTabHost + ViewPager + XRecycleList 实现的 标签切换 + 列表上滑加载+列表下滑刷新

其中 列表上滑加载+列表下滑刷新 可参考下一篇文章:

Android 支持下拉刷新、上拉加载更多 的 XRecyclerview

如果觉得有帮助,欢迎在 Github 为我 star!

五、参考文章

https://www.jianshu.com/p/491386d6435c

https://www.cnblogs.com/langfei8818/p/6349354.html

本博客地址: wukong1688

本文原文地址:https://www.cnblogs.com/wukong1688/p/10753339.html

转载请著名出处!谢谢~~

转载于:https://www.cnblogs.com/wukong1688/p/10753339.html

发表评论

表情:
评论列表 (有 0 条评论,434人围观)

还没有评论,来说两句吧...

相关阅读