android实现3D Gallery 轮播效果,触摸时停止轮播
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 轮播效果,触摸时停止轮播的更多相关文章
- Android实现图片轮显效果——自定义ViewPager控件
一.问题概述 使用ViewPager控件实现可横向翻页.水平切换图片等效果,但ViewPager需要手动滑动才能切换页面,图片轮显效果的效果本质上就是在ViewPager控件的基础上让它能自动的进行切 ...
- 用JQ去实现一个轮播效果
前提:用JQ去实现轮播效果一步步的做一个梳理. 首先肯定是轮播的HTML和CSS样式了: <body> <div class="pic"> <div ...
- jquery特效(5)—轮播图③(鼠标悬浮停止轮播)
今天很无聊,就接着写轮播图了,需要说明一下,这次的轮播图是在上次随笔中jquery特效(3)—轮播图①(手动点击轮播)和jquery特效(4)—轮播图②(定时自动轮播)的基础上写出来的,也就是本次随笔 ...
- jquery特效(4)—轮播图②(定时自动轮播)
周末出去逛完街,就回公司好好地研究代码了,也算是把定时自动轮播程序写出来了,特意说明一下,这次的轮播图是在昨天随笔中jquery特效(3)—轮播图①(手动点击轮播)的基础上写出来的,也就是本次随笔展示 ...
- JQ 实现轮播图(3D旋转图片轮播效果)
轮播图效果如下: 代码: <!DOCTYPE html> <html xmlns="/www.w3.org/1999/xhtml"> <head> ...
- Taro -- Swiper的图片由小变大3d轮播效果
Swiper的图片由小变大3d轮播效果 this.state = ({ nowIdx:, swiperH:'', imgList:[ {img:'../../assets/12.jpg'}, {img ...
- Android使用ViewPager实现左右循环滑动及轮播效果
边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...
- ViewFlipper的简单使用实现图片轮播效果
/** * ViewFlipper: * 安卓系统自带的一个多页面管理控件,它可以实现子页面的自动切换 * 为ViewFlipper加入View: * (1)在layout布局文件静态导入子View ...
- viewPager+Handler+Timer简单实现广告轮播效果
基本思想是在Avtivity中放一个ViewPager,然后通过监听去实现联动效果,代码理由详细的解释,我就不说了. MainActivity.java package com.example.adm ...
随机推荐
- mac sz rz file tras
安装Zmodem的实现 brew install lrzsz 下载 iterm2-send-zmodem.sh 和 iterm2-recv-zmodem.sh 到路径/usr/local/bin/ ...
- oracle重做日志文件硬盘坏掉解决方法
rman target/ list backup; list backup summary; 删除数据库数据文件夹下的log日志,例如/u01/app/oracle/oradata/ORCL下的所有后 ...
- Nio使用Selector客户端与服务器的通信
使用NIO的一个最大优势就是客户端于服务器自己的不再是阻塞式的,也就意味着服务器无需通过为每个客户端的链接而开启一个线程.而是通过一个叫Selector的轮循器来不断的检测那个Channel有消息处理 ...
- mysql-sql语言参考
字段去重查询 select distinct style from music 批量修改某字段 update music set style = "ost" where styl ...
- 我发起了一个 .Net Core 平台上的 分布式缓存 开源项目 ShareMemory 用于 取代 Redis
Redis 的 安装 是 复杂 的, 使用 是 复杂 的, Redis 的 功能 是 重型 的, Redis 本身的 技术实现 是 复杂 的 . Redis 是用 C 写的, C 语言 编写的代码需要 ...
- [转]一个故事讲清楚NIO
假设某银行只有10个职员.该银行的业务流程分为以下4个步骤: 1) 顾客填申请表(5分钟): 2) 职员审核(1分钟): 3) 职员叫保安去金库取钱(3分钟): 4) 职员打印票据,并将钱和票据返回给 ...
- MySQL 遇到错误集锦
MySQL 规定:varchar必须指定长度,否则报错:ERROR 1064 (42000) 只有一列时,primary key 直接写在这一列的后面: 没有定义主键时,提示错误:ERROR 1075 ...
- thinkphp5 查询的数据是对象时,获取原始数据方法
获取原始数据 如果你定义了获取器的情况下,希望获取数据表中的原始数据,可以使用: $user = User::get(1); // 通过获取器获取字段 echo $user->status; / ...
- 安装mysql时包冲突解决方法
报错信息如下: 解决办法: 在卸载代码上加上不检查关联信息即可(rpm -ev mysql-libs-5.1.73-7.el6.x86_64 --nodeps) 检查服务器是否还有mysql安装包:r ...
- [转]使用 Angular CLI 和 ng-packagr 构建一个标准的 Angular 组件库
使用 Angular CLI 构建 Angular 应用程序是最方便的方式之一. 项目目标 现在,我们一起创建一个简单的组件库. 首先,我们需要创建一个 header 组件.这没什么特别的,当然接下来 ...