Android开发Android技术知识Android开发经验谈

小翅膀一样的viewpager

2018-06-06  本文已影响72人  fushuang

先来个效果


这里写图片描述

分析

  1. 需求:靠近中间的item始终压在两边。滑动后中间的始终在最下面。
  2. 效果的实现大致有两种,第一种:自定义RecyclerView LayoutManager 通过onLayoutChildren() 自己摆放控件,绘制需从屏幕两边的控件往中间绘制,这样才能保证覆盖层级没有问题,同时需要重写父类scrollHorizontallyBy() ,在其中调用offsetChildrenHorizontal()使得recyclerview拥有滑动效果
  3. 第二种:通过对Viewpager设置android:clipChildren="false" 方法,让父布局不去限制viewPager 绘制,即在屏幕外面的也会被画出来,本文主要介绍第二种,简便易行的方案

实现

  1. 对ViewPager 设置android:clipChildren="false" 使viewpager 画出隐藏区域(此时如果是mathparent 画在屏幕外面),将viewpager区域缩小到一个item ,可以看到多个item。
  2. 外面包裹一个viewgroup 将事件传递给viewpager
 ll_container.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return cardViewPager.onTouchEvent(event);
            }
        });

3.处理层叠关系,viewpager

public class CustomViewPager extends ViewPager {
    private ArrayList<Integer> childCenterXAbs = new ArrayList<>();
    private SparseArray<Integer> childIndex = new SparseArray<>();

    public CustomViewPager(Context context) {
        super(context);
        init();
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
        setClipToPadding(false);
        setOverScrollMode(OVER_SCROLL_NEVER);
    }


    /*
     * @return 第n个位置的child 的绘制索引
     */
    @Override
    protected int getChildDrawingOrder(int childCount, int n) {
        if (n == 0 || childIndex.size() != childCount) {
            childCenterXAbs.clear();
            childIndex.clear();
            int viewCenterX = getViewCenterX(this);
            for (int i = 0; i < childCount; ++i) {
                int indexAbs = Math.abs(viewCenterX - getViewCenterX(getChildAt(i)));
                //两个距离相同,后来的那个做自增,从而保持abs不同
                if (childIndex.get(indexAbs) != null) {
                    ++indexAbs;
                }
                childCenterXAbs.add(indexAbs);
                childIndex.append(indexAbs, i);
            }
            Collections.sort(childCenterXAbs);
        }
        return childIndex.get(childCenterXAbs.get(childCount - 1 - n));
    }

    private int getViewCenterX(View view) {
        int[] array = new int[2];
        view.getLocationOnScreen(array);
        return array[0] + view.getWidth() / 2;
    }
}

4.自定义实现缩放唯一动画

public class ScaleInTransformer extends BasePageTransformer
{
    private static final float DEFAULT_MIN_SCALE = 0.85f;
    private float mMinScale = DEFAULT_MIN_SCALE;

    public ScaleInTransformer()
    {

    }

    public ScaleInTransformer(float minScale)
    {
        this(minScale, NonPageTransformer.INSTANCE);
    }

    public ScaleInTransformer(ViewPager.PageTransformer pageTransformer)
    {
        this(DEFAULT_MIN_SCALE, pageTransformer);
    }


    public ScaleInTransformer(float minScale, ViewPager.PageTransformer pageTransformer)
    {
        mMinScale = minScale;
        mPageTransformer = pageTransformer;
    }


    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void pageTransform(View view, float position)
    {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();

        view.setPivotY(pageHeight / 2);
        view.setPivotX(pageWidth / 2);
        float abs = Math.abs(position);

        view.setScaleX((float) (1.5-(0.15*abs)));
        view.setScaleY((float) (1.5-(0.15*abs)));
        view.setBackgroundResource(R.drawable.pic);
        view.setTranslationY(-50*abs);
    }
}

上一篇下一篇

猜你喜欢

热点阅读