Android用ViewPager实现一个中间大两边小并且带指示器的轮播图,也称画廊效果

在项目开发中,遇到了一个新需求,要做一个画廊效果的轮播图,要求指示器跟轮播图分离。效果图如下。以前做轮播图都是直接拿第三方的,现在突然做一个这种小众的效果,发现自己不知道怎么做,尤其是这个指示器,后来在GitHub上搜到了一个很好用 指示器实现方案,特地引用进来,非常感谢LinweiJ,帮我完成了功能实现。老规矩,附上指示器的地址:ViewPagerIndicator

Android用ViewPager实现一个中间大两边小并且带指示器的轮播图,也称画廊效果_第1张图片

1.ViewPagerIndicator的强大我就不过赘述了,自己前去GitHub看使用方法,我只附上效果图

Android用ViewPager实现一个中间大两边小并且带指示器的轮播图,也称画廊效果_第2张图片

2.clipChildren,先了解这个属性,因为在只用过程中至关重要。clipChild用来定义他的子控件是否要在他应有的边界内进行绘制。 默认情况下,clipChild被设置为true,不允许进行扩展绘制。所以我们要实现画廊效果就要设置该属性为false。而且,这个属性一定是要添加在viewpager所在的直接父布局的

接下来就是mViewpager.setPageTransformer(true, new CardTransformer());这句关键代码,setPageTransformer设置轮播图两边的缩放效果,才能实现画廊效果,下面附上CardTransformer的代码,可以根据自己的需求设置不同的属性值

/**
 * Created by zzf on 2017/10/27.
 */

public class CardTransformer implements ViewPager.PageTransformer {
    private static final float MAX_SCALE = 1.2f;
    private static final float MIN_SCALE = 1.0f;//0.85f

    @Override
    public void transformPage(View page, float position) {
        if (position <= 1) {
         //   1.2f + (1-1)*(1.2-1.0)
            float scaleFactor = MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE - MIN_SCALE);

            page.setScaleX(scaleFactor);  //缩放效果

            if (position > 0) {
                page.setTranslationX(-scaleFactor * 2);
            } else if (position < 0) {
                page.setTranslationX(scaleFactor * 2);
            }
            page.setScaleY(scaleFactor);
        } else {

            page.setScaleX(MIN_SCALE);
            page.setScaleY(MIN_SCALE);
        }
    }
}

3.重要的关键的已经说完,前面说了轮播图和指示器分离,是比较少用的情况,所以我自身没做到自己写一个可以实现的指示器,在引用了ViewPagerIndicator以后,只要在xml布局中设置指示器的任意位置,就可以自己决定指示器是在轮播图内,还是分离开来。这里还是非常感谢LinweiJ提供的这么优秀的开源框架。下面附上xml代码:





    

    

    

        

        
    

实现效果

Android用ViewPager实现一个中间大两边小并且带指示器的轮播图,也称画廊效果_第3张图片

4.接下来就是Java代码的实现逻辑,实现起来还是非常简单的,我给轮播图添加了点击事件监听,可以直接使用

Activity代码:

/**
 * Created by zzf on 2018/8/29.
 */

public class BannerActivity extends BaseActivity {

    @BindView(R.id.viewpager)
    ViewPager mViewpager;
    @BindView(R.id.indicator_line)
    ViewPagerIndicator mIndicatorLine;
    @BindView(R.id.viewpager2)
    ViewPager mViewpager2;
    @BindView(R.id.indicator_line2)
    ViewPagerIndicator mIndicatorLine2;

    private BannerAdapter mBannerAdapter;
    private BannerAdapter mBannerAdapter2;

    @Override
    protected BasePresenter createPresenter() {
        return null;
    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_banner;
    }

    @Override
    public void initView() {
        initFirstBanner();
        initSecondBanner();
    }

    private void initSecondBanner() {
        mBannerAdapter2 = new BannerAdapter(this, mViewpager2);
        mViewpager2.setAdapter(mBannerAdapter2);
        mViewpager2.setOffscreenPageLimit(2);//预加载2个
        mViewpager2.setPageMargin(30);//设置viewpage之间的间距
        mViewpager2.setClipChildren(false);
        mViewpager2.setPageTransformer(true, new CardTransformer());
        mIndicatorLine2.setViewPager(mViewpager2, 6);
        mBannerAdapter2.setItemClickListener(new BannerAdapter.ItemClickListener() {

            @Override
            public void onItemClick(int index) {
//                ToastUtils.showToast("点击了图片" + index);
            }
        });
        mViewpager2.setCurrentItem(0);
    }

    private void initFirstBanner() {
        mBannerAdapter = new BannerAdapter(this, mViewpager);
        mViewpager.setAdapter(mBannerAdapter);
        mViewpager.setOffscreenPageLimit(2);//预加载2个
        mViewpager.setPageMargin(30);//设置viewpage之间的间距
        mViewpager.setClipChildren(false);
        mViewpager.setPageTransformer(true, new CardTransformer());
        mIndicatorLine.setViewPager(mViewpager, 6);
        mBannerAdapter.setItemClickListener(new BannerAdapter.ItemClickListener() {

            @Override
            public void onItemClick(int index) {
//                ToastUtils.showToast("点击了图片" + index);
            }
        });
        mViewpager.setCurrentItem(0);
    }
}

adapter代码:

/**
 * Created by zzf on 2018/7/29.
 */

public class BannerAdapter extends PagerAdapter implements View.OnClickListener, ViewPager.OnPageChangeListener {

    private Context mContext;
    private ItemClickListener itemClickListener;
    private int currentPosition = 0;


    public BannerAdapter(Context context, ViewPager viewPager) {
        mContext = context;
        viewPager.clearOnPageChangeListeners();
        viewPager.addOnPageChangeListener(this);
    }

    public void setItemClickListener(ItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }


    @Override
    public int getCount() {
        return 6;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_viewpager, null);
        ImageView imageView = view.findViewById(R.id.iv_icon);
        imageView.setOnClickListener(this);
        container.addView(view);
        return view;
    }

  /*  @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return tabList.get(position);
    }*/

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public void onClick(View v) {
        if (null != itemClickListener) {
            itemClickListener.onItemClick(currentPosition);
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        currentPosition = position;
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    public interface ItemClickListener {
        void onItemClick(int index);
    }
}

由于当时的项目没要求做无限轮播和自动轮播的要求,所以我也就没加这些功能,但是实现起来也是非常简单的,如果有需要可以提出来,我有时间可以再去实现该功能

你可能感兴趣的:(o',h)