之前,实现导航栏的效果有很多方法,使用第三方库,比如ViewPagerIndicator中的TabPagerIndicator,谷歌可能发现,导航栏使用的挺普遍的,so,也搞了一个属于自己的导航栏!就像侧滑菜单一样,也搞了一个属于自己的侧滑菜单DrawerLayout!
效果图是这样的:
跟ViewPagerIndicator实现的效果是一样的!
接下来看代码:
首先呢!需要compile一下:
compile 'com.android.support:design:25.3.1'
然后TabLayout就跟普通控件使用一样了!直接在xml里设置即可,代码如下:
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
app:tabIndicatorColor="#ff0000"
app:tabSelectedTextColor="#ff0000"
app:tabTextColor="#cccccc"
app:tabMode="scrollable"/>
属性说明:
app:tabIndicatorColor:指示器那条下划线的颜色
app:tabTextColor:上面文本颜色
app:tabSelectedTextColor:文本被选中后的颜色
app:tabMode="scrollable" 适用于多文本的滑动
当然,还有一些别的属性,比如设置指示器下划线的粗细等等。
接下来就是HomeActivity的代码:
public class HomeActivity extends FragmentActivity implements View.OnClickListener{
private ViewPager viewpager;
private TabLayout layout;
private DrawerLayout leftMenu;
private ImageView touxiang;
private List<String> titles = new ArrayList<>();
private List<Fragment> fragments = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
initView();
initData();
viewpager.setAdapter(new PagerAdapter(getSupportFragmentManager(),titles,fragments));
layout.setupWithViewPager(viewpager);//将导航栏和viewpager进行关联
layout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewpager.setCurrentItem(tab.getPosition());//联动
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void initData() {
titles.add("推荐");
titles.add("热点");
titles.add("美女");
titles.add("军事");
titles.add("数码");
titles.add("体育");
titles.add("汽车");
fragments.add(new TuiJianFragment());
fragments.add(new ReDianFragment());
fragments.add(new BeautyFragment());
fragments.add(new JunShiFragment());
fragments.add(new ShuMaFragment());
fragments.add(new SportFragment());
fragments.add(new CarFragment());
}
private void initView() {
viewpager = (ViewPager) findViewById(R.id.viewpager);
touxiang = (ImageView) findViewById(R.id.touxiang);
layout = (TabLayout) findViewById(R.id.title);
leftMenu = (DrawerLayout) findViewById(R.id.left_menu);
touxiang.setOnClickListener(this);
}
@Override
public void onClick(View v) {
leftMenu.openDrawer(GravityCompat.START);//打开侧滑菜单
}
}
适配器:
public class PagerAdapter extends FragmentPagerAdapter {
private List<String> titles;
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<String> titles,List<Fragment> fragments) {
super(fm);
this.titles = titles;
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
}
搞定!
————————————————————————————————————————————————————————————————
更多属性:
app:tabBackground="color"//整个TabLayout的颜色,这里不能直接写RGB,需要@color/xx
app:tabTextAppearance="@android:style/TextAppearance.Holo.Large"//设置文字的外貌大小
app:tabIndicatorHeight="2dp"//设置指示器下划线粗细,如果设置成0dp,则不显示指示器
app:tabMode="scrollable"//默认是fixed:固定的,标签很多时候会被挤压,不能滑动。
app:tabGravity="center"//居中,如果是fill,则是充满
默认选中某项这样设置:
tablayout.getTabAt(position).select();
————————————————————————————————————————————————————
PS:通常遇到这种组合,也需要实现Fragment懒加载,因为涉及到ViewPager的预加载特性,会预加载当前Fragment的前一个和后一个Fragment的数据。我们要实现的效果就是只有当点击该Fragment的时候,再去请求网络数据,禁用掉ViewPager的预加载特性,这样就节省很多开销。
可以让Fragment继承如下的BaseFragment:
public abstract class BaseFragment extends Fragment {
protected boolean isInit;
protected boolean isReallyLazy;//是否完全懒加载
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(setLayoutResourceID(), container, false);
init();
isInit = true;
isCanLoadData();
return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isCanLoadData();
}
private void isCanLoadData() {
//isReallyLazy为true实现完全懒加载,Fragment只会加载一次,再切回来的时候,不会加载,去掉该属性的话,再切回来的时候会重新加载
if (getUserVisibleHint() && isInit && !isReallyLazy) {
getData();
isReallyLazy = true;
}
}
protected abstract int setLayoutResourceID();
protected abstract void init();
protected abstract void getData();
@Override
public void onDestroyView() {
super.onDestroyView();
isInit = false;
}
}
这样就可以将一进入该Fragment加载网络数据的方法,或者是切换回该Fragment需要刷新数据的方法都放在上面的方法里了。
————————————————————————————————————————————————————————————
下面再实现一种案例。项目中有时会用到,就是Tab选项添加图片,可以随意控制图片在Tab中的位置。效果图大概如下:
左右滑动,可以改变字体颜色和图片。
核心代码:适配器getPageTitle返回null即可,然后增加一个自定义样式的方法:
public View getTabView(int position) {
View view = LayoutInflater.from(context).inflate(R.layout.tab_item, null);
TextView tab_title = view.findViewById(R.id.tab_title);
tab_title.setText(titles.get(position));
ImageView img = view.findViewById(R.id.tab_icon);
if (position == 0) {
tab_title.setTextColor(Color.RED);
img.setImageResource(R.drawable.icon_selected);
}
if (position == 1) {
tab_title.setTextColor(Color.GRAY);
img.setImageResource(R.drawable.flower_unselected);
}
if (position == 2) {
tab_title.setTextColor(Color.GRAY);
img.setImageResource(R.drawable.coin_unselected);
}
return view;
}
其中的tab_item布局就是随便定义文字和图片的摆放位置。这里我是将图片放在文字的右侧:
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="horizontal"
android:gravity="center">
<TextView
android:id="@+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/tab_icon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginLeft="4dp" />
</LinearLayout>
</LinearLayout>
最后Activity中进行设置:
在tabLayout.setupWithViewPager(viewPager)之后添加动态Tab内容
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
然后TabLayout的滑动监听,动态改变文字颜色和图片即可:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
View view = tab.getCustomView();
((TextView)(view.findViewById(R.id.tab_title))).setTextColor(Color.RED);
ImageView imageView = view.findViewById(R.id.tab_icon);
switch (tab.getPosition()){
case 0:
imageView.setImageResource(R.drawable.icon_selected);
break;
case 1:
imageView.setImageResource(R.drawable.flower_selected);
break;
case 2:
imageView.setImageResource(R.drawable.coin_selected);
break;
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
View view = tab.getCustomView();
((TextView)(view.findViewById(R.id.tab_title))).setTextColor(Color.GRAY);
ImageView imageView = view.findViewById(R.id.tab_icon);
switch (tab.getPosition()){
case 0:
imageView.setImageResource(R.drawable.icon_unselected);
break;
case 1:
imageView.setImageResource(R.drawable.flower_unselected);
break;
case 2:
imageView.setImageResource(R.drawable.coin_unselected);
break;
}
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});