Tablayout ViewPage 使用示例

时间:2021-09-16 22:45:23

上一篇文章介绍了使用 FragmenttabHost 来使用 tab 导航;到 Android 5.0 的时候,又推出了 TabLayout。因此,有必要对tablayout 进行了解下。

首先我们来看MainActivity,看起来有点多,那是因为包含了 toolbar 的代码:

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
private ViewPager viewPager;
private MyViewPagerAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}); tabLayout = (TabLayout) findViewById(R.id.tab_layout);
viewPager = (ViewPager) findViewById(R.id.pager); int s = 0; if (viewPager != null) {
setupViewPager(viewPager);
}
} private void setupViewPager(ViewPager viewPager) {
adapter = new MyViewPagerAdapter(getSupportFragmentManager(), this);
adapter.addFragment(new TabFragment1().newInstance("Page1"), "Tab 1");
adapter.addFragment(new TabFragment2().newInstance("Page2"), "Tab 2");
adapter.addFragment(new TabFragment3().newInstance("Page3"), "Tab 3");
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} return super.onOptionsItemSelected(item);
}

首先是初始化 tabLayout 和 viewPager,接着是建立一个 MyViewPagerAdapter 的实例,并向里面添加 fragment。

那我们就去看看神秘的 MyViewPagerAdapter。

public class MyViewPagerAdapter extends FragmentStatePagerAdapter {

    private final List<Fragment> myFragments = new ArrayList<>();
private final List<String> myFragmentTitles = new ArrayList<>();
private Context context; public MyViewPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
} public void addFragment(Fragment fragment, String title) {
myFragments.add(fragment);
myFragmentTitles.add(title);
} @Override
public Fragment getItem(int position) {
return myFragments.get(position);
} @Override
public int getCount() {
return myFragments.size();
} @Override
public CharSequence getPageTitle(int position) {
return myFragmentTitles.get(position);
}
}

这里我们重写了其中几个方法,分别是 getItem,getCount,getPageTitle。那这样我们的数量能够传进去嘛?

不用怕,当我们调用 setAdapt 的时候,其实就把 adapt 传进 ViewPager 了,当需要获取数量的时候,直接调用这个方法就可以了。

tabLayout.setupWithViewPager(viewPager) 则是把tab 与ViewPage 建立联系,这样在变动的时候一起变,在TabLaout 中,可以通过 viewPager.getAdapt 来获取我们刚刚穿进去的adapt;这样两者都有 adapt 这个变量了。

public void setupWithViewPager(ViewPager viewPager) {
PagerAdapter adapter = viewPager.getAdapter();
if(adapter == null) {
throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
} else {
this.setTabsFromPagerAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
}
}

看源码可以发现 tablayout 和 viewpager 互相设置或者添加监听器,这样无论是滑动 viewPager,还是点击tab都可以实现 view 的切换,两者就可以同步了。

public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
private final ViewPager mViewPager; public ViewPagerOnTabSelectedListener(ViewPager viewPager) {
this.mViewPager = viewPager;
} public void onTabSelected(TabLayout.Tab tab) {
this.mViewPager.setCurrentItem(tab.getPosition());
} public void onTabUnselected(TabLayout.Tab tab) {
} public void onTabReselected(TabLayout.Tab tab) {
}
}

我们可以具体看看 ViewPagerOnTabSelectedListener,发现其实现了 TabLayout.OnTabSelectedListener 的接口,在构造函数中,将 viewPager 变量赋值给内部变量,这样在 tab 选中的时候,获取选中 tab 的 position,然后再将设置显示 同样位置的 fragment 即可。

public static class TabLayoutOnPageChangeListener implements OnPageChangeListener {
private final WeakReference<TabLayout> mTabLayoutRef;
private int mScrollState; public TabLayoutOnPageChangeListener(TabLayout tabLayout) {
this.mTabLayoutRef = new WeakReference(tabLayout);
} public void onPageScrollStateChanged(int state) {
this.mScrollState = state;
} public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
TabLayout tabLayout = (TabLayout)this.mTabLayoutRef.get();
if(tabLayout != null) {
tabLayout.setScrollPosition(position, positionOffset, this.mScrollState == 1);
} } public void onPageSelected(int position) {
TabLayout tabLayout = (TabLayout)this.mTabLayoutRef.get();
if(tabLayout != null) {
tabLayout.getTabAt(position).select();
} }
}

当滑动页面,回掉  onPageSelected,传入目前选中的 pager,这时候只要指定对应的 tab 即可。这样两者很好的进行同步了。

我们再来看看布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true"
tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_scrollFlags="scroll|enterAlways" /> <android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#eeeeee"
app:tabTextColor="#888888"
app:tabSelectedTextColor="#000000"
app:tabGravity="fill"
app:tabMode="fixed"/> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/> <android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" /> </android.support.design.widget.CoordinatorLayout>

因为有 toolbar ,所以布局文件看上去有些复杂,但其实很简单。

简化后的布局(id 不一定对得上,其他地方 copy 过来的):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tabLayout"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#cdc36e"
app:tabMode="fixed"
app:tabGravity="fill"/> <android.support.v4.view.ViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/viewPager"
android:layout_below="@+id/tabLayout"
android:layout_centerHorizontal="true" />
</RelativeLayout>

至于 fragment 文件可以参考上一篇文章中的布局

fragmentTabHost 使用示例

或者直接查看源码所在地:

https://github.com/huanshen/Learn-Android/tree/master/TablayoutViewpager

Tablayout ViewPage 使用示例的更多相关文章

  1. 【Scroller】scrollTo scrollBy startScroll computeScroll 自定义ViewPage 简介 示例

    简介 android.widget.Scroller是用于模拟scrolling行为,它是scrolling行为的一个帮助类.我们通常通过它的 startScroll 函数来设置一个 scrollin ...

  2. 仿9GAG制作过程(一)

    有话要说: 准备开始学习Android应用程序的一个完整的设计过程.准备做一个仿9GAG的APP,前端界面设计+后台数据爬虫+后台接口设计,整个流程体验一遍.今天准备先把前端界面的框架给完成了. 成果 ...

  3. viewpage和tablayout导航栏

    引入material库: implementation 'com.google.android.material:material:1.2.1' <?xml version="1.0& ...

  4. ViewPage 大圣归来 原生示例

    VP简介 android-support-v4.jar 是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而ViewPage就是其中之一,利用它,我 ...

  5. TabLayout 简单使用。

    先上效果图 在使用TabLayout 之前需要导入design包. 我使用的是android studio 只要在build.gradle中加入 compile 'com.android.suppor ...

  6. ViewPager导航栏TabLayout

    ViewPager中加入TabLayout导航 需要导入依赖包:  'com.android.support:appcompat-v7:xxxxx' compile 'com.android.supp ...

  7. Android Material Design控件学习(一)——TabLayout的用法

    前言 Google官方在14年Google I/O上推出了全新的设计语言--Material Design.一并推出了一系列实现Material Design效果的控件库--Android Desig ...

  8. 使用TabLayout快速实现一个导航栏

    在没有Material Design的年代,要实现一个类似微信主页面的效果,我们有以下几种解决方案: 1.Fragment + ViewPager  +  RadioGroup自定义固定导航条 2.F ...

  9. 介绍三个Android支持库控件:TabLayout&plus;ViewPager&plus;RecyclerView

    本文主要介绍如下三个Android支持库控件的配合使用: TabLayout:android.support.design.widget.TabLayout ViewPager:android.sup ...

随机推荐

  1. jQuery版AJAX简易封装

    开发过程中,AJAX的应用应该说非常频繁,当然,jQuery的AJAX函数已经非常好用,但是小编还是稍微整理下,方便不同需求下,可以简化输入参数,下面是实例代码: $(function(){ /** ...

  2. 深化管理、提升IT的数据平台建设方案

    谈到信息化,每个企业有每个企业的业务模式,每个企业有每个企业不同的思考.落地有效的信息化建设一定紧跟着企业的发展,围绕业务和管理,来提升效率,创造价值. 对于企业如何在发展的不同阶段提升信息化建设,这 ...

  3. android中的回调请求的个人理解

    Fragment类提供了管理"选项菜单"的回调函数onCreateOptionMenu(Menu,MenuInflater),调用它可以--创建"选项菜单". ...

  4. sql server2008 字段类型

    bit    整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off. 注意:很省空间的一种数据类型, ...

  5. PHP5 各版本维护时间

    版本维护: 5.2:维护至:2011-01-06.支持:xp(2003)以上.最终版本:5.2.17. 5.3:维护至:2014-08-14.支持:xp(2003)以上.最终版本:5.3.29 5.4 ...

  6. Atitit&period;&period;文件上传组件选型and最佳实践总结&lpar;3&rpar;----断点续传控件的实现

    Atitit..文件上传组件选型and最佳实践总结(3)----断点续传控件的实现 1. 实现思路:::元插件,元设置... 1 2. 实现流程downzip,unzip,exec 1 3. Zip  ...

  7. ubuntu profile-environment-bashrc 添加环境变量

    Ubuntu Linux系统环境变量配置文件: /etc/profile : 在登录时,操作系统定制用户环境时使用的第一个文件 ,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. ...

  8. Vim 简明教程【转载】

    简明 Vim 练级攻略 第一级 – 存活 安装 vim 启动 vim 什么也别干!请先阅读 当你安装好一个编辑器后,你一定会想在其中输入点什么东西,然后看看这个编辑器是什么样子.但vim不是这样的,请 ...

  9. pyinstaller打包错误 UnicodeDecodeError&colon; &&num;39&semi;gbk&&num;39&semi; codec can&&num;39&semi;t decode byte 0xab in position 160&colon;

    注:我的博客原本在CSDN,现转到博客园,图片采用以前的图片,并没有盗图. 在将.py文件打包时,出现了下列错误 >>C:\Users\小呆\PycharmProjects\pycharm ...

  10. vue语法小练习

    实现功能:新增/删除 学生 <html> <head> <script src="https://cdn.staticfile.org/vue/2.2.2/vu ...