网上有很多例子,虽然网上有很多例子,可是我还是弄了挺久才实现,以下记录一下过程中遇到的问题
环境: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>
效果
源码地址