Tablayout ViewPage 使用示例
上一篇文章介绍了使用 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 文件可以参考上一篇文章中的布局
或者直接查看源码所在地:
https://github.com/huanshen/Learn-Android/tree/master/TablayoutViewpager
Tablayout ViewPage 使用示例的更多相关文章
- 【Scroller】scrollTo scrollBy startScroll computeScroll 自定义ViewPage 简介 示例
简介 android.widget.Scroller是用于模拟scrolling行为,它是scrolling行为的一个帮助类.我们通常通过它的 startScroll 函数来设置一个 scrollin ...
- 仿9GAG制作过程(一)
有话要说: 准备开始学习Android应用程序的一个完整的设计过程.准备做一个仿9GAG的APP,前端界面设计+后台数据爬虫+后台接口设计,整个流程体验一遍.今天准备先把前端界面的框架给完成了. 成果 ...
- viewpage和tablayout导航栏
引入material库: implementation 'com.google.android.material:material:1.2.1' <?xml version="1.0& ...
- ViewPage 大圣归来 原生示例
VP简介 android-support-v4.jar 是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而ViewPage就是其中之一,利用它,我 ...
- TabLayout 简单使用。
先上效果图 在使用TabLayout 之前需要导入design包. 我使用的是android studio 只要在build.gradle中加入 compile 'com.android.suppor ...
- ViewPager导航栏TabLayout
ViewPager中加入TabLayout导航 需要导入依赖包: 'com.android.support:appcompat-v7:xxxxx' compile 'com.android.supp ...
- Android Material Design控件学习(一)——TabLayout的用法
前言 Google官方在14年Google I/O上推出了全新的设计语言--Material Design.一并推出了一系列实现Material Design效果的控件库--Android Desig ...
- 使用TabLayout快速实现一个导航栏
在没有Material Design的年代,要实现一个类似微信主页面的效果,我们有以下几种解决方案: 1.Fragment + ViewPager + RadioGroup自定义固定导航条 2.F ...
- 介绍三个Android支持库控件:TabLayout+ViewPager+RecyclerView
本文主要介绍如下三个Android支持库控件的配合使用: TabLayout:android.support.design.widget.TabLayout ViewPager:android.sup ...
随机推荐
- 五十个小技巧提高PHP执行效率(二)
更详细具体的总结如下: 1.用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量, 单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的 ...
- 使用vee-validate表单插件是如何设置中文提示?
最近在写vue表单验证的时候,在网上找到一款不错的插件vee-validate,在使用的过程中发现配置不了中文提示,这就很苦恼了,基本上网上的配置办法我都看过,都是有问题的,比如这种 import z ...
- springBoot系列教程02:mongodb的集成及使用
1.安装mongodb mongdb的安装很简单,只需要下载解压后运行mongod就好了 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86 ...
- NOIP2014无线网络发射器选址改编1
问题描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129条东西向街道和129条南北向街道所形成的网格状,并且相邻的平 ...
- 【Keras】从两个实际任务掌握图像分类
我们一般用深度学习做图片分类的入门教材都是MNIST或者CIFAR-10,因为数据都是别人准备好的,有的甚至是一个函数就把所有数据都load进来了,所以跑起来都很简单,但是跑完了,好像自己还没掌握图片 ...
- Struts2入门到放弃
写在前面------------------------------------------------------------------------- 本文章主要从三个方面来学习Struts2框架 ...
- 蓝牙核心技术概述(五):蓝牙协议规范(irOBEX、BNEP、AVDTP、AVCTP)
关键词:蓝牙核心技术协议 irDA BNEP AVDTP AVCTP 作者:xubin341719(欢迎转载,请注明作者,请尊重版权,谢谢! )欢迎指正错误,共同学习.共同进步!! 下载链接:Bl ...
- eclipse中JDK、struts2、Spring、Hibernate源码查看
一般,我们导入的只有jar文件,所以看不到对于的java文件,如果需要看源码,必须下载对应开源包的源码,一般都是zip文件,比如Spring,下载spring-framework-2.0.8-with ...
- javascript中的事件Event
一.事件流 1.事件流:描述的是从页面中接受事件的顺序 IE的事件流是事件冒泡流,Netscape的事件流是事件捕获流. 2.事件冒泡 IE的事件流叫做事件冒泡(event bubbing),即事件开 ...
- nginx、fastCGI、php-fpm关系梳理
前言: Linux下搭建nginx+php+memached(LPMN)的时候,nginx.conf中配需要配置fastCGI,php需要安装php-fpm扩展并启动php-fpm守护进程,nginx ...