一页显示三个,当中的呈放大状态,另外两页显示一部分并有灰色蒙层.效果如下:
这个实现起来还是比较容易的,不需要用到第三方的,使用viewpager完全可以实现.
布局文件如下,其中宽高可以自己定义:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="287dp"
android:layout_marginTop="12dp"
android:clipChildren="false"
android:gravity="center"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="165dp"
android:layout_height="match_parent"/>
</LinearLayout>
Activity代码如下,ZoomOutPageTransformer.java就是控制viewpager展示大小的蒙层,搜一下网上很多,等会我会把代码贴在下方:
viewPager.setOffscreenPageLimit(5);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
adapter = new PageAdapter(this, jsonElements);
viewPager.setAdapter(adapter);
PageAdapter.java文件如下,数据源自己解决,这里图片加载使用的是glide.
public class PageAdapter extends PagerAdapter {
private JsonArray jsonArray;
private Context context;
public PageAdapter(Context context, JsonArray jsonArray) {
this.context = context;
this.jsonArray = jsonArray;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(context).inflate(R.layout.item_view, null);
ImageView imageView = (ImageView) view.findViewById(R.id.iv_movie);
position %= jsonArray.size();
String img_url = jsonArray.get(position).getAsString();
ImageLoadUtil.loadImage(container.getContext(), img_url, R.mipmap.icon_wx, imageView);
container.addView(view);
return view;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
View view = (View) object;
container.removeView(view);
}
}
现在这个轮播空间就写出来了,但是却不能自动轮播,需要用手滑动,那么我们就自己写一个handler来实现图片的自动轮播,代码中注释写的很清楚,不用一一讲解.
private static class ImageHandler extends Handler {
/**
* 请求更新显示的View。
*/
protected static final int MSG_UPDATE_IMAGE = 1;
/**
* 请求暂停轮播。
*/
protected static final int MSG_KEEP_SILENT = 2;
/**
* 请求恢复轮播。
*/
protected static final int MSG_BREAK_SILENT = 3;
/**
* 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
* 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
* 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
*/
protected static final int MSG_PAGE_CHANGED = 4;
//轮播间隔时间
protected static final long MSG_DELAY = 3000;
//使用弱引用避免Handler泄露.这里的泛型参数可以不是Activity,也可以是Fragment等
private WeakReference<MACDPushActivity> weakReference;
private int currentItem = 0;
protected ImageHandler(WeakReference<MACDPushActivity> wk) {
weakReference = wk;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MACDPushActivity activity = weakReference.get();
if (activity == null) {
//Activity已经回收,无需再处理UI了
return;
}
//检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
if (activity.handler.hasMessages(MSG_UPDATE_IMAGE)) {
activity.handler.removeMessages(MSG_UPDATE_IMAGE);
}
switch (msg.what) {
case MSG_UPDATE_IMAGE:
currentItem++;
activity.viewPager.setCurrentItem(currentItem);
//准备下次播放
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_KEEP_SILENT:
//只要不发送消息就暂停了
break;
case MSG_BREAK_SILENT:
activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_PAGE_CHANGED:
//记录当前的页号,避免播放的时候页面显示不正确。
currentItem = msg.arg1;
break;
default:
break;
}
}
}
然后看一下,在activity中的调用,这里使用弱引用方式,防止内存溢出.
ImageHandler handler = new ImageHandler(new WeakReference<MACDPushActivity>(this));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
//配合Adapter的currentItem字段进行设置。
@Override
public void onPageSelected(int arg0) {
handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, arg0, 0));
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
//覆写该方法实现轮播效果的暂停和恢复
@Override
public void onPageScrollStateChanged(int arg0) {
switch (arg0) {
case ViewPager.SCROLL_STATE_DRAGGING:
handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case ViewPager.SCROLL_STATE_IDLE:
handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
default:
break;
}
}
});
这样一个可以自动3D轮播就写好了.
附:ZoomOutPageTransformer.java
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.9f;
private static final float MIN_ALPHA = 0.5f;
private static float defaultScale = 0.9f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
view.setScaleX(defaultScale);
view.setScaleY(defaultScale);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +
(scaleFactor - MIN_SCALE) /
(1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
view.setScaleX(defaultScale);
view.setScaleY(defaultScale);
}
}}