流行的界面切换FragmentTabHost详解

时间:2020-12-26 16:48:22

1. 前戏

  当前80%的移动客户端都是此种布局,包括主流的QQ,微信,通过下方的控制tab来操作进行切换当前的界面,当然方法有很多,但是能有封装,能有控件我认为当然用可行的,废话不多说了,看图。
流行的界面切换FragmentTabHost详解

2.  干货

     xml布局如下,一定要注意几点:
1.这个布局为了要用weight,所以一定要使用LinearLayout布局
2.为了优化fragment之间切换的流畅和灵活性,可以对google的控件FragmentTabHost进行自定义的修改,所以这里我使用的自定义控件,至于修改的地方,网上实际上的都一样,我也是看大牛的,开始没想过这个问题,这里推荐两个文章。 点击打开链接(强力推荐), 点击打开链接.。
3.xml代码中有两个framelayou,注意一个是真的,一个是假的,并且要严格按照这代码的id写,weight=1的是真的,weight=0的是假的
4.我们在使用这个控件时,可能会报错java.lang.IllegalStateException: No tab known for tag null,如图,但是不用担心,都是这样的,实际并没有什么影响。如果有疑问,推荐 点击打开链接,但是我看了好像然并卵。
<?xml version="1.0" encoding="utf-8"?>
流行的界面切换FragmentTabHost详解
  MainActivity中代码要注意以下几点:
1. 使用这个FragmentTabHost的activity一定要继承FragmentActivity,但是我们如果使用V7包的 AppCompatActivity,则不用管,因为这个继承了FragmentActivity。
2. FragmentTabHost的大致使用规范,第一步得到fragmenttabhost,第二步调用setup方法,具体见代码,第三步得到tabspec 第四步 加载我们需要的view,使用setIndivator(),第五,添加tab,使用addTab(),因为我这里使用的图文并茂的tab形式,并没有用官方demo中的单一的文字,所以例外要写个view,布局xml代码一起放在下面。
3. 因为一个一个添加tab太浪费代码,所以这里进行了封装,封装的代码很好用,可以直接使用。
4. 选择器selector这里就不用多说了,我直接上其中一个tab图片的代码和tab文字的代码
package com.guozhaohui.fragmenttabhost;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TextView;

import com.guozhaohui.fragmenttabhost.bean.Tab;
import com.guozhaohui.fragmenttabhost.fragment.EatFragment;
import com.guozhaohui.fragmenttabhost.fragment.GameFragment;
import com.guozhaohui.fragmenttabhost.fragment.SleepFragment;
import com.guozhaohui.fragmenttabhost.widget.FragmentTabHost;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private FragmentTabHost fragmentTabHost;
    private LayoutInflater layoutInflater;
    private List tabs = new ArrayList(3);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        layoutInflater = LayoutInflater.from(this);
        fragmentTabHost = (FragmentTabHost) this.findViewById(R.id.tabhost);




        /**
         * This method is deprecated. Don't call the original TabHost setup,
         * you must instead call setup(Context, FragmentManager) or setup(Context, FragmentManager, int).
         * 注意这个方法中第三个参数的意义,在布局文件中,里面那个framelayout只是假的,并且id一定要写成
         * android:id="@android:id/tabcontent",但是这里用的是   android:id="@+id/realtabcontent",是外面那个id
         *
         * */
        fragmentTabHost.setup(this,getSupportFragmentManager(),R.id.realtabcontent);


        //这是FragmentTabHost添加tab的详细过程  要实现就要写三份一样,下面封装
//        TabHost.TabSpec tabSpec = fragmentTabHost.newTabSpec("eat");
//          View view = layoutInflater.inflate(R.layout.indicator_tabspec, null);
//          ImageView tab_iv = (ImageView) view.findViewById(R.id.tab_iv);
//          TextView tab_tv = (TextView) view.findViewById(R.id.tab_tv);
//        tab_iv.setImageResource(R.mipmap.eat2);
//        tab_tv.setText("吃饭");
//        tabSpec.setIndicator(view);
//       fragmentTabHost.addTab(tabSpec, EatFragment.class,null);


        //这是官方的写法,但是太过单一
//        fragmentTabHost.addTab(fragmentTabHost.newTabSpec("eat").setIndicator("吃饭"),EatFragment.class,null);
//        fragmentTabHost.addTab(fragmentTabHost.newTabSpec("sleep").setIndicator("睡觉"),SleepFragment.class,null);
//        fragmentTabHost.addTab(fragmentTabHost.newTabSpec("game").setIndicator("游戏"),GameFragment.class,null);

           initTab();
        for(Tab tab:tabs){

            TabHost.TabSpec tabSpec = fragmentTabHost.newTabSpec(getString(tab.getTextResId()));

            tabSpec.setIndicator(getTabSpecView(tab));

            fragmentTabHost.addTab(tabSpec,tab.getTab_fragment(),null);

        }

        fragmentTabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE); //去掉每个tab之间的分割线


    }

    private View getTabSpecView(Tab tab) {
        View view = layoutInflater.inflate(R.layout.indicator_tabspec, null);
        ImageView tab_iv = (ImageView) view.findViewById(R.id.tab_iv);
        TextView tab_tv = (TextView) view.findViewById(R.id.tab_tv);
        tab_iv.setImageResource(tab.getIconResId());
        tab_tv.setText(tab.getTextResId());
        return view;
    }

    private void initTab() {

        Tab tab_eat = new Tab(R.drawable.selector_eat,R.string.eat,EatFragment.class);
        Tab tab_sleep = new Tab(R.drawable.selector_sleep,R.string.sleep,SleepFragment.class);
        Tab tab_game = new Tab(R.drawable.selector_game,R.string.game,GameFragment.class);
        tabs.add(tab_eat);
        tabs.add(tab_sleep);
        tabs.add(tab_game);
    }

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

3.道友留步

  源代码地址 点击打开链接。好像没什么其他的了,双十一来了,哎是不是要买点什么,没钱啊,靠