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

b5133901ee68286220b9bf1e33720531.png

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

0b956e16486d5870f0f4b5f15bf48327.png

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代码:

实现效果

77c73741520cfad3c8b9dbb90968eca0.png

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);

}

}

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

更多推荐