本文共 7212 字,大约阅读时间需要 24 分钟。
第4弹,TabLayout 实现滑动选项卡
如上图的滑动选项卡的效果在移动端的应用中很是常见,之前要是该效果需要利用动态加载布局技术和控制滑动技术(比如利用HorizontalScrollView),较为繁琐。不过现在就完全不同了,Design Support Library提供了功能强大的TabLayout来帮助我们实现动态滑动选项卡。它可以和ViewPager很好地配合,让我们来看看它们如何工作的吧。
以上是页面布局文件,其中的重点看本次的主角TabLayout和ViewPager,其他的控件都是陪衬。
AppbarLayout继承自LinearLayout,上文介绍NavigationView时候已经出场了,它就是一个垂直方向的LinearLayout,并支持滑动手势,它可以让你定制在某个可滑动的View滑动手势发生改变时,内部的子View也做出相应的变化,下一集中它和CoordinatorLayout才是主角,这里让它提前登场混个脸熟(没错,这里是下一篇文章的伏笔)。
请注意TabLayout中的app:tabMode="scrollable"属性,它设定TabLayout是的标签是可以滑动的:当标签过多而设备屏幕无法将其全部展示时,可以滑动切换Tab。如果被设定app:tabMode="fixed",则代表Tab都是固定的,不能滑动切换。对比效果如下:
ViewPager在布局文件还不需要更多的设置,我们需要在代码中为ViewPager和TabLayout绑定关系。
在实现ViewPager与TabLayout协同工作之前,我们需要做点准备工作,就是为TabLayout和ViewPager中的Fragment生成要显示的数据,这里为了便于研究就是显示一些字符串。
//标签文字private ListmTitles;//Fragment中显示的提示词private List mWords;//ViewPager中加载的Fragmentprivate List mFragments;//数据长度private final int mSize = 8;//初始化待显示的数据private void initData() { //初始化Tab标签 mTitles = new StringGenerator("title").generateList(mSize); //初始化Fragment中显示提示词 mWords = new StringGenerator("Fragment").generateList(mSize); //初始化待放入View中的Fragment mFragments = new ArrayList<>(); for (int i = 0; i < mSize; i++) { TabFragment fragment = new TabFragment(); fragment.setWords(mWords.get(i)); mFragments.add(fragment); }}
这里调用自定义的生成器StringGenerator来生成数据,填充List类型的mTitles和mWords,这是一种常见的为了测试而生成数据并填充容器的方法,参考了《Thinking in Java》第17章。其代码如下
public class StringGenerator implements Generator{ private String preString; private int index = 0; public StringGenerator(String preString){ this.preString = preString; } @Override public String next() { return preString+(index++); } public List generateList(int size){ if(size<1){ return null; } List list = new ArrayList<>(); for (int i=0;i { T next();}
众所周知,ViewPager只是一中要容器,需要在其中记载Fragment才能显示内容。TabFragment是自定义的Fragment,其内容很简单,布局里只有一个TextView来显示字符串。代码如下:
public class TabFragment extends android.support.v4.app.Fragment { private String words; private TextView mTextView; public TabFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_tab,null); findView(view); return view; } private void findView(View view) { mTextView = (TextView) view.findViewById(R.id.tv_in_tab_fragment); mTextView.setText(words); } public String getWords() { return words; } public void setWords(String words) { this.words = words; }}
现在准备工作已经完成,进入重点内容:设置适配器让TabLayout和ViewPager协同工作。其流程如下:
由此可见其核心就是在于构建适配器FragmentPagerAdapter。
实现代码如下:
private ViewPager mViewPager; private TabLayout mTabLayout; private FloatingActionButton mActionButton;//浮动按钮;//初始化ViewPager private void initViewPager() { initData(); //预加载 mViewPager.setOffscreenPageLimit(mTitles.size()/2); //ViewPager滑动监听 mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } //只有位置为0的Fragment才会显示浮动按钮; @Override public void onPageSelected(int position) { if(position==0){ mActionButton.setVisibility(View.GONE); } else { mActionButton.setVisibility(View.VISIBLE); } } @Override public void onPageScrollStateChanged(int state) { } }); //为ViewPager设置适配器,设定Fragment和title的关系 //设置不同Fragment对应不同的Title mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } @Override public CharSequence getPageTitle(int position) { return mTitles.get(position); } }); //将ViewPage绑定到TabLayout mTabLayout.setupWithViewPager(mViewPager); //去掉ActionBar的渐进阴影 getSupportActionBar().setElevation(0); }
其核心代码就是
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } @Override public CharSequence getPageTitle(int position) { return mTitles.get(position); } }); //将ViewPage绑定到TabLayout mTabLayout.setupWithViewPager(mViewPager);
最后补上其余实现代码:
public class TabLayoutActivity extends AppCompatActivity { private ViewPager mViewPager; private TabLayout mTabLayout; private FloatingActionButton mActionButton; private final int mSize = 8; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tab_layout); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); initView(); } //初始Activity中的各种View private void initView() { mViewPager = (ViewPager) findViewById(R.id.viewpager); mTabLayout = (TabLayout) findViewById(R.id.tabs); mActionButton = (FloatingActionButton) findViewById(R.id.btnFloatingAction); mActionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Snackbar.make(v, "Hello SnackBar!", Snackbar.LENGTH_SHORT) .setAction("Undo", new View.OnClickListener() { @Override public void onClick(View v) { // Perform anything for the action selected } }) .show(); } }); initViewPager();//具体代码见前文 }
效果如下:
更多关于Design Support Library中控件的讲解将会在持续更新,欢迎关注。
最后给出转载地址:http://yijla.baihongyu.com/