FragmentTabHost实现底部菜单+附源码

网上有很多例子,虽然网上有很多例子,可是我还是弄了挺久才实现,以下记录一下过程中遇到的问题

环境:Android studio 3.3.2    

遇到的报错:

   1.java.lang.IllegalStateException: Must call setup() that takes a Context and FragmentManager

   我在网上找了下原因,是因为https://issuetracker.google.com/issues/37128407  

     大概意思就是因为Android studio 版本低于3.0  然后我去升级了就没事了

    2.TabHost requires a TabWidget with id "android:id/tabs".

        解决:改变API的目标(XML的图形视图的左上角)到3.0,你可以看到它。。。。我是先加了TabWidget这个属性然后又报1的错误,然后又升级了软件与gradle等,然后又出现了问题3和问题4

        参考https://blog.csdn.net/csxjy1986/article/details/6662549

3.Could not find com.android.tools.build:aapt2:3.2.1-4818971.

       解决 

      

4.No tab content FrameLayout found for id xxx

     解决:删掉xml中的Tabwidget

 

依次解决了以上问题后,下面就好实现了,以下代码是我看了以及对比了好些个博客综合实现的来,好些博客代码都没放全

项目结构

   

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.sojournerapplication.MainActivity">
    <include layout="@layout/top"></include>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/realcontent">

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

top.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="45dp"
    android:background="#e6e6e6"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="养老旅居服务"
        android:textColor="#545454"
        android:textSize="20sp"
        android:layout_gravity="center"
        android:textStyle="bold"/>
</LinearLayout>

fragment_home.xml  (有几个tab来几份)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Home"
        android:textColor="#545454"
        android:textSize="23sp"
        android:textStyle="bold" />
</LinearLayout>

tab_indicater.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >

<ImageView
    android:id="@+id/tab_indicator_icon"
    android:layout_width="34dp"
    android:layout_height="34dp"
    android:layout_marginTop="5dp"
    android:focusable="false"
    android:padding="3dp">
</ImageView>

<TextView
    android:id="@+id/tab_indicator_hint"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="首页"
    android:layout_alignParentRight="true"
    android:layout_marginBottom="5dp"
    android:layout_marginTop="3dp"
    android:gravity="center"
    android:textSize="10sp"
    android:textColor="@color/selector_tab_textcolor">
</TextView>

</LinearLayout>
HomeFragment  (几个tab来几份)
package com.example.sojournerapplication.com.edu.cqjtu.fragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.sojournerapplication.R;

public class HomeFragment extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_home, container, false);
    }
}

Tab

public class Tab {
    private int Image;
    private int Text;
    private Class Fragment;

    public Tab(int image, int text, Class fragment) {
        Image = image;
        Text = text;
        Fragment = fragment;    }

    public int getImage() {        return Image;    }
    public void setImage(int image) {        Image = image;    }
    public int getText() {        return Text;    }
    public void setText(int text) {        Text = text;    }
    public Class getFragment() {        return Fragment;    }
    public void setFragment(Class fragment) {        Fragment = fragment;    }
}

MainActivity

package com.example.sojournerapplication;

import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TextView;

import com.example.sojournerapplication.com.edu.cqjtu.bean.Tab;
import com.example.sojournerapplication.com.edu.cqjtu.fragment.FriendsFragment;
import com.example.sojournerapplication.com.edu.cqjtu.fragment.HomeFragment;
import com.example.sojournerapplication.com.edu.cqjtu.fragment.NewsFragment;
import com.example.sojournerapplication.com.edu.cqjtu.fragment.RecordFragment;
import com.example.sojournerapplication.com.edu.cqjtu.fragment.UserFragment;

import java.util.ArrayList;

public class MainActivity extends FragmentActivity {
    private FragmentTabHost mTabHost;
    private LayoutInflater mInflater;
    private ArrayList<Tab> mTabs= new ArrayList<Tab>(5);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        initTab();
    }
    private void initTab() {
        //实例化5个Tab类的对象
        Tab Tab_home = new Tab(R.drawable.selector_home, R.string.home, HomeFragment.class);
        Tab Tab_news = new Tab(R.drawable.selector_news, R.string.news, NewsFragment.class);
        Tab Tab_friends = new Tab(R.drawable.selector_friends, R.string.friends, FriendsFragment.class);
        Tab Tab_record = new Tab(R.drawable.selector_record, R.string.record, RecordFragment.class);
        Tab Tab_user = new Tab(R.drawable.selector_user, R.string.user, UserFragment.class);

        //将这5个对象加到一个List中
        mTabs.add(Tab_home);
        mTabs.add(Tab_news);
        mTabs.add(Tab_friends);
        mTabs.add(Tab_record);
        mTabs.add(Tab_user);

        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup(this, getSupportFragmentManager(), R.id.realcontent);
        mInflater = LayoutInflater.from(this);

        //通过循环实例化一个个TabSpec
        //并调用其中setIndicator方法
        //然后将TabSpec加到TabHost中
        for (Tab tab : mTabs) {
            TabHost.TabSpec tabSpec = mTabHost.newTabSpec(String.valueOf(tab.getText()));
            tabSpec.setIndicator(buildView(tab));
            mTabHost.addTab(tabSpec, tab.getFragment(), null);
        }
        //通过这行代码可以去除掉底部菜单5个图表之间的分割线
        mTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
    }

        //设置Indicator中的View

    private View buildView(Tab tab) {
        View view = mInflater.inflate(R.layout.tab_indicator, null);
        ImageView Tab_img = (ImageView) view.findViewById(R.id.tab_indicator_icon);
        TextView Tab_txt = (TextView) view.findViewById(R.id.tab_indicator_hint);

        Tab_img.setBackgroundResource(tab.getImage());
        Tab_txt.setText(tab.getText());
        return view;
    }
}

图片先自己准备好,可以在https://www.iconfont.cn/search/index?searchType=icon&q=%E6%88%91%E7%9A%84  下载

然后我是放在mipmap文件夹的

strings.xml

<resources>
    <string name="app_name">SojournerApplication</string>
    <string name="home">主页</string>
    <string name="friends">好友</string>
    <string name="news">资讯</string>
    <string name="user">我的</string>
    <string name="record">动态</string>
</resources>

selector_home.xml  定义图标被选中状态(几个tab来几份) 可以放在drawable

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    //被选中的时候的图标
    <item android:state_selected="true" android:drawable="@mipmap/selector_home"/>
    //正常状态下的图标
    <item android:drawable="@mipmap/home"/>
</selector>

selector_tab_textcolor.xml   定义文字选中后颜色变化的,一份即可,会被用在tab_indicater.xml里textView处

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    //被选中时候为红色
    <item android:color="#1296db" android:state_selected="true"/>
    //正常情况下为灰色
    <item android:color="#545454" android:state_selected="false"/>
</selector>

效果

源码地址

https://github.com/HYDmonster/SojournerApplication

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值