TabLayout+ViewPager+Fragment(懒加载)实现导航栏

之前,实现导航栏的效果有很多方法,使用第三方库,比如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) {

            }
        });
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘彦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值