zoukankan      html  css  js  c++  java
  • Android ViewPager系列之ViewPager一屏显示多个子页面

    ViewPager一屏显示多个子页面,常见的有两种形式:

    1、当前展示的页面右侧显示一部分下个页面的内容

    这里写图片描述


    2、当前页面居中,左右两边分别显示上一个页面、下一个页面

    这里写图片描述


    第 1 种表现形式的实现代码

    其实这种效果很容易实现,谷歌给我们提供了方法,只需要在adapter中重写这个方法就可以了。  
    /**
     * Returns the proportional width of a given page as a percentage of the
     * ViewPager's measured width from (0.f-1.f]
    返回给定的页面所占ViewPager 测量宽度的比例,范围(0,1]
     *
     * @param position The position of the page requested
     * @return Proportional width for the given page position
     */
    public float getPageWidth(int position) {
        return 1.f;//默认值
    }

    Adapter 代码,重写 getPageWidth(int position) 方法

    public class MultiplePagerAdapter extends PagerAdapter {
        private List<Integer> mList;
        private LayoutInflater layoutInflater;
    
        public MultiplePagerAdapter(Context context, List<Integer> list) {
            super();
            this.mList = list;
            layoutInflater = LayoutInflater.from(context);
        }
    
        @Override
        public int getCount() {
            return mList.size();
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    
        /**
         * 页面宽度所占ViewPager测量宽度的权重比例,默认为1
         */
        @Override
        public float getPageWidth(int position) {
            return (float) 0.8;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = (View) object;
            ((ViewPager) container).removeView(view);
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
    
            // 自己实现
            return null;
        }
    }

    第 2 种表现形式的实现代码

    这种效果也好实现,主要的关键点是 Android:clipChildren=”false” 这个属性。

    1.配置ViewPager 和其父布局的 android:clipChildren属性为”false”. 
    (android:clipChildren表示是否限制子View在其范围内,默认为true. 代码设置setClipChildren(false)) 
    因为如果clipChildren属性设置为true,就表明我们要将children给clip掉,就是说对于子元素来说,超出当前view的部分都会被切掉,那我们在这里把它设置成false,就表明超出view的部分,不要切掉,依然显示。

    注意:setClipChildren(false)在3.0以上版本中,开启了硬件加速后将不能正常工作,所以需要将其设置为软件加速。设置软硬件加速使用 setLayerType(View.LAYER_TYPE_SOFTWARE, null); 也可以在布局文件中添加 android:layerType=”software”

    <RelativeLayout
        android:id="@+id/viewPager_container"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="@android:color/white"
        android:clipChildren="false"
        android:layerType="software">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="110dp"
            android:layout_marginRight="110dp"
            android:clipChildren="false" />
    </RelativeLayout>

    2.设置幕后item的缓存数目。如果一屏展示的pager数目多的话就需要设置此项。

    mViewPager.setOffscreenPageLimit(3);  // 具体缓存页数自己订吧

    3.设置页与页之间的间距

    其实我感觉这里是最麻烦的。UI 上是指定了两个pager间距的,而这个调整起来也颇为麻烦。可以通过setPageMargin 来设置,也可以通过ViewPager.的宽高来展示。这里算起来确实要麻烦很多。

    mViewPager.setPageMargin(int marginPixls);  // setPageMargin表示设置page之间的间距

    4.设置滑动,点击事件

    如果只是简单的实现滑动,可以用设置viewPager父控件的onTouch监听到ViewPager的监听上。

    // 将父类的touch事件分发至viewPgaer,否则只能滑动中间的一个view对象  
    findViewById(R.id.relativeLayout).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return mViewPager.dispatchTouchEvent(event);
        }
    });

    如果要实现点击滑动可以用以下方法(注:代码是我找的demo,效果还不错,是写了个实现类继承自ViewPager。着实当了回代码搬运工…Orz)

    ublic class ClipViewPager extends ViewPager {
    
        public ClipViewPager(Context context) {
            super(context);
        }
    
        public ClipViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
    
            if (ev.getAction() == MotionEvent.ACTION_UP) {
                View view = viewOfClickOnScreen(ev);
                if (view != null) {
                    int index = indexOfChild(view);
                    if (getCurrentItem() != index) {
                        setCurrentItem(indexOfChild(view));
                    }
                }
            }
            return super.dispatchTouchEvent(ev);
        }
    
        /**
         * @param ev
         * @return
         */
        private View viewOfClickOnScreen(MotionEvent ev) {
            int childCount = getChildCount();
            int[] location = new int[2];
            for (int i = 0; i < childCount; i++) {
                View v = getChildAt(i);
                v.getLocationOnScreen(location);
    
                int minX = location[0];
                int minY = getTop();
    
                int maxX = location[0] + v.getWidth();
                int maxY = getBottom();
    
                float x = ev.getX();
                float y = ev.getY();
    
                if ((x > minX && x < maxX) && (y > minY && y < maxY)) {
                    return v;
                }
            }
            return null;
        }
    }
  • 相关阅读:
    数论数论函数基础知识
    KMP入门和简单运用
    高斯消元入门
    FFT和NTT
    AC自动机入门和简单应用
    后缀自动机入门
    线段树优化建图的速成
    爱情九十七课,降低期待
    爱情九十二课,说出你的弱
    爱情八十六课,等得不是爱情
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7441169.html
Copyright © 2011-2022 走看看