FragmentTabHost +viewpager
这个方式 跟上面那个方式差不多 都是通过 监听 实现联动
如果只使用FragmentTabHost 只能实现 点击tab切换 页面的效果 不能实现左右滑动 而 结合viewPager 刚好实现这一效果
先来看看FragmentTabHost经常用的方法
- setup() 在使用addTab之前调用 设置必要的数据 如 FragmentManager,Fragment的容器id
- addTab() 添加标签
- newTabSpec() 新建 tab
- setCurrentTab() 设置当前显示的标签
- setOnChangeTabListtener 设置tab选中改变监听
- tabHost.getTabWidget().setDividerDrawable(null); //去除间隔线
- Tab的常用方法:
- setIndicator() 可以设置view 和 字符串
main布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_tab_pager" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.skymxc.demo.fragment.TabPagerActivity"> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"></android.support.v4.view.ViewPager> <android.support.v4.app.FragmentTabHost android:id="@+id/tab_host" android:layout_width="match_parent" android:layout_height="wrap_content"></android.support.v4.app.FragmentTabHost> </LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
Framgent 简单起见 就不写布局文件了 其他的Fragment 跟这个类似
public class DiscoverFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setText("发现"); textView.setGravity(Gravity.CENTER); return textView; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
tab 的布局 图片在上 文本在下 比较简单
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/icon" android:layout_width="30dp" android:layout_height="30dp" android:layout_gravity="center"/> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/selector_font" android:text="发现" android:layout_gravity="center"/> </LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
selector 基本类似 这里贴一个
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@mipmap/cb_icon_discover_selected"/> <item android:drawable="@mipmap/cb_icon_discover_normal"/> </selector>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Java 代码
初始化 TabHost
private void initTabHost() { tabHost.setup(this,getSupportFragmentManager(), R.id.pager); tabHost.getTabWidget().setDividerDrawable(null); tabHost.addTab(tabHost.newTabSpec("discover").setIndicator(createView(R.drawable.selector_bg,"发现")), DiscoverFragment.class,null); tabHost.addTab(tabHost.newTabSpec("attach").setIndicator(createView(R.drawable.selector_bg_attach,"关注")), AttachFragment.class,null); tabHost.addTab(tabHost.newTabSpec("message").setIndicator(createView(R.drawable.selector_bg_message,"消息")), MsgFragment.class,null); tabHost.addTab(tabHost.newTabSpec("info").setIndicator(createView(R.drawable.selector_bg_info,"我的")), ContactFragment.class,null); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
初始化 pager 并绑定适配器
/** * 初始化 pager 绑定适配器 */ private void initPager() { fragments = new ArrayList<>(); fragments.add(new DiscoverFragment()); fragments.add(new AttachFragment()); fragments.add(new MsgFragment()); fragments.add(new ContactFragment()); FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager(),fragments); pager.setAdapter(adapter); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
分别给 TabHost 和pager 添加监听 实现联动
/** * 为TabHost和viewPager 添加监听 让其联动 */ private void bindTabAndPager() { tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() { /** * tab改变后 * @param tabId 当前tab的tag */ @Override public void onTabChanged(String tabId) { log("vonTabChanged:"+tabId); int position = tabHost.getCurrentTab(); pager.setCurrentItem(position,true); } }); pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { /** * 页面滑动 触发 * @param position 当前显得第一个页面的索引,当滑动出现时屏幕就会显示两个pager, 向右滑 position为当前-1(左边的pager就显示出来了),向左滑position为当前(右面就显出来了), * @param positionOffset 0-1之间 position的偏移量 从原始位置的偏移量 * @param positionOffsetPixels 从position偏移的像素值 从原始位置的便宜像素 */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { log("onPageScrolled=============position:"+position+"====positionOffset:"+positionOffset+"====positionOffsetPixels:"+positionOffsetPixels); } /** * 页面选中后 * @param position 当前页面的index */ @Override public void onPageSelected(int position) { tabHost.setCurrentTab(position); log("onPageSelected==========:position:"+position); } /** * 页面滑动状态改变时触发 * @param state 当前滑动状态 共三个状态值 */ @Override public void onPageScrollStateChanged(int state) { String stateStr=""; switch (state){ case ViewPager.SCROLL_STATE_DRAGGING: stateStr="正在拖动"; break; case ViewPager.SCROLL_STATE_SETTLING: stateStr="正在去往最终位置 即将到达最终位置"; break; case ViewPager.SCROLL_STATE_IDLE: stateStr="滑动停止,当前页面充满屏幕"; break; } log("onPageScrollStateChanged========stateCode:"+state+"====state:"+stateStr); } }); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
完整代码
public class TabPagerActivity extends AppCompatActivity { private static final String TAG ="TabPagerActivity"; private FragmentTabHost tabHost; private ViewPager pager; private List<Fragment> fragments; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tab_pager); tabHost = (FragmentTabHost) findViewById(R.id.tab_host); pager = (ViewPager) findViewById(R.id.pager); //初始化TabHost initTabHost(); //初始化pager initPager(); //添加监听关联TabHost和viewPager bindTabAndPager(); } /** * 为TabHost和viewPager 添加监听 让其联动 */ private void bindTabAndPager() { tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() { /** * tab改变后 * @param tabId 当前tab的tag */ @Override public void onTabChanged(String tabId) { log("vonTabChanged:"+tabId); int position = tabHost.getCurrentTab(); pager.setCurrentItem(position,true); } }); pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { /** * 页面滑动 触发 * @param position 当前显得第一个页面的索引,当滑动出现时屏幕就会显示两个pager, 向右滑 position为当前-1(左边的pager就显示出来了),向左滑position为当前(右面就显出来了), * @param positionOffset 0-1之间 position的偏移量 从原始位置的偏移量 * @param positionOffsetPixels 从position偏移的像素值 从原始位置的便宜像素 */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { log("onPageScrolled=============position:"+position+"====positionOffset:"+positionOffset+"====positionOffsetPixels:"+positionOffsetPixels); } /** * 页面选中后 * @param position 当前页面的index */ @Override public void onPageSelected(int position) { tabHost.setCurrentTab(position); log("onPageSelected==========:position:"+position); } /** * 页面滑动状态改变时触发 * @param state 当前滑动状态 共三个状态值 */ @Override public void onPageScrollStateChanged(int state) { String stateStr=""; switch (state){ case ViewPager.SCROLL_STATE_DRAGGING: stateStr="正在拖动"; break; case ViewPager.SCROLL_STATE_SETTLING: stateStr="正在去往最终位置 即将到达最终位置"; break; case ViewPager.SCROLL_STATE_IDLE: stateStr="滑动停止,当前页面充满屏幕"; break; } log("onPageScrollStateChanged========stateCode:"+state+"====state:"+stateStr); } }); } /** * 初始化 pager 绑定适配器 */ private void initPager() { fragments = new ArrayList<>(); fragments.add(new DiscoverFragment()); fragments.add(new AttachFragment()); fragments.add(new MsgFragment()); fragments.add(new ContactFragment()); FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager(),fragments); pager.setAdapter(adapter); } /** * 初始化 TabHost */ private void initTabHost() { tabHost.setup(this,getSupportFragmentManager(), R.id.pager); tabHost.getTabWidget().setDividerDrawable(null); tabHost.addTab(tabHost.newTabSpec("discover").setIndicator(createView(R.drawable.selector_bg,"发现")), DiscoverFragment.class,null); tabHost.addTab(tabHost.newTabSpec("attach").setIndicator(createView(R.drawable.selector_bg_attach,"关注")), AttachFragment.class,null); tabHost.addTab(tabHost.newTabSpec("message").setIndicator(createView(R.drawable.selector_bg_message,"消息")), MsgFragment.class,null); tabHost.addTab(tabHost.newTabSpec("info").setIndicator(createView(R.drawable.selector_bg_info,"我的")), ContactFragment.class,null); } /** * 返回view * @param icon * @param tab * @return */ private View createView(int icon,String tab){ View view = getLayoutInflater().inflate(R.layout.fragment_tab_discover,null); ImageView imageView = (ImageView) view.findViewById(R.id.icon); TextView title = (TextView) view.findViewById(R.id.title); imageView.setImageResource(icon); title.setText(tab); return view; } private void log(String log){ Log.e(TAG,"="+log+"="); } }