ViewPager 的用法详解

现在很多浏览类型app都是viewpager + fragment + 自定义tab的组合,比如网易新闻,优酷等。

使用这种组合的好处: 可以在一个Activity中处理多个页面,方便用户操作,视图结构清晰。

一、 viewpager 对应的几个adapter

PagerAdapter: 一般适配器,图片,view,Fragment都行。
FragmentPagerAdapter: 为PageAdapter子类, 适用于数量较少的Fragment为页面。特点,每一个生成的Fragment都将保存到内存中,当不可见时,销毁Fragment的view,调用onDestroyView; 用户体验好
FragmentStatePagerAdapter: 为PageAdapter子类, 适用于处理很多页,数据动态性较大,占用内存较多的Fragment为页面。 特点,当不可见时,整个Fragment都会销毁,调用onDestroy 和 onDestroyView; 数据需重新加载

一般PageAdapter中4个方法:
1. public int getCount():  返回当前有效视图的个数。
2. public boolean isViewFromObject(View view, Object object): 该函数用来判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View)
3. public Object instantiateItem(ViewGroup container, int position): 这个函数的实现的功能是创建指定位置的页面视图。返回值:返回一个代表新增视图页面的Object(Key),这里没必要非要返回视图本身,也可以这个页面的其它容器。
4. public void destroyItem(ViewGroup container, int position, Object object): 该方法实现的功能是移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。
5. public CharSequence getPageTitle(int position): 使用系统PagerTabStrip   PagerTitleStrip 返回的tab字符串

二、ViewPager 滑动页面的监听,一般可用于对自定义tab进行动画处理

   //viewPager.setOnPageChangeListener(myOnPageChangeListener);  被弃用。  下面区别是将listener放入集合中
   viewPager.addOnPageChangeListener(myOnPageChangeListener);


   private MyOnPageChangeListener myOnPageChangeListener = new MyOnPageChangeListener();


    public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {


        @Override    //滑动的过程调用   位置     当前页面屏幕的百分比    当前页面偏移的像素位置   
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            Log.d("stormxz", "onPageScrolled  111");
        }


        @Override    //当前页面的位置
        public void onPageSelected(int position) {
            Log.d("stormxz", "onPageScrolled  222");
        }


        @Override    //状态  1开始  2正在滑动  0结束
        public void onPageScrollStateChanged(int state) {
            Log.d("stormxz", "onPageScrollStateChanged  333");
        }
    }
   
   一般用来对自定义tabbar 进行位置,动画设置

三、3种adapter使用Fragment + viewPager

1. PagerAdapter 

package com.example.stormxz.viewpagerdemo;


import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;


import java.util.ArrayList;


/**
 * Created by stormxz on 2017/9/6.
 */


public class MyViewPagerAdapter extends PagerAdapter {


    private ArrayList<Fragment> fragments = new ArrayList<Fragment>();
    private ArrayList<String> titles = new ArrayList<String>();
    private FragmentManager fragmentManager = null;


    public MyViewPagerAdapter(ArrayList<Fragment> viewArrayList, ArrayList<String> titlesList, FragmentManager fragmentManager) {
        this.fragments = viewArrayList;
        this.titles = titlesList;
        this.fragmentManager = fragmentManager;
    }


    @Override
    public int getCount() {   //返回fragment 的个数
        return fragments.size();
    }


    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;  //判读当前View是否一致
    }


    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = fragments.get(position);
        if (fragment != null) {
            if (!fragment.isAdded()){  //判读当前fragment是否已经提交 ,如果没有,则创建事务,进行提交
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.add(fragment, fragment.getClass().getSimpleName());
                fragmentTransaction.commitAllowingStateLoss();
                /**
                 * 在用FragmentTransaction.commit()方法提交FragmentTransaction对象后 会在进程的主线程中,用异步的方式来执行。
                 * 如果想要立即执行这个等待中的操作,就要调用这个方法(只能在主线程中调用)。 要注意的是,所有的回调和相关的行为都会在这个调用中被执行完成,因此要仔细确认这个方法的调用位置。
                 */
                fragmentManager.executePendingTransactions();
            }


            if (fragment.getView() != null) {
                container.addView(fragment.getView());
            }
        }
        return fragment.getView();
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(fragments.get(position).getView());  //removeView
    }


    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);   //返回tab 文字信息
    }
}

MainActivity.java  传递FragmentManager   tabname   Fragment集合
    myViewPagerAdapter = new MyViewPagerAdapter(fragments, titles, getSupportFragmentManager());
    viewPager.setAdapter(myViewPagerAdapter);

一般不建议使用PagerAdapter. 建议使用其子类FragmentPagerAdapter  以及 FragmentStatePagerAdapter

2.  FragmentPagerAdapter  与   FragmentStatePagerAdapter 

只需要重新2个方法即可
package com.example.stormxz.viewpagerdemo;


import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;


import java.util.ArrayList;


/**
 * Created by stormxz on 2017/9/11.
 */


public class MyFragmentAdapter extends FragmentPagerAdapter {


    private ArrayList<Fragment> fragments = new ArrayList<Fragment>();
    public MyFragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }


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


    @Override
    public int getCount() {
        return fragments.size();
    }
}

MainActivity.java 中传递FragmentManager  以及Fragment的集合;  给ViewPager添加适配器
    myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(), fragments);
    viewPager.setAdapter(myFragmentAdapter);

源码中已经实现
   @Override
    public Object instantiateItem(ViewGroup container, int position) {
        // If we already have this item instantiated, there is nothing
        // to do.  This can happen when we are restoring the entire pager
        // from its saved state, where the fragment manager has already
        // taken care of restoring the fragments we previously had instantiated.
        if (mFragments.size() > position) {
            Fragment f = mFragments.get(position);
            if (f != null) {
                return f;
            }
        }


        if (mCurTransaction == null) {   //获得事务
            mCurTransaction = mFragmentManager.beginTransaction();
        }


        Fragment fragment = getItem(position);
        if (DEBUG) Log.v(TAG, "Adding item #" + position + ": f=" + fragment);
        if (mSavedState.size() > position) {
            Fragment.SavedState fss = mSavedState.get(position);
            if (fss != null) {
                fragment.setInitialSavedState(fss);
            }
        }
        while (mFragments.size() <= position) {
            mFragments.add(null);
        }
        fragment.setMenuVisibility(false);
        fragment.setUserVisibleHint(false);  //设置为不可见
        mFragments.set(position, fragment);
        mCurTransaction.add(container.getId(), fragment);  //添加Fragment


        return fragment;
    }

事务提交
 @Override
    public void finishUpdate(ViewGroup container) {
        if (mCurTransaction != null) {
            mCurTransaction.commitNowAllowingStateLoss();
            mCurTransaction = null;
        }
    }

判断fragment是否是当前的,是则设置为用户可见
@Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment)object;
        if (fragment != mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem.setMenuVisibility(false);
                mCurrentPrimaryItem.setUserVisibleHint(false);
            }
            if (fragment != null) {
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
            }
            mCurrentPrimaryItem = fragment;
        }
    }

四、 系统PagerTabStrip   PagerTitleStrip

1. 使用,将其作为子类View 放入ViewPager中
<android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="368dp"
        android:layout_height="495dp"
        tools:layout_editor_absoluteY="8dp"
        tools:layout_editor_absoluteX="8dp">


        <android.support.v4.view.PagerTabStrip
            android:id="@+id/pager_tab_strip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </android.support.v4.view.PagerTabStrip>


<!--        <android.support.v4.view.PagerTitleStrip
            android:id="@+id/pager_title_strip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">


        </android.support.v4.view.PagerTitleStrip>-->


    </android.support.v4.view.ViewPager>

2. 在Adapter中传入tabname集合,并在不同位置进行提取
    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }

相同点: 
(1)作为ViewPager内部控件进行使用,只需要重写adapter中的getPageTitle(return position的字符串)
(2) android:layout_gravity 属性设置为TOP或BOTTOM来将它显示在ViewPager的顶部或底部。

不同点: PagerTabStrip 支持点击tab进行跳转页面,有下划线; PagerTitleStrip 则无

主流app  不会用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ViewPager是一个Android支持库中的类,它允许用户在不同的页面之间进行滑动。在Android Studio中使用ViewPager的步骤如下: 1. 在build.gradle文件中添加ViewPager的依赖: ``` dependencies { implementation 'com.android.support:viewpager:28.0.0' } ``` 2. 在XML布局文件中添加ViewPager: ``` <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3. 创建一个FragmentPagerAdapterFragmentStatePagerAdapter的子类: ```java public class MyPagerAdapter extends FragmentPagerAdapter { private final List<Fragment> mFragmentList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>(); public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void addFragment(Fragment fragment, String title) { mFragmentList.add(fragment); mFragmentTitleList.add(title); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position); } } ``` 4. 在Activity或Fragment中设置ViewPager的适配器: ```java MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new Fragment1(), "Fragment 1"); adapter.addFragment(new Fragment2(), "Fragment 2"); adapter.addFragment(new Fragment3(), "Fragment 3"); ViewPager viewPager = findViewById(R.id.view_pager); viewPager.setAdapter(adapter); ``` 5. (可选)如果你想要使用TabLayout来帮助用户切换页面,可以使用以下代码: ```java TabLayout tabLayout = findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); ``` 这样就可以在Android应用中使用ViewPager了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值