android实现3D Gallery 轮播效果,触摸时停止轮播

时间:2021-09-04 05:43:38

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实现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&gt ...

  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&plus;Handler&plus;Timer简单实现广告轮播效果

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

随机推荐

  1. &lbrack;Django&rsqb;用户权限学习系列之User权限基本操作指令

    针对Django 后台自带的用户管理系统,虽说感觉还可以,但是为了方便用户一些操作,特别设计自定义的用户权限管理系统. 在制作权限页面前,首先需要了解权限和用户配置权限的指令,上章讲到权限的添加,删除 ...

  2. TDirectory&period;GetLogicalDrives获取本地逻辑驱动器

    使用函数: System.IOUtils.TDirectory.GetLogicalDrives class function GetLogicalDrives: TStringDynArray; s ...

  3. JAVA小项目之五子棋

    五子棋V1.0 功能: 人人对战,人机对战(初级) 记录双方分数: 主要知识点: 二维坐标系中,各方向坐标的关系及规律. 效果图: 主框架类: package com.gxlee.wzq; /** * ...

  4. 从不同层面看cocos2d-x

    一  框架层面 二  Lua层面 三  工具层面 四  android打包 一 框架层     总体来说,cocos2dX提供的一个简便的框架,包括了渲染,动画,事件分发,网络还有UI,物理引擎等几大 ...

  5. CAN总线基础知识(一)

    1.CAN总线是什么? CAN(Controller Area Network)是ISO国际标准化的串行通信协议.广泛应用于汽车.船舶等.具有已经被大家认可的高性能和可靠性. CAN控制器通过组成总线 ...

  6. git&lpar;三&rpar; 使用github

    1.创建仓库 ① 注册github账户,登录后,点击"New respository ". ② 在新页面中,输入项目的名称,勾选'readme.md',点击'create repo ...

  7. 剑指offer八之跳台阶

    一.题目 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 二.思路 a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法 ...

  8. Laravel 入门笔记

    1.MVC简介 MVC全名是Model View Controller,是模型-视图-控制器的缩写 Model是应用程序中用于处理应用程序数据逻辑的部分 View是应用程序中处理数据显示的部分 Con ...

  9. 51NOD 1227:平均最小公倍数——题解

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1227 懒得打公式了,看这位的吧:https://blog.csdn.ne ...

  10. firewall-cmd 防火墙命令详解 及 TCP Wrappers

    firewall-cmd 常用参数及作用 参数 作用 --get-default-zone 查询默认的区域名称 --set-default-zone=<区域名称> 设置默认的区域,使其永久 ...