实际开发中,ViewPager经常结合Fragment来使用,然后再使用三方开源的PagerSlidingTabStrip去实现类似选项卡滑动效果。我之前那个APP的首页就是这样搭建的。
基于Material Design设计的分享文字图片的APP
现在,我们可以和这种方式说拜拜了。先看效果图:
可以随意添加标题,可以修改标题与指示器样式,可以快速滑动选择标题。和当前主流APP的首页效果还是很像的。而这一切,只需要今天的主角—-TabLayout来帮你搞定即可。
Google在2015的IO大会上,给我们带来了Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,给我们提供了更加规范的MD设计风格的控件。最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2。TabLayout是Android Design Support Library库中的控件。
来看看怎么使用:
1.准备工作:
在build.gradle加入如下代码:
compile 'com.android.support:design:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
2.布局文件:
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="50dp">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
上面是我们的TabLayout,其中属性配置在后面会进行设置,下面就是熟悉的viewpager
3.代码实现:
public class TabLayoutActivity extends AppCompatActivity {
private TabLayout tab;
private ViewPager viewpager;
private TabAdapter adapter;
public static final String[] tabTitle = new String[]{"综艺", "体育", "新闻", "热点", "头条", "军事", "历史", "科技", "人文", "地理"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_layout);
initviews();
}
private void initviews() {
tab = (TabLayout) findViewById(R.id.tab);
viewpager = (ViewPager) findViewById(R.id.viewpager);
List<Fragment> fragments = new ArrayList<>();
for (int i = 0; i < tabTitle.length; i++) {
fragments.add(TabLayoutFragment.newInstance(i + 1));
}
adapter = new TabAdapter(getSupportFragmentManager(), fragments);
//给ViewPager设置适配器
viewpager.setAdapter(adapter);
//将TabLayout和ViewPager关联起来。
tab.setupWithViewPager(viewpager);
//设置可以滑动
tab.setTabMode(TabLayout.MODE_SCROLLABLE);
}
}
准备好taTitle数组,适配器,然后给Viewpager设置适配器,将TabLayout和ViewPager关联起来,最后就是设置tab可以滑动,不然标题太多,会挤满上方屏幕。再来看看Adapter的代码:
public class TabAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public TabAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
//设置tablayout标题
@Override
public CharSequence getPageTitle(int position) {
return TabLayoutActivity.tabTitle[position];
}
}
记得加上设置tablayout这个方法。接下来就是fragment的代码了:
/**
* Created by tangyangkai on 16/5/12.
*/
public class TabLayoutFragment extends Fragment {
public static String TABLAYOUT_FRAGMENT = "tab_fragment";
private TextView txt;
private int type;
public static TabLayoutFragment newInstance(int type) {
TabLayoutFragment fragment = new TabLayoutFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(TABLAYOUT_FRAGMENT, type);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
type = (int) getArguments().getSerializable(TABLAYOUT_FRAGMENT);
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tablayout, container, false);
initView(view);
return view;
}
protected void initView(View view) {
txt = (TextView) view.findViewById(R.id.tab_txt);
switch (type) {
case 1:
txt.setText("这是综艺Fragment");
break;
case 2:
txt.setText("这是体育Fragment");
break;
case 3:
txt.setText("这是新闻Fragment");
break;
case 4:
txt.setText("这是热点Fragment");
break;
case 5:
txt.setText("这是头条Fragment");
break;
case 6:
txt.setText("这是军事Fragment");
break;
case 7:
txt.setText("这是历史Fragment");
break;
case 8:
txt.setText("这是科技Fragment");
break;
case 9:
txt.setText("这是人文Fragment");
break;
case 10:
txt.setText("这是地理Fragment");
break;
}
}
}
关于使用setArguments()来创建Fragment,这种方法在上一篇博客里面着重给大家推荐了
从BaseActivity与BaseFragment的封装谈起
这里我们再一次看到了其中的好处,就是fragment的复用。根据传递过来的不同参数,显示不同的界面。TabLayout非常适合那种界面相差不大的,就像CSDN客户端首页,都是显示技术类文章,只是分类不一样而已。
当然,你要是说,要是我这些界面差异很大怎么办,没问题:
List<Fragment> fragments = new ArrayList<>();
for (int i = 0; i < tabTitle.length; i++) {
fragments.add(TabLayoutFragment.newInstance(i + 1));
}
我在这里放进不同的fragment即可。原则就是:相似的我就复用,不一样的我就新增
图示效果是默认样式的,要是想修改一下文字,指示器样式咋办,很简单:
官方的 TabLayout 没有提供修改 TextView size 的方法,可以新建一个 style CustomTabLayoutTextAppearance 继承 TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse ,然后增加 item 再设置 android:textSize 为你想设置的大小。
<style name="MyTabLayoutTextAppearanceInverse" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse">
<item name="android:textSize">20sp</item>
</style>
XML文件中使用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
app:tabTextAppearance="@style/MyTabLayoutTextAppearanceInverse"
tools:context="com.example.tangyangkai.testdemo.TabLayoutActivity">
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabSelectedTextColor="@color/colorAccent"
app:tabTextAppearance="@style/MyTabLayoutTextAppearanceInverse"
app:tabTextColor="@color/colorPrimary"
app:tabIndicatorColor="@color/colorAccent">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
</LinearLayout>
依次是设置选中字体颜色,大小,正常颜色,以及指示器的颜色,看完改完的效果:
纯属演示,大家可以自己设置自己喜欢的风格。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~分割线
无意间看到别的APP的首页,好多好看的效果。果断去github了一把,果然找到了。
上图:
给大家链接地址:
感兴趣的可以研究研究。
收工!!!又到周五啦,大家周末愉快