1、轮播控件涉及到的两个类

CarouselViewPager.java
public class CarouselViewPager extends ViewPager {
@IntDef({RESUME, PAUSE, DESTROY})
@Retention(RetentionPolicy.SOURCE)
public @interface LifeCycle {
} public static final int RESUME = 0;
public static final int PAUSE = 1;
public static final int DESTROY = 2;
/**
* 生命周期状态,保证{@link #mCarouselTimer}在各生命周期选择执行策略
*/
private int mLifeCycle = RESUME;
/**
* 是否正在触摸状态,用以防止触摸滑动和自动轮播冲突
*/
private boolean mIsTouching = false; /**
* 超时时间
*/
private int timeOut = 2; /**
* 轮播定时器
*/
private ScheduledExecutorService mCarouselTimer; /**
* 有数据时,才开始进行轮播
*/
private boolean hasData; public CarouselViewPager(Context context) {
super(context);
} public CarouselViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
} public void setLifeCycle(@LifeCycle int lifeCycle) {
this.mLifeCycle = lifeCycle;
} @Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
mIsTouching = true;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mIsTouching = false;
break;
}
return super.onTouchEvent(ev);
} @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
startTimer();
} public void startTimer() {
if (!hasData) {
return;
}
shutdownTimer();
mCarouselTimer = Executors.newSingleThreadScheduledExecutor();
mCarouselTimer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
switch (mLifeCycle) {
case RESUME:
if (!mIsTouching
&& getAdapter() != null
&& getAdapter().getCount() > 1) {
post(new Runnable() {
@Override
public void run() {
setCurrentItem(getCurrentItem() + 1);
}
});
}
break;
case PAUSE:
break;
case DESTROY:
shutdownTimer();
break;
}
}
}, 0, 1000 * timeOut, TimeUnit.MILLISECONDS);
} public void setHasData(boolean hasData) {
this.hasData = hasData;
} public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
} @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
shutdownTimer();
} private void shutdownTimer() {
if (mCarouselTimer != null && mCarouselTimer.isShutdown() == false) {
mCarouselTimer.shutdown();
}
mCarouselTimer = null;
}
}
CarouselPagerAdapter.java
/**
* @描述 @link CarouselViewPager 轮播控件}所需的adapter
*/ public abstract class CarouselPagerAdapter<V extends CarouselViewPager> extends PagerAdapter {
/**
* 系数,可以自行设置,但又以下原则需要遵循:
* <ul>
* <li>必须大于1</li>
* <li>尽量小</li>
* </ul>
*/
private static final int COEFFICIENT = 10;
private V mViewPager; public CarouselPagerAdapter(V viewPager) {
this.mViewPager = viewPager;
} /**
* @return 实际数据数量
*/
@IntRange(from = 0)
public abstract int getRealDataCount(); @Override
public final int getCount() {
long realDataCount = getRealDataCount();
if (realDataCount > 1) {
realDataCount = getRealDataCount() * COEFFICIENT;
realDataCount = realDataCount > Integer.MAX_VALUE ? Integer.MAX_VALUE : realDataCount;
}
return (int) realDataCount;
} @Override
public final boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public final Object instantiateItem(ViewGroup container, int position) {
position = position % getRealDataCount();
return this.instantiateRealItem(container, position);
} public abstract Object instantiateRealItem(ViewGroup container, int position); @Override
public final void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
} @Override
public final void finishUpdate(ViewGroup container) {
// 数量为1,不做position替换
if (getCount() <= 1) {
return;
} int position = mViewPager.getCurrentItem();
// ViewPager的更新即将完成,替换position,以达到无限循环的效果
if (position == 0) {
position = getRealDataCount();
mViewPager.setCurrentItem(position, false);
} else if (position == getCount() - 1) {
position = getRealDataCount() - 1;
mViewPager.setCurrentItem(position, false);
}
}
}

2、实现3D效果需要用到的类

public class GalleryTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
float scale = 0.5f;
float scaleValue = 1 - Math.abs(position) * scale;
view.setScaleX(scaleValue);
view.setScaleY(scaleValue);
view.setAlpha(scaleValue);
view.setPivotX(view.getWidth() * (1 - position - (position > 0 ? 1 : -1) * 0.75f) * scale);
view.setElevation(position > -0.25 && position < 0.25 ? 1 : 0);
}
}

3、使用方法

public class MainActivity extends AppCompatActivity {
private CarouselViewPager viewPager; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (CarouselViewPager) findViewById(R.id.id_viewpager); ImagePagerAdapter adapter = new ImagePagerAdapter(this, viewPager);
viewPager.setOffscreenPageLimit(3);
viewPager.setAdapter(adapter);
// 设置轮播时间
viewPager.setTimeOut(5);
// 设置3d效果
viewPager.setPageTransformer(true, new GalleryTransformer());
// 设置已经有数据了,可以进行轮播,一般轮播的图片等数据是来源于网络,网络数据来了后才设置此值,此处因为是demo,所以直接赋值了
viewPager.setHasData(true);
// 开启轮播
viewPager.startTimer();
}
}
public class ImagePagerAdapter extends CarouselPagerAdapter<CarouselViewPager> {

    public ImagePagerAdapter(Context context, CarouselViewPager viewPager) {
super(viewPager);
} int[] imgRes = {
R.drawable.img_wallhaven_426244,
R.drawable.img_wallhaven_431231,
R.drawable.img_wallhaven_432740,
/* R.drawable.img_wallhaven_426244,
R.drawable.img_wallhaven_431231,
R.drawable.img_wallhaven_432740,
R.drawable.img_wallhaven_426244,
R.drawable.img_wallhaven_431231,
R.drawable.img_wallhaven_432740,*/
}; @Override
public Object instantiateRealItem(ViewGroup container, int position) {
ImageView view = new ImageView(container.getContext());
view.setScaleType(ImageView.ScaleType.FIT_XY);
view.setAdjustViewBounds(true);
view.setImageResource(imgRes[position]);
view.setLayoutParams(new LinearLayout.LayoutParams(900, 400));
container.addView(view);
return view;
} @Override
public int getRealDataCount() {
return imgRes != null ? imgRes.length : 0;
}
}

ps:

ImagePagerAdapter.java是一个普通的PagerAdapter类,用户自定义,需要继承CarouselPagerAdapter<CarouselViewPager>并重写CarouselPagerAdapter的构造方法,在
public Object instantiateRealItem(ViewGroup container, int position) 方法中定义界面的具体显示
 public int getRealDataCount() {
return imgRes != null ? imgRes.length : 0;
}方法中返回具体的页面总数

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:gravity="center"
tools:context=".MainActivity"> <com.twiceyuan.galleryviewpager.CarouselViewPager
android:id="@+id/id_viewpager"
android:layout_width="240dp"
android:layout_height="120dp"
android:clipChildren="false"/> </RelativeLayout>
 
 

android实现3D Gallery 轮播效果,触摸时停止轮播的更多相关文章

  1. Android实现图片轮显效果——自定义ViewPager控件

    一.问题概述 使用ViewPager控件实现可横向翻页.水平切换图片等效果,但ViewPager需要手动滑动才能切换页面,图片轮显效果的效果本质上就是在ViewPager控件的基础上让它能自动的进行切 ...

  2. 用JQ去实现一个轮播效果

    前提:用JQ去实现轮播效果一步步的做一个梳理. 首先肯定是轮播的HTML和CSS样式了: <body> <div class="pic"> <div ...

  3. jquery特效(5)—轮播图③(鼠标悬浮停止轮播)

    今天很无聊,就接着写轮播图了,需要说明一下,这次的轮播图是在上次随笔中jquery特效(3)—轮播图①(手动点击轮播)和jquery特效(4)—轮播图②(定时自动轮播)的基础上写出来的,也就是本次随笔 ...

  4. jquery特效(4)—轮播图②(定时自动轮播)

    周末出去逛完街,就回公司好好地研究代码了,也算是把定时自动轮播程序写出来了,特意说明一下,这次的轮播图是在昨天随笔中jquery特效(3)—轮播图①(手动点击轮播)的基础上写出来的,也就是本次随笔展示 ...

  5. JQ 实现轮播图(3D旋转图片轮播效果)

    轮播图效果如下: 代码: <!DOCTYPE html> <html xmlns="/www.w3.org/1999/xhtml"> <head> ...

  6. Taro -- Swiper的图片由小变大3d轮播效果

    Swiper的图片由小变大3d轮播效果 this.state = ({ nowIdx:, swiperH:'', imgList:[ {img:'../../assets/12.jpg'}, {img ...

  7. Android使用ViewPager实现左右循环滑动及轮播效果

    边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...

  8. ViewFlipper的简单使用实现图片轮播效果

    /** * ViewFlipper: * 安卓系统自带的一个多页面管理控件,它可以实现子页面的自动切换 * 为ViewFlipper加入View: * (1)在layout布局文件静态导入子View ...

  9. viewPager+Handler+Timer简单实现广告轮播效果

    基本思想是在Avtivity中放一个ViewPager,然后通过监听去实现联动效果,代码理由详细的解释,我就不说了. MainActivity.java package com.example.adm ...

随机推荐

  1. itcast-spring-三大框架整合

    三大框架架构(整合原理) struts整合到spring   hibernate整合到spring 导包 eclipse需要导入   myeclipse不用 单独配置spring容器 单独配置stru ...

  2. MySQL--Semi-join(半连接)优化策略

    Semi-join(半连接)半连接主要场景:检查一个结果集(外表)的记录是否在另外一个结果集(字表)中存在匹配记录,半连接仅关注”子表是否存在匹配记录”,而并不考虑”子表存在多少条匹配记录”,半连接的 ...

  3. Abstract Data Types in C

    Interface declares operations, not data structure Implementation is hidden from client (encapsulatio ...

  4. 改变codeblocks里面各种注释的颜色。

    ->Setting->Editor->Syntax highlighting->“Comment(normal)” /* 改变块注释颜色 */"Comment lin ...

  5. SecureCRT突然卡死的问题

    SecureCRT作为著名的SSHclient,经经常使用于登陆远程server. 在上面编辑文本,特别是用vi打开两个文本,而且须要切换时.非常easy出现卡死的现象,不能接受不论什么的键盘输入. ...

  6. LoadRunner内部介绍以及常见问题

    Tools Recording Options 接下来我们挨个看一下里面的东东以及区别 General(通常的) Script,不用修改,是脚本的语言,我们一般都是基于 C 语言的 Protocols ...

  7. javascript, jquery, nodejs学习2

    debug tools http://stackoverflow.com/questions/1911015/how-to-debug-node-js-applications node inspec ...

  8. mysql 的 docker 镜像使用

    mysql 的 docker 镜像使用: 下载镜像: docker pull mysql:8.0.14 运行容器: docker run -it -e MYSQL_ROOT_PASSWORD=mypw ...

  9. php调用Redis队列使用例子

    1.Controller顶部引入use think\Queue; 2.Controller调用Redis任务 // 1.当前任务将由哪个类来负责处理. $job = 'app\api\job\Resu ...

  10. VC++6 调用teststand api的方法

    参考example中的vs2010的例子,创建MFC工程 打开project->setting ,c/c++ tab  cat 选 Proprocessor ->Additional in ...