1. 前戏
当前80%的移动客户端都是此种布局,包括主流的QQ,微信,通过下方的控制tab来操作进行切换当前的界面,当然方法有很多,但是能有封装,能有控件我认为当然用可行的,废话不多说了,看图。
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"?>
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.道友留步
源代码地址
点击打开链接。好像没什么其他的了,双十一来了,哎是不是要买点什么,没钱啊,靠