经常在群里看到有些开发者在提问:怎么实现3D画廊效果,没思路。

有人出谋划策,你重写onTouch,在里面去判断;或者你去重写滑动监听事件,滑动的时候去动态设置左右两边的图片的大小和缩放效果。可能你们去那样写可以实现,不过时间太长,项目时间紧急的时候,根本来不及写。怎么办呢?没关系,跟着我的思路走一下,你就知道了。

首先, 试着猜想一下,既然是与页面滑动有关,那么ViewPager肯定有setPageXXX之类的方法,那么我们试着找一下:

果然我们看到了有一个很关键的方法:(其他几个一看就很清楚把:设置间距,背景,显示页数的,监听)

setPageTransformer(XXX);
复制代码

我们接着看看源码,看看到底是什么鬼:

有人会说我的英语不好,看不懂这段话,,没关系,万能的谷歌帮了我们(现在谷歌翻译是不需要翻墙的),我们看看重要的翻译:

# 设置pagetransformer,这允许应用程序将自定义属性转换应用到每个页面,重写默认的滑动行为。
复制代码

参数2是:Pagetransformer对象,它是ViewPager里面的一个接口。

翻译一下Pagetransformer接口的注释的意思:
每当可见/附加页面滚动时,就会调用一个PageTransformer。这为应用程序提供了使用动画属性将自定义转换应用于页面视图的机会。transformPage方法的说明:将属性转换应用于给定页面。参数1 page   将转换应用于此页面参数2 position    页面相对于pager的当前中心位置的位置。 0是正面和中心。 1是右侧的一个整页位置,-1是左侧的一页位置。
复制代码

ok,既然找到了关键所在,那么好久开始撸码!开干!

1.写一个类实现ViewPager.PageTransformer,重写transformPage方法

/*** 注意:ViewPager要用V4包里面的,别导错包了* 用ViewPager实现3D画廊效果*/
public class RotationPageTransformer implements ViewPager.PageTransformer {private static final float MIN_SCALE=0.85f;@Overridepublic void transformPage(View page, float position) {float scaleFactor = Math.max(MIN_SCALE,1 - Math.abs(position));float rotate = 10 * Math.abs(position);//position小于等于1的时候,代表page已经位于中心item的最左边,//此时设置为最小的缩放率以及最大的旋转度数if (position <= -1){page.setScaleX(MIN_SCALE);page.setScaleY(MIN_SCALE);page.setRotationY(rotate);} else if (position < 0){//position从0变化到-1,page逐渐向左滑动page.setScaleX(scaleFactor);page.setScaleY(scaleFactor);page.setRotationY(rotate);} else if (position >=0 && position < 1){//position从0变化到1,page逐渐向右滑动page.setScaleX(scaleFactor);page.setScaleY(scaleFactor);page.setRotationY(-rotate);} else if (position >= 1){//position大于等于1的时候,代表page已经位于中心item的最右边page.setScaleX(scaleFactor);page.setScaleY(scaleFactor);page.setRotationY(-rotate);}}
}
复制代码

2.自定义ViewPager的适配器,这个很简单了,就不多讲了,直接上代码:

public class MyPagerAdapter extends PagerAdapter {
private int[] mBitmapIds;
private Context mContext;
private LruCache<Integer,Bitmap> mCache;public MyPagerAdapter(int[] data,Context context){this.mBitmapIds = data;this.mContext = context;//以下两个变量是做缓存处理int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);int cacheSize = maxMemory * 3 / 8;  //缓存区的大小mCache = new LruCache<Integer, Bitmap>(cacheSize){@Overrideprotected int sizeOf(Integer key, Bitmap value) {return value.getRowBytes() * value.getHeight();  //返回Bitmap的大小}};
}@Override
public int getCount() {return mBitmapIds.length;
}@Override
public boolean isViewFromObject(View view, Object object) {return view == object;
}@Override
public Object instantiateItem(ViewGroup container, int position) {View view = LayoutInflater.from(mContext).inflate(R.layout.item_main,container,false);ImageView imageView = (ImageView) view.findViewById(R.id.iv);//imageView.setImageResource(mBitmapIds[position]);//new LoadBitmapTask(imageView).execute(mBitmapIds[position]);loadBitmapIntoTarget(mBitmapIds[position],imageView);container.addView(view);return view;
}@Override
public void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View) object);
}/*** 看有没有缓存,有就开启异步加载,没有就直接加载图片* @param id* @param imageView*/
public void loadBitmapIntoTarget(Integer id, ImageView imageView){//真正开发中是要做三级缓存处理的,这里都是用的本地图片,就没有做处理。//如果你想试试,可以在tomcat里面放几个图片,试试从服务器获取图片,然后去做三级缓存处理//我这里简化操作,只简洁的说一下基本的思路//首先尝试从内存缓存中获取是否有对应id的BitmapBitmap bitmap = mCache.get(id);if (bitmap != null){imageView.setImageBitmap(bitmap);}else {//如果没有则开启异步任务去加载new LoadBitmapTask(imageView).execute(id);}
}//计算图片大小
private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){int height = options.outHeight;int width = options.outWidth;int inSampleSize = 1;if (height >= reqHeight || width > reqWidth){while ((height / (2 * inSampleSize)) >= reqHeight&& (width / (2 * inSampleSize)) >= reqWidth){inSampleSize *= 2;}}return inSampleSize;
}//dp转换成px
public static int dp2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);
}/*** 异步加载图片*/
private class LoadBitmapTask extends AsyncTask<Integer,Void,Bitmap> {private ImageView imageView;public LoadBitmapTask(ImageView imageView){this.imageView = imageView;}@Overrideprotected Bitmap doInBackground(Integer... params) {//这样做没有做缓存处理,加载大量大图容易出现OOM//Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),params[0]);BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;     //1、inJustDecodeBounds置为true,此时只加载图片的宽高信息BitmapFactory.decodeResource(mContext.getResources(),params[0],options);options.inSampleSize = calculateInSampleSize(options,dp2px(mContext,240),dp2px(mContext,360));  //2、根据ImageView的宽高计算所需要的采样率options.inJustDecodeBounds = false;   //3、inJustDecodeBounds置为false,正常加载图片Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),params[0],options);//把加载好的Bitmap放进LruCache内mCache.put(params[0],bitmap);return bitmap;}@Overrideprotected void onPostExecute(Bitmap bitmap) {imageView.setImageBitmap(bitmap);}}
复制代码

}

3.在MainAvtivity里面测试一下。

/*** 在这里测试一下,看看效果*/
public class MainActivity extends AppCompatActivity {//这里的图片自己去随便找几张吧private static final int[] drawableIds = new int[]{R.mipmap.ic1,R.mipmap.ic2, R.mipmap.ic3,R.mipmap.ic4, R.mipmap.ic5, R.mipmap.ic6, R.mipmap.ic7, R.mipmap.ic8,R.mipmap.ic9, R.mipmap.ic10, R.mipmap.ic11, R.mipmap.ic12, R.mipmap.ic13};private ViewPager mViewPager;private RelativeLayout mRelativeLayout;private MyPagerAdapter mPagerAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();}private void initViews() {mViewPager = (ViewPager) findViewById(R.id.viewpager);mPagerAdapter = new MyPagerAdapter(drawableIds,this);mViewPager.setAdapter(mPagerAdapter);mViewPager.setPageTransformer(true,new RotationPageTransformer());mViewPager.setOffscreenPageLimit(2);//设置预加载的数量,这里设置了2,会预加载中心item左边两个Item和右边两个ItemmViewPager.setPageMargin(10);//设置两个Page之间的距离}
}
复制代码

###4.布局里面就是一个ViewPager,id为viewpager,这里就不写了。

OK,下面来看一下效果图吧,是不是很酷呢?

[原创]自定义ViewPager实现3D画廊效果相关推荐

  1. Android开发学习之基于ViewPager实现Gallery画廊效果

    通过我们前面的学习,我们知道ViewPager是可以做出近乎完美的滑动体验,回顾整个Android,我们发现Gallery具备同样的特点,于是我们大胆地猜想,Gallery是否和ViewPager之间 ...

  2. 使用RecyclerView实现旋转3D画廊效果

    3D旋转画廊效果实现有哪些方式? 1.Gallery实现(官方已不推荐使用). 2.RecyclerView通过自定义LayoutManager实现. 一.简介 RecyclerView是google ...

  3. Android自带组件之Gallery 实现3D画廊效果

    1: 首先我们要了解到这个该控件的常用属性: 如图: 2:通过该组件定义属于我们自己的组件 iphone 中的coverflow中图片切换是有旋转和缩放效果的,而自带的gallery中并没有实现.因此 ...

  4. 【CSON原创】javascript实现3D涂鸦效果

    功能说明: 通过鼠标移动,实时绘制出3d旋转的线条. 兼容IE 5 6 7 8 9 10 firefox chrome 效果预览: 请按着鼠标左键,在画板上拖动绘制 实现原理: 在上一篇文章<j ...

  5. 自定义ViewPager实现轮播效果

    您也可以点此浏览,阅读体验更佳 前言 这种轮播效果多应用于展示电影海报,但是效果并不好,有些没有手势动画,更加没有fling效果.我将ViewPager的源码拷贝出来,做了修改,实现了这两个效果. 效 ...

  6. ViewPager实现Gallery画廊效果——仿慕课网app-求职路线计划-效果(一)

    效果图: 大体上就是这个样子,可能不太清楚 但是大家知道是什么效果就好啦~ (PS: 图中没有加高斯模糊图,后边 我会加上) 下面来分析一下这个布局 底层用一个ImageView 上层用一个定制的Vi ...

  7. ViewPager实现Gallery画廊效果——仿慕课网app-求职路线计划-效果(二)

    今晚给之前的写的收个尾 http://blog.csdn.net/codenoodles/article/details/50992113 前边没有看的可以先看一下效果. 之前写的没有背景的模糊图片效 ...

  8. android画廊效果的轮播图,轮播图(3d画廊效果)

    首先需要将轮播图的依赖导入 implementation 'com.github.xiaohaibin:XBanner:1.6.1' 接下来就是在项目目录下bulidgradle中导入(allproj ...

  9. XBanner实现3D画廊效果

    导依赖 在工程的build.gradle中allprojects {repositories {google()jcenter()maven { url 'https://jitpack.io' }} ...

最新文章

  1. Apache Maven 安装与配置-修改源
  2. 2018-2019-2 20165313 《网络对抗技术》Exp4 恶意代码分析
  3. Codeforces Round #375 (Div. 2) D. Lakes in Berland 并查集
  4. 【并发那些事】可见性问题的万恶之源
  5. 理解伪元素 :before 和 :after
  6. 悲催的CamShift
  7. JAVA安装报1620错误_java安装错误1620
  8. TCP之三:TCP/IP协议中backlog参数(队列参数)
  9. GPS从入门到放弃(十九) --- 精密星历
  10. 【高频电子线路】[模型]阻抗变换与阻抗匹配(第2章 谐振功率放大器)
  11. MS17010(永恒之蓝)漏洞利用与复现
  12. Petalinux配置
  13. Mac能连接手机热点却无法上网问题解决
  14. Cisco QOS之LLQ
  15. 入侵检测技术期末重点总结
  16. 分享假如你买到缩水U盘了怎么办?认倒霉?肯定不能的!
  17. 按头安利 好看又实用的SolidEdge 3d模型素材看这里
  18. 【笔试题】求最小公倍数 C++(两种方法)
  19. EOS智能合约开发系列(11): 多重签名
  20. 线上nacos命名空间误删如何找回 实践笔记

热门文章

  1. 火山视窗读写ini文件,写配置项与读配置项使用
  2. 互芯裁员,华平投资半导体四中一
  3. 徐直军:今年至少3亿设备用上鸿蒙,互联网又一领域暗藏“金矿“
  4. FileFilter 文件过滤器
  5. java eclipse 查看版本_怎么查看eclipse的版本号
  6. springboot+shiro+redis+jwt实现多端登录:PC端和移动端同时在线(不同终端可同时在线)
  7. C语言将一个简单的文件压缩
  8. 138.深度学习分布式计算框架-1
  9. python图像处理---python的图像处理模块Image
  10. Bootstrap进阶四:jQuery插件详解