美文网首页
ViewPager的学习

ViewPager的学习

作者: 我就是杨过 | 来源:发表于2018-05-29 14:51 被阅读0次

    ViewPager继承自viewGroup,用来在一个空间加载多个页面。开发过程中比较常用。

    ViewPager的基础实现部分

    布局文件

    • 在主页面文件中放入 viewpager组件
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.yangguo.uilearn.MainActivity">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </android.support.constraint.ConstraintLayout>
    
    • 创建每个页面的视图 (这里只写了一个textview)(这里只 创建了一个 需要加载多少就创建多少视图)
    <?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">
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我是第一页"
            android:layout_gravity="center"/>
    </LinearLayout>
    

    在Activity中实现

    public class MainActivity extends AppCompatActivity {
    
        private View view1, view2, view3, view4;
        private ViewPager mViewPager;
        private List<View> mPageList;
        private PagerAdapter mAdapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initData();
            initViewPager();
        }
    
        void initData() {
            //引入要展示的页面
            LayoutInflater inflater=getLayoutInflater();
            view1 = inflater.inflate(R.layout.page1, null);
            view2 = inflater.inflate(R.layout.page2,null);
            view3 = inflater.inflate(R.layout.page3, null);
            view4 = inflater.inflate(R.layout.page4, null);
    
            mPageList = new ArrayList<View>();// 将要分页显示的View装入数组中
            mPageList.add(view1);
            mPageList.add(view2);
            mPageList.add(view3);
            mPageList.add(view4);
        }
    
         void initViewPager() {
            //引入ViewPager组件
             mViewPager = (ViewPager) findViewById(R.id.viewPager);
             //进行适配器的设置
             mAdapter = new PagerAdapter() {
                 @Override
                 public int getCount() {
                     return mPageList.size();
                 }
                 // TODO: 2018/5/29  和谁进行比较?    判断是否是同一个视图     判断谁和谁是同一个视图
    
                 @Override
                 public boolean isViewFromObject(View view, Object object) {
                     return view == object;
                 }
    
                 // // PagerAdapter只缓存三张要显示的图片,如果此时滑动到第三页时,第一页就会调用该方法去销毁相应的View。
                 @Override
                 public void destroyItem(ViewGroup container, int position, Object object) {
                    container.removeView(mPageList.get(position));
                 }
    
                 // 该方法是按需调用,默认情况先调用三次,将三个即将使用View页面添加到ViewGroup中,当你滑动到第二页View时,
                 // ViewPager会调用一次该方法将第四个View页面添加到ViewGroup中。
                 // 该方法返回值作为key和对应位置的View关联起来。用于isViewFromObject方法判断当前View和key是否关联的。
                 @Override
                 public Object instantiateItem(ViewGroup container, int position) {
                   container.addView(mPageList.get(position));
                   return mPageList.get(position);
                 }
             };
             mViewPager.setAdapter(mAdapter);
        }
    }
    

    ViewPager下面位置指示点的实现

    ViewPager 实时更新view

    在更新适配器的数据的时候会出现数据虽然删除但是删除的view叠加在后一个view上面 导致这个问题的原因是虽然适配器刷新了 但是其中的View并没有实时删除解决方法是重写下面的方法

     //默认的时候
     public int getItemPosition(Object object) {
            return POSITION_UNCHANGED; // 更新适配器的时候 对应的view不会销毁
            return POSITION_NONE   // 更新适配器的时候 对应位置的view会销毁
        }
    

    ViewPager禁止滑动

     @Override
        public void scrollTo(int x, int y) {
            if (mTotal != 1){          //当总数量1 的时候能进行滑动
                                              // x 和 y 是用户点击滑动的坐标点吗?
                super.scrollTo(x, y);
            }
        }
    

    Viewpager实现自动轮播

    实现代码如下
    //验证 下面的autoswitch以及怎么判断是用户滑动还是 自己滑动 ?
    //看handler 这部分 到现在还是很模糊 ?
    //这个地方很有疑惑

    private Runnable mAutoSwitchRunnable = new Runnable() {
            @Override
            public void run() {
                if (mTotal > 1 && mCurSwitchMode == AUTO_SWITCH) {
                    ++mCurrentPos;
                    int item = (mCurrentPos) % mTotal;
                    CustomViewPager.this.setCurrentItem(item, true);
                }
            }
        };
    
        public void startAutoSwitch() {
            if (mTotal > 1 && mCurSwitchMode == AUTO_SWITCH) {
                mHandler.postDelayed(mAutoSwitchRunnable, DELAY_TIME);
            }
        }
    

    ViewPager切换页面速度控制

    • 在viewpager里面 有一个成员变量mScroller 来控制切换的速度,所以我们需要把viewPager中的这个变量 转换为我们自己的Scroller变量 可以用java反射做到 实现代码如下
      //什么是java反射 怎么使用 ?
      //mScroller 这个变量是从哪里来的 是viewpager自己的吗 还是说什么适配器的 ?
      //这个功能是怎么实现的 在代码里面
    public class ViewPagerScroller extends Scroller {
        private int DEFAULT_DURATION = 900; //ms
    
        public ViewPagerScroller(Context context) {
            this(context, null);
        }
    
        public ViewPagerScroller(Context context, Interpolator interpolator) {
            this(context, interpolator, false);
        }
    
        public ViewPagerScroller(Context context, Interpolator interpolator, boolean flywheel) {
            super(context, interpolator, flywheel);
        }
    
        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            super.startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
        }
    
        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
        }
    
        /**
         * 设置切换一个页面的时长,时间越长,切换速度越慢,反之越慢
         */
        public void setDuration(int duration) {
            DEFAULT_DURATION = duration;
        }
    
        //该方法在ViewPager初始化的时候调用即可
        public void initViewPagerScroller(ViewPager viewPager) {
            try {
                Field mScroller = ViewPager.class.getDeclaredField("mScroller");
                mScroller.setAccessible(true);
                mScroller.set(viewPager, this);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    

    通过调用和设置setDuration() 来设置切换时间的大小

    ViewPager定义页面切换效果

    默认情况下viewpager没有切换效果只有简单的scrollTo平移效果,需要自己定义酷炫的动画效果。可以使用viewpager的setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 这个方法来设置viewpager的切换效果。官方有两个示例

    示例一
    public class DepthPageTransformer implements ViewPager.PageTransformer {  
        private static final float MIN_SCALE = 0.75f;  
    
        public void transformPage(View view, float position) {  
            int pageWidth = view.getWidth();  
    
            if (position < -1) { // [-Infinity,-1)  
                // This page is way off-screen to the left.  
                view.setAlpha(0);  
    
            } else if (position <= 0) { // [-1,0]  
                // Use the default slide transition when moving to the left page  
                view.setAlpha(1);  
                view.setTranslationX(0);  
                view.setScaleX(1);  
                view.setScaleY(1);  
    
            } else if (position <= 1) { // (0,1]  
                // Fade the page out.  
                view.setAlpha(1 - position);  
    
                // Counteract the default slide transition  
                view.setTranslationX(pageWidth * -position);  
    
                // Scale the page down (between MIN_SCALE and 1)  
                float scaleFactor = MIN_SCALE  
                        + (1 - MIN_SCALE) * (1 - Math.abs(position));  
                view.setScaleX(scaleFactor);  
                view.setScaleY(scaleFactor);  
    
            } else { // (1,+Infinity]  
                // This page is way off-screen to the right.  
                view.setAlpha(0);  
            }  
        }  
    }  
    
    mViewPager.setPageTransformer(true, new DepthPageTransformer());
    
    效果展示
    示例二
    public class ZoomOutPageTransformer implements ViewPager.PageTransformer  
    {  
        private static final float MIN_SCALE = 0.85f;  
        private static final float MIN_ALPHA = 0.5f;  
    
        @SuppressLint("NewApi")  
        public void transformPage(View view, float position)  
        {  
            int pageWidth = view.getWidth();  
            int pageHeight = view.getHeight();  
    
            Log.e("TAG", view + " , " + position + "");  
    
            if (position < -1)  
            { // [-Infinity,-1)  
                // This page is way off-screen to the left.  
                view.setAlpha(0);  
    
            } else if (position <= 1) //a页滑动至b页 ; a页从 0.0 -1 ;b页从1 ~ 0.0  
            { // [-1,1]  
                // Modify the default slide transition to shrink the page as well  
                float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));  
                float vertMargin = pageHeight * (1 - scaleFactor) / 2;  
                float horzMargin = pageWidth * (1 - scaleFactor) / 2;  
                if (position < 0)  
                {  
                    view.setTranslationX(horzMargin - vertMargin / 2);  
                } else  
                {  
                    view.setTranslationX(-horzMargin + vertMargin / 2);  
                }  
    
                // Scale the page down (between MIN_SCALE and 1)  
                view.setScaleX(scaleFactor);  
                view.setScaleY(scaleFactor);  
    
                // Fade the page relative to its size.  
                view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE)  
                        / (1 - MIN_SCALE) * (1 - MIN_ALPHA));  
    
            } else  
            { // (1,+Infinity]  
                // This page is way off-screen to the right.  
                view.setAlpha(0);  
            }  
        }  
    }  
    代码调用示例:
    mViewPager.setPageTransformer(true, new ZoomOutPageTransformer());  
    
    效果展示
    接口和参数介绍
    public interface PageTransformer {
            /**
             * Apply a property transformation to the given page.
             *
             * @param page Apply the transformation to this page
             * @param position Position of page relative to the current front-and-center
             *                 position of the pager. 0 is front and center. 1 is one full
             *                 page position to the right, and -1 is one page position to the left.
             */
            void transformPage(View page, float position);
        }
    

    page: 正在执行动画的view
    position: view的位置表示 取值范围如下

    1.(-∞,-1):表示最左边不可见的View page 
    2. [-1,0]:表示从A切换到B页面时,A页面的position变化 
    3. ( 0,1]:表示从A切换到B页面时,B页面的pisition变化 
    4.(1,+∞):表示最右边不可见的View page
    

    相关文章

      网友评论

          本文标题:ViewPager的学习

          本文链接:https://www.haomeiwen.com/subject/tafvjftx.html