Android Tab -- 使用ViewPager、Fragment、FragmentPagerAdapter来实现

原文地址http://blog.csdn.net/crazy1235/article/details/42678877

效果:滑动切换;点击标签切换。

代码:https://github.com/ldb-github/Layout_Tab

1、布局:使用LinearLayout布置标签;再使用ViewPager来布置Fragment;使用ImageView作为指示器。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:orientation="horizontal"
        android:weightSum="3">

        <TextView
            android:id="@+id/tab1_tv"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="选项卡一"
            android:textColor="#707070"/>

        <TextView
            android:id="@+id/tab2_tv"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="选项卡二"
            android:textColor="#707070"/>

        <TextView
            android:id="@+id/tab3_tv"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="选项卡三"
            android:textColor="#707070"/>
    </LinearLayout>

    <ImageView
        android:id="@+id/cursor"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="0dp"
        android:src="@drawable/down_line"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/third_vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
viewpager_fragmentpageradapter.xml

1、实现View.OnClickLinstener接口,在onClick方法中完成点击标签进行切换的功能:调用ViewPager的setCurrentItem()方法。

2、实现ViewPager.OnPageChangeListener方法,在onPageScrolled方法中,改变指示器的位置。

3、在原文的基础上:

a、去掉screen1_3(屏幕宽度的三分之一);增加tabCount(tab的数量)和widthOfOneTab(一个tab的宽度 screenWidth / tabCount)。

b、调整onPageScrolled方法,使其更具通用性。

public class ViewPagerAndFragmentPagerAdapterActivity extends FragmentActivity
        implements View.OnClickListener, ViewPager.OnPageChangeListener{

    private static final String LOG_TAG =
            ViewPagerAndFragmentPagerAdapterActivity.class.getSimpleName();

    // 三个textview
    private TextView tab1Tv, tab2Tv, tab3Tv;
    // 指示器
    private ImageView cursorImg;
    // viewPager
    private ViewPager viewPager;
    // fragment对象集合
    private ArrayList<Fragment> fragmentsList;
    // 记录当前选中的tab的index
    private int currentIndex = 0;
    // 指示器的偏移量
    private int offset = 0;
    // 左margin
    private int leftMargin = 0;
    // 屏幕宽度
    private int screenWidth = 0;
    // 屏幕宽度的三分之一
    //private int screen1_3;
    // Tab的数量
    private int tabCount;
    // 一个Tab的宽度 screenWidth / tabCount
    private int widthOfOneTab;
    //
    private LinearLayout.LayoutParams lp;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewpager_fragmentpageradapter);

        init();
    }

    /**
     * 初始化操作
     */
    private void init(){
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        screenWidth = dm.widthPixels;

        cursorImg = (ImageView) findViewById(R.id.cursor);
        lp = (LinearLayout.LayoutParams) cursorImg.getLayoutParams();
        leftMargin = lp.leftMargin;

        tab1Tv = (TextView) findViewById(R.id.tab1_tv);
        tab2Tv = (TextView) findViewById(R.id.tab2_tv);
        tab3Tv = (TextView) findViewById(R.id.tab3_tv);

        tabCount = 3;
        widthOfOneTab = screenWidth / tabCount;

        tab1Tv.setOnClickListener(this);
        tab2Tv.setOnClickListener(this);
        tab3Tv.setOnClickListener(this);

        initViewPager();
    }

    private void initViewPager(){
        viewPager = (ViewPager) findViewById(R.id.third_vp);
        fragmentsList = new ArrayList<>();
        Fragment fragment = new FragmentAndFManager_Fragment1();
        fragmentsList.add(fragment);
        fragment = new FragmentAndFManager_Fragment2();
        fragmentsList.add(fragment);
        fragment = new FragmentAndFManager_Fragment3();
        fragmentsList.add(fragment);

        viewPager.setAdapter(new FragmentAdapter(getSupportFragmentManager(), fragmentsList));
        viewPager.setCurrentItem(0);
        viewPager.setOnPageChangeListener(this);
    }

    @Override
    public void onClick(View v) {
        Log.d(LOG_TAG, "In onClick v.getId() = " + v.getId());
        switch(v.getId()){
            case R.id.tab1_tv:
                viewPager.setCurrentItem(0);
                break;
            case R.id.tab2_tv:
                viewPager.setCurrentItem(1);
                break;
            case R.id.tab3_tv:
                viewPager.setCurrentItem(2);
                break;
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        offset = (widthOfOneTab - cursorImg.getLayoutParams().width) / 2;
        Log.d(LOG_TAG, "In onPageScrolled: " + position + " -- " + positionOffset + " -- " +
                positionOffsetPixels);
        //final float scale = getResources().getDisplayMetrics().density;
//        if(position == 0){
//            lp.leftMargin = (int) (positionOffsetPixels / 3) + offset;
//        }else if(position == 1){
//            lp.leftMargin = (int) (positionOffsetPixels / 3) + widthOfOneTab + offset;
//        }

        if(position < tabCount - 1){
            lp.leftMargin = (int) (positionOffsetPixels / tabCount) + widthOfOneTab * position + offset;
        }

        cursorImg.setLayoutParams(lp);
        currentIndex = position;
    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}
ViewPagerAndFragmentPagerAdapterActivity.java

1、自定义类FragmentAdapter继承FragmentPagerAdapter,实现方法getItem()和getCount()。

2、通过ArrayList<Fragmet>来保存适配器绑定的Fragment集合。

public class FragmentAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> list;
    public FragmentAdapter(FragmentManager fm, ArrayList<Fragment> list) {
        super(fm);
        this.list = list;
    }

    @Override
    public Fragment getItem(int position) {
        return list.get(position);
    }

    @Override
    public int getCount() {
        return list.size();
    }
}
FragmentAdapter.java
原文地址:https://www.cnblogs.com/yarightok/p/5640774.html