首页 > 代码库 > TabLayout 和 ViewPager【综合示例】

TabLayout 和 ViewPager【综合示例】

完整Demo地址:https://github.com/baiqiantao/TabLayoutTest.git

MainActivity 

  1. public class MainActivity extends ListActivity {
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. String[] array = {"0、不重写getPageTitle,会导致没有标题",
  5. "1、使用默认的MODE_FIXED模式",
  6. "2、代码中设置Tab样式",
  7. "3、XML中设置Tab样式",
  8. "4、和VP联动演示,自定义Tab,添加监听,自定义Tab间距",
  9. "5、不自定义Tab,不添加监听,不自定义Tab间距(注意:这里tabMinWidth的默认值会严重影响Tab的宽度)",
  10. "6、自定义Tab,添加监听,不自定义Tab间距",
  11. "7、添加点击事件,但不手动处理点击Tab后TabLayout和VP的变化",
  12. "8、添加点击事件,并手动处理点击Tab后TabLayout和VP的变化",
  13. "9、【动态添加、删除VP中的数据--正常情况】",
  14. "9、【动态添加、删除VP中的数据--非正常情况】",};
  15. setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
  16. }
  17. @Override
  18. protected void onListItemClick(ListView l, View v, int position, long id) {
  19. switch (position) {
  20. case 0:
  21. case 1:
  22. case 2:
  23. case 3:
  24. Intent intent = new Intent(this, Activity1.class);
  25. intent.putExtra("tag", position);
  26. startActivity(intent);
  27. break;
  28. case 4:
  29. case 5:
  30. case 6:
  31. Intent intent2 = new Intent(this, Activity2.class);
  32. intent2.putExtra("tag", position);
  33. startActivity(intent2);
  34. break;
  35. case 7:
  36. case 8:
  37. Intent intent3 = new Intent(this, Activity3.class);
  38. intent3.putExtra("tag", position);
  39. startActivity(intent3);
  40. break;
  41. case 9:
  42. Intent intent4 = new Intent(this, Activity_VP1.class);
  43. intent4.putExtra("tag", position);
  44. startActivity(intent4);
  45. break;
  46. case 10:
  47. Intent intent5 = new Intent(this, Activity_VP2.class);
  48. intent5.putExtra("tag", position);
  49. startActivity(intent5);
  50. break;
  51. }
  52. }
  53. }

MyFragment

  1. public class MyFragment extends Fragment {
  2. public static MyFragment newInstance(String tag) {
  3. Bundle args = new Bundle();
  4. args.putString("tag", tag);
  5. MyFragment fragment = new MyFragment();
  6. fragment.setArguments(args);
  7. return fragment;
  8. }
  9. @Override
  10. public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  11. TextView textView = new TextView(getContext());
  12. textView.setText(getArguments().getString("tag"));
  13. textView.setGravity(Gravity.CENTER);
  14. textView.setBackgroundColor(0xFF000000 + new Random().nextInt(0xFFFFFF));
  15. //注意,Integer.MAX_VALUE= http://www.mamicode.com/0x7fffffff,超过这个值就是负数了,所以通过随机数获取int值时,传入的值要小于0x7fffffff
  16. return textView;
  17. }
  18. }

Activity1 样式

  1. public class Activity1 extends FragmentActivity {
  2. private List<String> list = new ArrayList<>(Arrays.asList(new String[]{"包青天", "白", "baiqiantao(注意大小写)", "1", "12", "123", "1234",}));
  3. private int tag;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. tag = getIntent().getIntExtra("tag", 0);
  9. //3、XML中设置Tab样式
  10. TabLayout tabLayout;
  11. if (tag != 3) {
  12. tabLayout = (TabLayout) findViewById(R.id.tablayout1);
  13. findViewById(R.id.tablayout1).setVisibility(View.VISIBLE);
  14. } else {
  15. tabLayout = (TabLayout) findViewById(R.id.tablayout2);
  16. findViewById(R.id.tablayout2).setVisibility(View.VISIBLE);
  17. }
  18. ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
  19. viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
  20. @Override
  21. public Fragment getItem(int position) {
  22. return MyFragment.newInstance(list.get(position));
  23. }
  24. @Override
  25. public int getCount() {
  26. return list.size();
  27. }
  28. @Override
  29. public CharSequence getPageTitle(int position) {
  30. if (tag == 0) return super.getPageTitle(position);
  31. //0、不重写ViewPager的getPageTitle方法,会导致TabLayout没有标题
  32. else return list.get(position);//因为返回值是CharSequence,所以可以返回一个内容丰富的SpannableString
  33. }
  34. });
  35. tabLayout.setupWithViewPager(viewPager);
  36. //1、默认MODE_FIXED模式,会将每个tab都显示出来,tab的宽度一样;MODE_SCROLLABLE会根据tab中的内容自动调整tab宽度
  37. if (tag != 1) tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
  38. //2、代码中设置Tab样式
  39. if (tag == 2) {
  40. tabLayout.setTabGravity(Gravity.TOP);//没卵用啊!
  41. tabLayout.setTabTextColors(Color.RED, Color.GREEN);
  42. tabLayout.setSelectedTabIndicatorColor(Color.BLUE);
  43. tabLayout.setSelectedTabIndicatorHeight(15);
  44. tabLayout.setBackgroundColor(Color.YELLOW);
  45. }
  46. }
  47. }

Activity2 样式

  1. public class Activity2 extends FragmentActivity {
  2. private List<String> list = new ArrayList<>(Arrays.asList(new String[]{"包青天", "白", "baiqiantao(注意大小写)", "1", "12", "123", "1234",}));
  3. private TabLayout tabLayout;
  4. private ViewPager viewPager;
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. int tag = getIntent().getIntExtra("tag", 0);
  10. initView();
  11. if (tag != 5) {//是否自定义Tab,是否添加监听
  12. setCustomTabView();
  13. addOnTabSelectedListener();
  14. }
  15. if (tag != 6) {//是否自定义Tab间距
  16. tabLayout.post(new Runnable() {
  17. @Override
  18. public void run() {
  19. setIndicator(tabLayout, 1, 1);//必须在setupWithViewPager之后(数据确定后)才可以操作
  20. }
  21. });
  22. }
  23. }
  24. private void initView() {
  25. viewPager = (ViewPager) findViewById(R.id.view_pager);
  26. tabLayout = (TabLayout) findViewById(R.id.tablayout1);
  27. findViewById(R.id.tablayout1).setVisibility(View.VISIBLE);
  28. PagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
  29. @Override
  30. public Fragment getItem(int position) {
  31. return MyFragment.newInstance(list.get(position));
  32. }
  33. @Override
  34. public int getCount() {
  35. return list.size();
  36. }
  37. @Override
  38. public CharSequence getPageTitle(int position) {
  39. return list.get(position);
  40. }
  41. };
  42. viewPager.setAdapter(adapter);
  43. tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);//可滚动模式,另一个是固定宽度模式
  44. tabLayout.setupWithViewPager(viewPager);
  45. }
  46. /**
  47. * 使用自定义的Tab,设置后要自己控制每个Tab的文字以及【默认】选中Tab的样式(比如默认第一个Tab要显示indicator等)
  48. */
  49. private void setCustomTabView() {
  50. tabLayout.setSelectedTabIndicatorHeight(0);
  51. for (int i = 0; i < list.size(); i++) {//必须在setupWithViewPager之后(即被绑定VP的数据确定后)才可以操作
  52. View view = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
  53. TextView tv_tab_name = (TextView) view.findViewById(R.id.tv_tab_name);
  54. View line_indicator = view.findViewById(R.id.line_indicator);
  55. tv_tab_name.setText(list.get(i));//控制每个Tab的文字
  56. if (i == 0) {//控制默认选中Tab的样式
  57. view.setSelected(true);//背景样式
  58. line_indicator.setSelected(true);//指示器样式
  59. } else {
  60. view.setSelected(false);
  61. line_indicator.setSelected(false);
  62. }
  63. TabLayout.Tab tab = tabLayout.getTabAt(i);//获得每一个tab
  64. if (tab != null) tab.setCustomView(view);//给每一个tab设置view
  65. }
  66. }
  67. /**
  68. * 添加监听,当使用自定义的Tab时,要自己控制选中Tab【改变】时Tab的样式,以及ViewPager的当前Item
  69. */
  70. private void addOnTabSelectedListener() {
  71. tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  72. @Override
  73. public void onTabSelected(TabLayout.Tab tab) {
  74. if (tab.getCustomView() != null) {
  75. tab.getCustomView().setSelected(true);//要自己控制选中Tab改变时Tab的样式
  76. tab.getCustomView().findViewById(R.id.line_indicator).setSelected(true);
  77. viewPager.setCurrentItem(tab.getPosition());//要自己控制ViewPager的当前Item
  78. }
  79. }
  80. @Override
  81. public void onTabUnselected(TabLayout.Tab tab) {
  82. if (tab.getCustomView() != null) {
  83. tab.getCustomView().setSelected(false);
  84. tab.getCustomView().findViewById(R.id.line_indicator).setSelected(false);
  85. }
  86. }
  87. @Override
  88. public void onTabReselected(TabLayout.Tab tab) {
  89. }
  90. });
  91. }
  92. /**
  93. * 自定义Indicator左右间距。适用于自定义Tab的情况下,在使用默认Tab时,通过tabPadding设置既可以了
  94. * 注意:除了tabPadding外,tabMinWidth的值也会影响Tab的宽度,特别是1-2两字符时,会非常明显
  95. */
  96. public static void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
  97. try {
  98. Class<?> tabLayout = tabs.getClass();
  99. Field tabStrip = tabLayout.getDeclaredField("mTabStrip");
  100. tabStrip.setAccessible(true);
  101. int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
  102. int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
  103. LinearLayout llTab = (LinearLayout) tabStrip.get(tabs);
  104. for (int i = 0; i < llTab.getChildCount(); i++) {
  105. View child = llTab.getChildAt(i);
  106. child.setPadding(0, 0, 0, 0);
  107. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
  108. params.leftMargin = left;
  109. params.rightMargin = right;
  110. child.setLayoutParams(params);
  111. child.invalidate();
  112. }
  113. } catch (Exception e) {
  114. e.printStackTrace();
  115. }
  116. }
  117. }

Activity3 样式

  1. public class Activity3 extends FragmentActivity implements View.OnClickListener {
  2. private List<String> list = new ArrayList<>(Arrays.asList(new String[]{"包青天", "白", "baiqiantao(注意大小写)", "1", "12", "123", "1234",}));
  3. private TabLayout tabLayout;
  4. private ViewPager viewPager;
  5. private int tag;
  6. private static final int OFFSET = 10086;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. tag = getIntent().getIntExtra("tag", 0);
  12. initView();
  13. setCustomTabView();
  14. addOnTabSelectedListener();
  15. tabLayout.post(new Runnable() {
  16. @Override
  17. public void run() {
  18. setIndicator(tabLayout, 1, 1);//必须在setupWithViewPager之后(数据确定后)才可以操作
  19. }
  20. });
  21. }
  22. private void initView() {
  23. viewPager = (ViewPager) findViewById(R.id.view_pager);
  24. tabLayout = (TabLayout) findViewById(R.id.tablayout1);
  25. findViewById(R.id.tablayout1).setVisibility(View.VISIBLE);
  26. PagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
  27. @Override
  28. public Fragment getItem(int position) {
  29. return MyFragment.newInstance(list.get(position));
  30. }
  31. @Override
  32. public int getCount() {
  33. return list.size();
  34. }
  35. @Override
  36. public CharSequence getPageTitle(int position) {
  37. return list.get(position);
  38. }
  39. };
  40. viewPager.setAdapter(adapter);
  41. tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
  42. tabLayout.setupWithViewPager(viewPager);
  43. }
  44. private void setCustomTabView() {
  45. tabLayout.setSelectedTabIndicatorHeight(0);
  46. for (int i = 0; i < list.size(); i++) {//必须在setupWithViewPager之后(数据确定后)才可以操作
  47. View view = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
  48. //注意:给view添加点击事件后,点击Tab后的点击事件会被这里的view消耗掉,所以Tab自身的点击事件不会响应
  49. //也即点击Tab后将不会触发OnTabSelectedListener,也不会自动切换VP,这些都需要我们自己手动处理
  50. if (i <= 3) {
  51. view.setTag(i + OFFSET);
  52. view.setOnClickListener(this);
  53. }
  54. TextView tv_tab_name = (TextView) view.findViewById(R.id.tv_tab_name);
  55. View line_indicator = view.findViewById(R.id.line_indicator);
  56. tv_tab_name.setText(list.get(i));
  57. if (i == 0) {
  58. view.setSelected(true);
  59. line_indicator.setSelected(true);
  60. } else {
  61. view.setSelected(false);
  62. line_indicator.setSelected(false);
  63. }
  64. TabLayout.Tab tab = tabLayout.getTabAt(i);//获得每一个tab
  65. if (tab != null) tab.setCustomView(view);//给每一个tab设置view
  66. }
  67. }
  68. private void addOnTabSelectedListener() {
  69. tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  70. @Override
  71. public void onTabSelected(TabLayout.Tab tab) {
  72. if (tab.getCustomView() != null) {
  73. tab.getCustomView().setSelected(true);
  74. tab.getCustomView().findViewById(R.id.line_indicator).setSelected(true);
  75. viewPager.setCurrentItem(tab.getPosition());
  76. }
  77. }
  78. @Override
  79. public void onTabUnselected(TabLayout.Tab tab) {
  80. if (tab.getCustomView() != null) {
  81. tab.getCustomView().setSelected(false);
  82. tab.getCustomView().findViewById(R.id.line_indicator).setSelected(false);
  83. }
  84. }
  85. @Override
  86. public void onTabReselected(TabLayout.Tab tab) {
  87. }
  88. });
  89. }
  90. /**
  91. * 自定义Indicator左右间距。适用于自定义Tab的情况下,在使用默认Tab时,通过tabPadding设置既可以了
  92. * 注意:除了tabPadding外,tabMinWidth的值也会影响Tab的宽度,特别是1-2两字符时,会非常明显
  93. */
  94. public static void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
  95. try {
  96. Class<?> tabLayout = tabs.getClass();
  97. Field tabStrip = tabLayout.getDeclaredField("mTabStrip");
  98. tabStrip.setAccessible(true);
  99. int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
  100. int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
  101. LinearLayout llTab = (LinearLayout) tabStrip.get(tabs);
  102. for (int i = 0; i < llTab.getChildCount(); i++) {
  103. View child = llTab.getChildAt(i);
  104. child.setPadding(0, 0, 0, 0);
  105. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
  106. params.leftMargin = left;
  107. params.rightMargin = right;
  108. child.setLayoutParams(params);
  109. child.invalidate();
  110. }
  111. } catch (Exception e) {
  112. e.printStackTrace();
  113. }
  114. }
  115. @Override
  116. public void onClick(View v) {
  117. if (tag != 7) {
  118. int currentTabPosition = (int) v.getTag() - OFFSET;
  119. if (currentTabPosition >= 0 && currentTabPosition < tabLayout.getTabCount()) {
  120. reSetTabLayout(currentTabPosition);
  121. //setCurrentItem时,当点击最边缘那个Tab后,TabLayout也会像之前那样,将被点击的那个Tab滚动到屏幕中间
  122. viewPager.setCurrentItem(currentTabPosition);
  123. }
  124. }
  125. Toast.makeText(this, "我们需要自己手动处理点击Tab后所有变化", Toast.LENGTH_SHORT).show();
  126. }
  127. private void reSetTabLayout(int currentTabPosition) {
  128. for (int j = 0, count = tabLayout.getTabCount(); j < count; j++) {
  129. TabLayout.Tab tab = tabLayout.getTabAt(j);
  130. if (tab != null) {
  131. View view = tab.getCustomView();
  132. if (view != null) {
  133. TextView tv_tab_name = (TextView) view.findViewById(R.id.tv_tab_name);
  134. View line_indicator = view.findViewById(R.id.line_indicator);
  135. tv_tab_name.setText(list.get(j));
  136. if (j == currentTabPosition) {
  137. view.setSelected(true);
  138. line_indicator.setSelected(true);
  139. } else {
  140. view.setSelected(false);
  141. line_indicator.setSelected(false);
  142. }
  143. }
  144. }
  145. }
  146. }
  147. }

Activity_VP1 样式

  1. public class Activity_VP1 extends FragmentActivity {
  2. /**
  3. * 此Demo演示:不保存Fragment的引用,当adapter调用getItem时去【重新创建】新的Fragment
  4. */
  5. private List<String> list = new ArrayList<>(Arrays.asList(new String[]{"白", "1", "2", "3", "4", "5", "6", "7", "8",}));
  6. private PagerAdapter adapter;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. findViewById(R.id.tv_add).setVisibility(View.VISIBLE);
  12. findViewById(R.id.tv_remove).setVisibility(View.VISIBLE);
  13. ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
  14. //1、必须使用【FragmentStatePagerAdapter】,而不能使用FragmentPagerAdapter
  15. adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
  16. @Override
  17. public Fragment getItem(int position) {
  18. return MyFragment.newInstance(list.get(position));//每次都是创建新的Fragment
  19. }
  20. @Override
  21. public int getCount() {
  22. return list.size();
  23. }
  24. //2、必须重写getItemPosition,并且返回【PagerAdapter.POSITION_NONE】
  25. @Override
  26. public int getItemPosition(Object object) {
  27. return PagerAdapter.POSITION_NONE;
  28. }
  29. };
  30. viewPager.setAdapter(adapter);
  31. }
  32. public void add(View view) {
  33. list.add(0, new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()).format(new Date()));
  34. adapter.notifyDataSetChanged();
  35. }
  36. public void remove(View view) {
  37. if (list.size() > 0) list.remove(0);
  38. adapter.notifyDataSetChanged();
  39. }
  40. }

Activity_VP2 样式

  1. public class Activity_VP2 extends FragmentActivity {
  2. /**
  3. * 此Demo演示:保存所有Fragment的引用,当adapter调用getItem时去【获取】已经创建的Fragment
  4. */
  5. private List<Fragment> fragments;
  6. private PagerAdapter adapter;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. findViewById(R.id.tv_add).setVisibility(View.VISIBLE);
  12. findViewById(R.id.tv_remove).setVisibility(View.VISIBLE);
  13. ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
  14. String[] array = new String[]{"baiqiantao", "白", "包青天", "白乾涛", "1", "2", "3", "4", "5", "6", "7", "8",};
  15. fragments = new ArrayList<>();
  16. for (String string : array) {
  17. fragments.add(MyFragment.newInstance(string));
  18. }
  19. //1、必须使用【FragmentStatePagerAdapter】,而不能使用FragmentPagerAdapter
  20. adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {
  21. @Override
  22. public Fragment getItem(int position) {
  23. return fragments.get(position);//这里的Fragment都是已经创建好的,而不是getItem时重新创建的
  24. }
  25. @Override
  26. public int getCount() {
  27. return fragments.size();
  28. }
  29. //2、必须重写getItemPosition,并且返回【PagerAdapter.POSITION_NONE】
  30. @Override
  31. public int getItemPosition(Object object) {
  32. return POSITION_NONE;
  33. }
  34. };
  35. viewPager.setAdapter(adapter);
  36. }
  37. public void add(View view) {
  38. String data = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault()).format(new Date());
  39. fragments.add(0, MyFragment.newInstance(data));
  40. setFragments(fragments);
  41. }
  42. public void remove(View view) {
  43. if (fragments.size() > 0) fragments.remove(0);
  44. setFragments(fragments);
  45. }
  46. public void setFragments(List<Fragment> fragments) {
  47. FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  48. for (Fragment f : fragments) {
  49. ft.remove(f);
  50. }
  51. ft.commit();
  52. getSupportFragmentManager().executePendingTransactions();
  53. this.fragments = fragments;
  54. adapter.notifyDataSetChanged();
  55. }
  56. }

XML布局

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical">
  8. <TextView
  9. android:id="@+id/tv_add"
  10. android:layout_width="match_parent"
  11. android:layout_height="50dp"
  12. android:background="@color/colorAccent"
  13. android:gravity="center"
  14. android:onClick="add"
  15. android:text="添加一个Item"
  16. android:visibility="gone"/>
  17. <TextView
  18. android:id="@+id/tv_remove"
  19. android:layout_width="match_parent"
  20. android:layout_height="50dp"
  21. android:background="@color/colorPrimary"
  22. android:gravity="center"
  23. android:onClick="remove"
  24. android:text="移除一个Item"
  25. android:visibility="gone"/>
  26. <android.support.design.widget.TabLayout
  27. android:id="@+id/tablayout1"
  28. android:layout_width="match_parent"
  29. android:layout_height="wrap_content"
  30. android:visibility="gone"
  31. app:theme="@style/Widget.Design.TabLayout"/>
  32. <android.support.design.widget.TabLayout
  33. android:id="@+id/tablayout2"
  34. style="@style/MyTabStyle"
  35. android:layout_width="match_parent"
  36. android:layout_height="wrap_content"
  37. android:visibility="gone"
  38. app:tabTextAppearance="@style/MyTabTextAppearance"/>
  39. <android.support.v4.view.ViewPager
  40. android:id="@+id/view_pager"
  41. android:layout_width="match_parent"
  42. android:layout_height="match_parent"/>
  43. </LinearLayout>

自定义Tab的布局

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="50dp"
  4. android:layout_height="35dp"
  5. android:background="@drawable/sel_tab_bgcolor">
  6. <TextView
  7. android:id="@+id/tv_tab_name"
  8. android:layout_width="wrap_content"
  9. android:layout_height="match_parent"
  10. android:layout_centerInParent="true"
  11. android:ellipsize="end"
  12. android:gravity="center"
  13. android:maxEms="3"
  14. android:maxLines="1"
  15. android:text="热门热门热门热门"
  16. android:textColor="@drawable/sel_tab_textcolor"
  17. android:textSize="12sp"/>
  18. <TextView
  19. android:id="@+id/line_indicator"
  20. android:layout_width="40dp"
  21. android:layout_height="3dp"
  22. android:layout_alignParentBottom="true"
  23. android:layout_centerHorizontal="true"
  24. android:background="@drawable/sel_tab_indicator"/>
  25. </RelativeLayout>

选择器

sel_tab_textcolor
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:color="#f00" android:state_selected="true"/>
  4. <item android:color="#00f"/>
  5. </selector>
sel_tab_bgcolor 和 sel_tab_indicator
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:state_selected="true">
  4. <shape>
  5. <corners android:radius="2dp"/>
  6. <solid android:color="#f00"/>
  7. </shape>
  8. </item>
  9. <item>
  10. <shape>
  11. <corners android:radius="2dp"/>
  12. <solid android:color="#00f"/>
  13. </shape>
  14. </item>
  15. </selector>

定义的样式

  1. <style name="MyTabStyle" parent="Widget.Design.TabLayout">
  2. <item name="android:background">@android:color/holo_green_dark</item><!--此背景会被tabBackground覆盖掉-->
  3. <item name="tabBackground">@android:color/holo_orange_dark</item><!--"通常"background的效果完全一样-->
  4. <item name="tabContentStart">20dp</item><!--此值导致左边一块区域属于background,但不属于tabBackground-->
  5. <item name="tabGravity">fill</item><!--只能是fillcenter,貌似没有卵用啊-->
  6. <item name="tabIndicatorHeight">5dp</item>
  7. <item name="tabIndicatorColor">#f00</item>
  8. <item name="tabMaxWidth">120dp</item>
  9. <item name="tabMinWidth">20dp</item>
  10. <item name="tabPadding">0dp</item>
  11. <item name="tabMode">scrollable</item>
  12. <item name="tabSelectedTextColor">#f00</item>
  13. <!--以下属性貌似都无效!-->
  14. <item name="android:ellipsize">end</item>
  15. <item name="android:maxLines">1</item>
  16. <item name="android:gravity">top</item>
  17. <item name="android:textColor">#fff</item>
  18. </style>
  19. <style name="MyTabTextAppearance" parent="TextAppearance.Design.Tab"><!--必须继承自TextAppearance.Design.Tab -->
  20. <!--只支持以下三个属性-->
  21. <item name="android:textSize">15sp</item>
  22. <item name="android:textAllCaps">false</item>
  23. <!--选择器无效!除非根据tab的选中状态手动设置-->
  24. <item name="android:textColor">@drawable/sel_tab_textcolor</item>
  25. </style>
2017-6-28


null


TabLayout 和 ViewPager【综合示例】