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

之前,实现导航栏的效果有很多方法,使用第三方库,比如ViewPagerIndicator中的TabPagerIndicator,谷歌可能发现,导航栏使用的挺普遍的,so,也搞了一个属于自己的导航栏!就像侧滑菜单一样,也搞了一个属于自己的侧滑菜单DrawerLayout!

效果图是这样的:

TabLayout+ViewPager+Fragment(懒加载)实现导航栏_第1张图片

跟ViewPagerIndicator实现的效果是一样的!

接下来看代码:

首先呢!需要compile一下:

compile 'com.android.support:design:25.3.1'

然后TabLayout就跟普通控件使用一样了!直接在xml里设置即可,代码如下:


属性说明:

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 titles = new ArrayList<>();
    private List 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 titles;
    private List fragments;

    public PagerAdapter(FragmentManager fm, List titles,List 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 = false;
    protected boolean isLoad = false;
    private View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(setLayoutResourceID(), container, false);
        init();
        isInit = true;
        isCanLoadData();
        return view;
    }

    /**
     * 视图是否已经对用户可见
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isCanLoadData();
    }

    /**
     * 是否可以加载数据
     * 可以加载数据的条件:
     * 1.视图已经初始化
     * 2.视图对用户可见
     */
    private void isCanLoadData() {
        if (!isInit) {
            return;
        }
        if (getUserVisibleHint()) {
            getData();
            isLoad = true;
        }
    }

    protected abstract int setLayoutResourceID();

    protected abstract void init();

    protected abstract void getData();

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isInit = false;
        isLoad = false;
    }
}
 

继承此Fragment会实现下面的方法:

public class OneFragment extends BaseFragment {

    @Override
    protected int setLayoutResourceID() {
        return R.layout.fragment_one;
    }

    @Override
    protected void init() {

    }

    @Override
    protected void getData() {
        //进行网络请求
    }
}

这样就可以将一进入该Fragment加载网络数据的方法,或者是切换回该Fragment需要刷新数据的方法都放在上面的方法里了。
————————————————————————————————————————————————————————————
下面再实现一种案例。项目中有时会用到,就是Tab选项添加图片,可以随意控制图片在Tab中的位置。效果图大概如下:
TabLayout+ViewPager+Fragment(懒加载)实现导航栏_第2张图片
左右滑动,可以改变字体颜色和图片。
核心代码:适配器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布局就是随便定义文字和图片的摆放位置。这里我是将图片放在文字的右侧:



    
        
        
    

最后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) {

            }
        });

你可能感兴趣的:(普通)