1.先看效果图:
2.上代码:
public abstract class BaseOverlayPageAdapter extends PagerAdapter {
private Context context;
private Integer[] imgUrls;
private WeakReference<Bitmap>[] bitmaps;
protected RequestOptions mRequestOptions;
public BaseOverlayPageAdapter(Context context, @NonNull RequestOptions imageOptions) {
this.context = context;
this.mRequestOptions = imageOptions;
}
/**
* item布局
*
* @return
*/
protected abstract View itemView();
public void setImgUrlsAndBindViewPager(ViewPager vp, Integer[] imgUrls) {
setImgUrlsAndBindViewPager(vp, imgUrls, 3);
}
public void setImgUrlsAndBindViewPager(ViewPager vp, Integer[] imgUrls, int layerAmount) {
setImgUrlsAndBindViewPager(vp, imgUrls, layerAmount, -1, -1);
}
/**
* @param vp
* @param imgUrls
* @param layerAmount 显示层数
*/
public void setImgUrlsAndBindViewPager(ViewPager vp, Integer[] imgUrls, int layerAmount, float scaleOffset, float transOffset) {
this.imgUrls = imgUrls;
if (imgUrls != null && imgUrls.length > 0) {
bitmaps = new WeakReference[imgUrls.length];
vp.setOffscreenPageLimit(layerAmount);
OverlayTransformer transformer = new OverlayTransformer(layerAmount, scaleOffset, transOffset);
vp.setPageTransformer(true, transformer);
}
}
@Override
public int getCount() {
if (null == imgUrls)
return 0;
if (imgUrls.length <= 1)
return imgUrls.length;
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view == o;
}
protected ImageView findImageView(View rootView) {
ImageView iv = rootView.findViewById(R.id.card_iv);
if (null != iv)
return iv;
if (rootView instanceof ImageView) {
return (ImageView) itemView();
}
throw new RuntimeException("you should set one of ImageViews id=card_iv or rootView=ImageView");
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
final int p = position % imgUrls.length;
final int imgUrl = imgUrls[p];
View view = itemView();
if (null == view) {
throw new RuntimeException("you should set a item layout");
}
final ImageView iv = view.findViewById(R.id.card_iv);
ConstraintLayout cl = view.findViewById(R.id.cl_bg);
cl.setBackground(null);
if (null == iv) {
throw new RuntimeException("you should set a item layout");
}
if (null != bitmaps && null != bitmaps[p] && null != bitmaps[p].get()) {
iv.setImageBitmap(bitmaps[p].get());
}
Glide.with(context).asBitmap().load(imgUrl).apply(mRequestOptions).into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
bitmaps[p] = new WeakReference<Bitmap>(resource);
iv.setImageBitmap(resource);
}
@Override
public void onLoadStarted(@Nullable Drawable placeholder) {
super.onLoadStarted(placeholder);
iv.setImageDrawable(placeholder);
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
iv.setImageDrawable(errorDrawable);
}
});
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
/**
* 叠加卡片效果
* Created by Acorn on 2017/12/29.
*/
public class OverlayTransformer implements ViewPager.PageTransformer {
private float scaleOffset = 100;
private float transOffset = 75;
private int overlayCount;
public OverlayTransformer(int overlayCount) {
this.overlayCount = overlayCount;
}
public OverlayTransformer(int overlayCount, float scaleOffset, float transOffset) {
this.overlayCount = overlayCount;
if (Float.compare(scaleOffset, -1) != 0)
this.scaleOffset = scaleOffset;
if (Float.compare(transOffset, -1) != 0)
this.transOffset = transOffset;
}
public int getOverlayCount() {
return overlayCount;
}
@Override
public void transformPage(View page, float position) {
if (position <= 0.0f) {//当前页
page.setTranslationX(0f);
page.setAlpha(1 - 0.5f * Math.abs(position));
page.setClickable(true);
} else {
otherTrans(page, position);
page.setClickable(false);
}
}
private void otherTrans(View page, float position) {
//缩放比例
float scale = (page.getWidth() - scaleOffset * position) / (float) (page.getWidth());
page.setScaleX(scale);
page.setScaleY(scale);
page.setAlpha(1f);
if (position > overlayCount - 1 && position < overlayCount) { //当前页向右滑动时,最右面第四个及以后页面应消失
float curPositionOffset = transOffset * (float) Math.floor(position); //向下取整
float lastPositionOffset = transOffset * (float) Math.floor(position - 1); //上一个卡片的偏移量
float singleOffset = 1 - Math.abs(position % (int) position);
float transX = (-page.getWidth() * position) + (lastPositionOffset + singleOffset * (curPositionOffset - lastPositionOffset));
page.setTranslationX(transX);
} else if (position <= overlayCount - 1) {
float transX = (-page.getWidth() * position) + (transOffset * position);
page.setTranslationX(transX);
} else {
page.setAlpha(0f);
// page.setTranslationX(0); //不必要的隐藏在下面
}
}
public class SimpleOverlayAdapter extends BaseOverlayPageAdapter {
private LayoutInflater mInflater;
public SimpleOverlayAdapter(Context context) {
super(context, new RequestOptions().error(R.drawable.error).placeholder(R.drawable.placeholder));
mInflater = LayoutInflater.from(context);
}
public SimpleOverlayAdapter(Context context, RequestOptions imageOptions) {
super(context, imageOptions);
mInflater = LayoutInflater.from(context);
}
@Override
protected View itemView() {
return mInflater.inflate(R.layout.item_viewpager, null);
}
}
class MainActivity : AppCompatActivity() {
private var vp: ViewPager? = null
private val imgUrls = arrayOf(
R.drawable.a,
R.drawable.b,
R.drawable.c,
R.drawable.d,
R.drawable.e,
R.drawable.g
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vp = findViewById(R.id.example_vp)
val adapter = SimpleOverlayAdapter(this)
adapter.setImgUrlsAndBindViewPager(vp, imgUrls, 3)
vp?.setAdapter(adapter)
vp?.setCurrentItem(100000) //伪无限循环
}
}
3.以下是布局文件:
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
tools:context=".MainActivity">
<view
android:id="@+id/example_vp"
class="androidx.viewpager.widget.ViewPager"
android:layout_width="match_parent"
android:layout_height="448dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</LinearLayout>
item_viewpager
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:id="@+id/cl_bg"
android:layout_height="448dp"
android:layout_marginTop="5dp"
android:background="@mipmap/abc">
<ImageView
android:id="@+id/card_iv"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="87dp"
android:layout_marginTop="76dp"
android:layout_marginEnd="87dp"
android:scaleType="centerCrop"
android:layout_marginBottom="105dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
网友评论