您的位置:首页 > 其它

ViewPager+Fragment实现Tab主界面

2015-04-22 12:34 295 查看
毕竟是第一次做项目,所以在每一点上都做得特别认真,接下来我来给大家大致讲述一下用ViewPager+Fragment来实现app Tab主界面,突然想起来LZ居然2天没去上课了......(>....<) 没办法,为了暑假的实习offer,只好拼了!!!

package com.bob.tabui;

import android.support.v4.app.*;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import android.view.View.*;
import android.widget.*;
import java.util.*;

public class MainActivity extends FragmentActivity implements OnClickListener {
    private ViewPager viewPager;//v4包下的一个控件,即就是一个可以左右滑动切换的东东
    private FragmentPagerAdapter adapter;//和ListView一个道理,集合——>适配器——>控件
    private List<Fragment> fragments = new ArrayList<>();

    /*
    底部的三个按钮以及所在布局,这里我们把这三个布局添加点击时间监听即可。三个按钮用来修改其背景图
     */
    private LinearLayout tab01;
    private LinearLayout tab02;
    private LinearLayout tab03;

    private ImageButton ib01;
    private ImageButton ib02;
    private ImageButton ib03;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        initView();//集中实例化这几个控件
        initEvent();

        adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {//定义一个数据适配器
            @Override//相当于添加数据了
            public Fragment getItem(int position) {//position即就是当前被选中或者要显示的数据在数据集合里的下标
                return fragments.get(position);//返回需要显示的控件
            }

            @Override
            public int getCount() {//获取数据集大小
                return fragments.size();
            }
        };
        viewPager.setAdapter(adapter);//将适配器进行最后一步的操作,安装到控件中

        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {//为ViewPager添加监听以随其动作更新ui,这点不同于BaseAdapter
            //主要原因在于我们需要将ViewPager和底部按钮进行联动处理,否则也用不着监听了

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            public void onPageSelected(int position) {
                Log.i("logging", position+"");
                resetTabBtn();//一定要在修改对应选中的按钮状态时先重置所有按钮,否则会让前边的效果影响后边
                switch (position) {//在响应该页被选中时,需要同时修改底部对应的按钮状态
                    case 0:
                        ib01.setImageResource(R.mipmap.one_clicked);
                        break;
                    case 1:
                        ib02.setImageResource(R.mipmap.two_clicked);
                        break;
                    case 2:
                        ib03.setImageResource(R.mipmap.one_clicked);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        //viewPager.setCurrentItem(0);//默认选中的是第一页,当然啦,我们也可以在这个地方进行自定义
        /**
         *需要说明的是,如果你不设置这个或者设置为和系统默认的一样的话,onPageSelected是不会被调用的
         * api: this method will be invoked when a new page becomes selected;
         * 接下来的读者自行脑补吧,哈哈~~~
         */
    }

    protected void resetTabBtn() {//重置每一个按钮的图标为灰暗
        ib01.setImageResource(R.mipmap.one_normal);
        ib02.setImageResource(R.mipmap.two_normal);
        ib03.setImageResource(R.mipmap.three_normal);
    }

    private void initView() {

        tab01 = (LinearLayout) findViewById(R.id.ll_first);
        tab02 = (LinearLayout) findViewById(R.id.ll_second);
        tab03 = (LinearLayout) findViewById(R.id.ll_third);

        ib01 = (ImageButton) findViewById(R.id.btn_first);//在这里我觉得不用以上三个布局进行查找也可以,博友如有高见,还请指出
        ib01.setImageResource(R.mipmap.one_clicked);//如果默认第一个,那就直接在这里进行选定高亮操作吧

        ib02 = (ImageButton) findViewById(R.id.btn_second);
        ib03 = (ImageButton) findViewById(R.id.btn_third);

        Tab01 frag01 = new Tab01();//实例化3个Fragment
        Tab02 frag02 = new Tab02();
        Tab03 frag03 = new Tab03();
        fragments.add(frag01);//添加到集合
        fragments.add(frag02);
        fragments.add(frag03);
    }

    private void initEvent() {
        tab01.setOnClickListener(this);
        tab02.setOnClickListener(this);
        tab03.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {//点击底部按钮对ViewPager进行切换
        int currentIndex = 0;
        switch (view.getId()) {//只需要选择被选中页,底部按钮会自动在onPageSelected中更新
            case R.id.ll_first:
                currentIndex = 0;
                break;
            case R.id.ll_second:
                currentIndex = 1;
                break;
            case R.id.ll_third:
                currentIndex = 2;
        }
        viewPager.setCurrentItem(currentIndex);//点击后切换当前选中page,或者说是fragment
    }

/*
    这一段是按照翔神写的,以上做了相应的重构
    public void setSelect(int i)
    {
        switch (i) {//在响应该页被选中时,需要同时修改底部对应的按钮状态
            case 0:
                ((ImageButton) findViewById(R.id.btn_first)).setImageResource(R.mipmap.one_clicked);
                break;
            case 1:
                ((ImageButton) findViewById(R.id.btn_second)).setImageResource(R.mipmap.two_clicked);
                break;
            case 2:
                ((ImageButton) findViewById(R.id.btn_third)).setImageResource(R.mipmap.one_clicked);
        }
        viewPager.setCurrentItem(i);//设置当前第i页为选中状态
    }*/
}


大致思路:

step1、

用过ListView和GridView的同学们对本片博客实现的方式都有种似曾相识的感觉吧~~~ 哇哈哈,没错!!!骚年你猜对了,对于ViewPager而言它和ListView以及GridView用的是同一个套路。只不过这里的FragmentPageAdapter适配器的用法和BaseAdapter是一致的!!!

step2、

然后我们需做的就是对ViewPager对象用onPageChangeListener进行监听。(我靠,不是说和ListView用法一致么,怎么还??)哈哈,仔细想想,我们当年滑动ListView的时候,仅仅是滑动而已~~~如果你只是想滑动ViewPager,你也可以不要这个~~~当然啦,在这里作为Tab界面的组件,我们还是需要做出一个联动效果的(也就是类似于微信的底部栏按钮一一对应的效果)。所以这一步必不可少!!!可以联想到的是,我们的ListView在滑动的时候也可以通过类似的方法达到所谓的联动效果~~~在监听的方法onPageSelected里我们即可对对应的按钮进行界面更新!(ps:每次进入该方法之前一定要记得先调用重置所有按钮,要不然等你划完所有page之后,底栏目全都变高亮啦~~~)

step3、

仔细想想还有什么没做???妈蛋,微信里的那个效果不是还有点击按钮切换ViewPager界面的么~~~呦西,so easy,我们只需要给按钮或者按钮所在子布局进行点击事件监听,然后在对应的case里setCurrentItem即可,因为VIewPager在发现当前选定条目被更改之后,会invoke onPageSelected,然后它自然而然会去帮我们处理那个联动关系。。。

布局图如下: (想看效果图参考源码请猛戳项目地址 github地址



Notice:

1、当我们设置默认选项页为0页或者不设置的时候,系统都会默认选中第0页,而此时的onPageSelected是不会被调用的,这样的话我们的高亮从何而来???解决办法:直接在初始化第一个按钮的时候对他进行高亮处理~~~

API论证:this method will be invoked when a new page becomes selected

2、在对按钮进行点击事件监听的时候,我们需要做的只有setCurrentItem(),因为在这以后,onPageSelected会自动被调用~~~希望翔哥能够看到!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: