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 ...
随机推荐
- 一不小心把win10的秘钥卸载了解决方法
我遇到的第一个问题是Win10家庭版激活失败提示错误代码0xC004C003 然后我百度后看到一个解决方法是卸载秘钥然后再输入秘钥的,于是我执行了slmgr.vbs /upk,发现win10秘钥被卸载 ...
- JQuery左右切换实现
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- prime 又一个开源的基于graphql 的cms
prime 是一个开源的基于graphql 的cms,类似的已经又好多了,strapi 就是一个(graphql 是通过插件扩展的) graphcms 是一款不错的,但是是收费的,prime 是基于t ...
- 数学 它的内容,方法和意义 第二卷 (A. D. 亚历山大洛夫 著)
第五章 常微分方程 1. 绪论 2. 常系数线性微分方程 3. 微分方程的解及应注意的几个方面 4. 微分方程积分问题的几何解释.问题的推广 5. 微分方程解的存在性与唯一性方程的近似解 6. 奇点 ...
- Java Bitset
Bitset创建一种特殊的数组来保存非负整数的值 取值为true和false,初始都是false.Bitset初始化是一个long,65位,增加位数的话只能是64的整数倍. 如果用一个Bitset存储 ...
- css 新单位 fr
fr是css刚出的一个新的单位,目前经过测试在chrome和firefox是可以支持的 举个案列,拿一个网格布局来说吧 <!DOCTYPE html> <html lang=&quo ...
- vue 下实现 echarts 全国到省份的地图下钻
vue 下实现 echarts 全国到省份的地图下钻 项目地址:https://github.com/cag2050/vue_echarts_v3_demo
- Jenkins进阶-应用的远程部署(12)
越来越多的公司部署需要实现自动化模式,大家的首选的工具就是Jenkins,下来介绍下通过Publish Over SSH Plugin插件实现远程部署: 一.安装插件Publish Over SSH ...
- java自动装箱的一个例子
Object obj = 56; int i = (Integer)obj; 第一行等价于: Object obj = Integer.valueOf(56); Integer.valueO ...
- 如何重写hashCode()和equals()方法
hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法. 如何重写equal ...
