Android使用FragmentTabHost实现底部导航栏切换卡

一、编写布局

编写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=".MainActivity">

    <FrameLayout android:id="@+id/contentLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        tools:ignore="Suspicious0dp"
        android:layout_weight="1">

    </FrameLayout>

    <androidx.fragment.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff">

        <FrameLayout android:id="@android:id/tabcontent"
            android:layout_height="0dp"
            android:layout_width="0dp"
            />

    </androidx.fragment.app.FragmentTabHost>

</LinearLayout>

编写footer_tabs.xml (这个布局相当于底部导航栏的一个图标和对应标题的组合体,底部导航栏一共5个,那么这个布局文件就复用了5次)

<?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="5dp"
        android:background="#F6F6F6"
        >
        <ImageView
            android:id="@+id/ivImg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="false"
            android:layout_alignParentTop="true"
            />

        <TextView
            android:id="@+id/tvTab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#AEAEAE"
            android:text="新闻"
            android:layout_marginTop="2dp"
            android:paddingLeft="0dp"/>

    </LinearLayout>

 

二、在drawable添加10张图片

https://www.iconfont.cn/    此网站可以搜索并下载很好看的图标,颜色、大小也可以自定义

我命名图片名称为:

foot_fond_normal.png
foot_found_light.png
foot_news_light.png
foot_news_normal.png
foot_out_light.png
foot_out_normal.png
foot_read_light.png
foot_read_normal.png
foot_vdio_light.png
foot_vdio_normal.png

 

三、添加颜色配置

在values文件夹的colors.xml文件,添加下面两种颜色

    <color name="read">#ff0000</color>
    <color name="foot_txt_gray">#AEAEAE</color>

 

四、编写TabDb类

这个类用来指定底部导航栏的图标路径、标题文字、各个Fragment页面对应的类

public class TabDb {
	public static String[] getTabsTxt(){
		String[] tabs={"新闻","读物","媒体","发现","我的"};
		return tabs;
	}
	public static int[] getTabsImg(){
		int[] ids={R.drawable.foot_news_normal,R.drawable.foot_read_normal,R.drawable.foot_vdio_normal,R.drawable.foot_fond_normal,R.drawable.foot_out_normal};
		return ids;
	}
	public static int[] getTabsImgLight(){
		int[] ids={R.drawable.foot_news_light,R.drawable.foot_read_light,R.drawable.foot_vdio_light,R.drawable.foot_found_light,R.drawable.foot_out_light};
		return ids;
	}
	public static Class[] getFragments(){
		Class[] clz={NewsFragment.class,ReadFragment.class,VideoFragment.class,FoundFragment.class,OwnerFragment.class};
		return clz;
	}
}

五、编写所有Fragment类

这5个Fragment是要展示数据的界面

FoundFragment
NewsFragment
OwnerFragment
ReadFragment
VideoFragment

 

public class FoundFragment extends Fragment {

    @Override
    public void onAttach(Context activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        TextView tvTitle=new TextView(super.getActivity());
        tvTitle.setText("FoundFragment");
        tvTitle.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        tvTitle.setGravity(Gravity.CENTER);
        tvTitle.setTextSize(30);
        return tvTitle;
    }

    @Override
    public void setArguments(Bundle args) {
        // TODO Auto-generated method stub
        super.setArguments(args);
    }

}
public class NewsFragment extends Fragment {

    @Override
    public void onAttach(Context activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        TextView tvTitle=new TextView(super.getActivity());
        tvTitle.setText("NewsFragment");
        tvTitle.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        tvTitle.setGravity(Gravity.CENTER);
        tvTitle.setTextSize(30);
        return tvTitle;
    }

    @Override
    public void setArguments(Bundle args) {
        // TODO Auto-generated method stub
        super.setArguments(args);
    }

}
public class OwnerFragment extends Fragment {

    @Override
    public void onAttach(Context activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        TextView tvTitle=new TextView(super.getActivity());
        tvTitle.setText("OwnerFragment");
        tvTitle.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        tvTitle.setGravity(Gravity.CENTER);
        tvTitle.setTextSize(30);
        return tvTitle;
    }

    @Override
    public void setArguments(Bundle args) {
        // TODO Auto-generated method stub
        super.setArguments(args);
    }

}
public class ReadFragment extends Fragment {

    @Override
    public void onAttach(Context activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        TextView tvTitle=new TextView(super.getActivity());
        tvTitle.setText("ReadFragment");
        tvTitle.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        tvTitle.setGravity(Gravity.CENTER);
        tvTitle.setTextSize(30);
        return tvTitle;
    }

    @Override
    public void setArguments(Bundle args) {
        // TODO Auto-generated method stub
        super.setArguments(args);
    }

}
public class VideoFragment extends Fragment {

    @Override
    public void onAttach(Context activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        TextView tvTitle=new TextView(super.getActivity());
        tvTitle.setText("VideoFragment");
        tvTitle.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        tvTitle.setGravity(Gravity.CENTER);
        tvTitle.setTextSize(30);
        return tvTitle;
    }

    @Override
    public void setArguments(Bundle args) {
        // TODO Auto-generated method stub
        super.setArguments(args);
    }

}

六、编写MainActivity

 

public class MainActivity extends FragmentActivity implements TabHost.OnTabChangeListener {

    private FragmentTabHost tabHost;
    protected void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //tabHost属于父元素,表示整个界面,找到布局文件的tabhost,然后赋值给tabHost,这样就可以用tabHost对象来操作布局了
        tabHost=(FragmentTabHost)super.findViewById(android.R.id.tabhost);
        //在tabHost创建FragmentLayout , contentLayout的id就是布局文件里面FragmentLayout的id,如果在布局文件FragmentLayout添加子元素,那么实际上相互切换的3个FragmentLayout都会被添加子元素
        tabHost.setup(this,super.getSupportFragmentManager(),R.id.contentLayout);
        //getTabWidget()方法表示获取切换卡,setDividerDrawable(null)表示没有分割线
        tabHost.getTabWidget().setDividerDrawable(null);
        //点击下面5个图标的时候会变色,就是setOnTabChangedListener(this)方法影响的,如果没有这个方法,那么点击图标不会变色
        tabHost.setOnTabChangedListener(this);
        initTab();


    }
    //initTab()方法表示没有点击图标的时候的初始状态
    private void initTab() {
        //tabs就是下面导航栏的“新闻”,“读物”,“媒体” 。。。的5个图标下面的文字,但是觉得不好看,就直接通过设置布局把文字隐藏了
        String tabs[]=TabDb.getTabsTxt();
        for(int i=0;i<tabs.length;i++){
            //https://www.cnblogs.com/littleby/p/5178736.html
            //TabHost相当于浏览器中分页的集合,而TabSpec则相当于浏览器中的每个分页。可以理解为TabHost就是放3个图标的长条区域的对象集合,TabSpec就是这个集合里面的每个对象
            //一个图标和下面一个文本加起来就属于一个TabSpec,可以理解为一个标签空间。tabs[i]只是将每个标签空间的名字设置为“新闻”,“读物”,“媒体” 。。。而已,这个可以随便设置。
            //setIndicator(View view)方法表示,把一些元素装进标签空间里面!
            TabHost.TabSpec tabSpec=tabHost.newTabSpec(tabs[i]).setIndicator(getTabView(i));
            //addTab()方法表示添加导航栏
            tabHost.addTab(tabSpec,TabDb.getFragments()[i],null);
            tabHost.setTag(i);
        }
    }

    private View getTabView(int idx) {
        //引入footer_tabs.xml布局,这个布局包含了导航栏的图片和文本,我这里通过设置布局文件参数把文本隐藏了
        View view= LayoutInflater.from(this).inflate(R.layout.footer_tabs,null);

        ((TextView)view.findViewById(R.id.tvTab)).setText(TabDb.getTabsTxt()[idx]);
        //下面的判断语句表示图标颜色的默认状态,第一个图标默认点亮,其他默认不点亮
        if(idx==0){

            ((TextView)view.findViewById(R.id.tvTab)).setTextColor(Color.RED);
            //设置为点亮的图标
            ((ImageView)view.findViewById(R.id.ivImg)).setImageResource(TabDb.getTabsImgLight()[idx]);
        }else{
            //设置为点不亮的图标
            ((ImageView)view.findViewById(R.id.ivImg)).setImageResource(TabDb.getTabsImg()[idx]);
        }
        return view;
    }

    //onTabChanged自带方法
    @Override
    public void onTabChanged(String tabId) {
        updateTab();
    }

    //点击图标就会调用updateTab()方法
    private void updateTab(){
        //TabWidget表示切换卡
        TabWidget tabw=tabHost.getTabWidget();
        for(int i=0;i<tabw.getChildCount();i++){
            View view=tabw.getChildAt(i);
            ImageView iv=(ImageView)view.findViewById(R.id.ivImg);
            if(i==tabHost.getCurrentTab()){
                ((TextView)view.findViewById(R.id.tvTab)).setTextColor(Color.RED);
                iv.setImageResource(TabDb.getTabsImgLight()[i]);
            }else{
                ((TextView)view.findViewById(R.id.tvTab)).setTextColor(getResources().getColor(R.color.foot_txt_gray));
                iv.setImageResource(TabDb.getTabsImg()[i]);
            }

        }
    }

}

 

运行效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值