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 ...
随机推荐
- Using Elixir Dynamic Supervisors
转自: https://blog.smartlogic.io/elixir-dynamic-supervisors/ I have been working on my side project Gr ...
- go-elasticsearch 来自官方的 golang es client
elasticsearch 终于有了官方的golang sdk 了,地址 https://github.com/elastic/go-elasticsearch 当前还不稳定,同时主要是对于es7 的 ...
- Singer 开源便捷的ETL 工具
singer 是一个强大,灵活的etl 工具,我们可以方便的提取web api,file,queue,基本上各种你可以想到的 数据源. singer 有一套自己的数据处理规范, taps, targe ...
- ViewBag & ViewData
ViewBag 和ViewData 是ASP.NET MVC 开发当中大家使用很多的传递数据的方法 VB可以称为VD的一块语法糖, VB是使用C# 4.0动态特征, 使得VD也具有动态特性. 下面就是 ...
- C#中Socket关闭 Close、Dispose、Shutdown、Disconnect
An answer on StackOverflow made me think I have finally reached some glimpse of an understanding. Th ...
- mysql之 openark-kit online ddl
MySQL工具集openark-kit (官方网站 http://code.openark.org/forge/openark-kit),内部包含很多小工具,在5.6之前用于实现online ddl操 ...
- secureCRT 设置证书免密登陆
1 第一步 2 第二步 3 第三步 4 第4 步 ,然后选择你的 私钥文件
- laravel 打印完整sql语句
laravel5 用DB自带的getQueryLog方法直接打印: DB::connection()->enableQueryLog(); // 开启QueryLog \App\User::fi ...
- sql update操作结果
Mysql 在MySQL中只有真正对记录进行修改了的情况下,row_count才会去记录影响的行数,否则如果记录存在但是没有实际修改则不会将该次更新记录到row_count中. update操作执行结 ...
- python调用hanlp分词包手记
python调用hanlp分词包手记 Hanlp作为一款重要的分词工具,本月初的时候看到大快搜索发布了hanlp的1.7版本,新增了文本聚类.流水线分词等功能.关于hanlp1.7版本的新功能,后 ...
