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.

       解决 

      FragmentTabHost实现底部菜单+附源码_第1张图片

4.No tab content FrameLayout found for id xxx

     解决:删掉xml中的Tabwidget

 

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

项目结构

FragmentTabHost实现底部菜单+附源码_第2张图片   FragmentTabHost实现底部菜单+附源码_第3张图片

 

activity_main.xml



    
    

    
    
        
        
    

top.xml



    

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



    

tab_indicater.xml










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 mTabs= new ArrayList(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


    SojournerApplication
    主页
    好友
    资讯
    我的
    动态

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


    //被选中的时候的图标
    
    //正常状态下的图标
    

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



    //被选中时候为红色
    
    //正常情况下为灰色
    

效果

源码地址

https://github.com/HYDmonster/SojournerApplication

你可能感兴趣的:(个人问题)