Android3D画廊总结整理
2016-07-08 19:34
351 查看
/**
* 在网上看到好多的3D画廊的效果,最常见就是Gallery,但是在API16的时候就已经废弃了,现在推荐使用ViewPager和HorizontalScrollView来实现这种效果,下面就在这里对其进行整理一下,代码更多的是借鉴了好多网上的,勿喷!!!!
*/
Gallery实现
步骤:
1、为Gallery设置Adapter
2、设置图片倒影效果
3、自定义Gallery
为了实现3D的效果需要覆盖protected boolean getChildStaticTransformation(View child, Transformation t)方法,通过为transformation设置动画来实现图片3D的浏览效果。
凡是大量用到Bitmap的地方都有可能发生OOM异常,为了解决OOM异常这里应用软引用来对图片进行缓存处理
使用步骤:
1、布局文件引用
ViewPager实现
滑动ViewPager页面显示动画效果,你需要去实现ViewPager.PageTransform类,重写public void transformPage(View page, float position) {方法
在Android官方文档提供了两种:ZoomOutPageTransformer、DepthPageTransformer
1、ZoomOutPageTransformer
代码
2、DepthPageTransformer
代码
效果
在一个屏幕显示多个Page
* 在网上看到好多的3D画廊的效果,最常见就是Gallery,但是在API16的时候就已经废弃了,现在推荐使用ViewPager和HorizontalScrollView来实现这种效果,下面就在这里对其进行整理一下,代码更多的是借鉴了好多网上的,勿喷!!!!
*/
Gallery实现
步骤:
1、为Gallery设置Adapter
@Override public View getView(int position, View convertView, ViewGroup parent) { ImageView iv; if (convertView != null) { iv = (ImageView) convertView; } else { iv = new ImageView(MainActivity.this); } //通过调用BitmapUtils的getBitmap方法来得到生成倒影效果的图片 Bitmap bitmap = BitmapUtils.getImageBitmap(getResources(), res[position]); BitmapDrawable bd = new BitmapDrawable(bitmap); bd.setAntiAlias(true);//为Bitmap设置抗锯齿效果 iv.setImageDrawable(bd); Gallery.LayoutParams params = new Gallery.LayoutParams(160, 400); iv.setLayoutParams(params);//为ImageView设置宽高 return iv; }
2、设置图片倒影效果
public static Bitmap getBitmap(Resources res, int drawableId) { Bitmap src_bitmap = BitmapFactory.decodeResource(res, drawableId);//原图 //1、生成倒影图片 Matrix matrix = new Matrix(); matrix.setScale(1, -1);// 让图形按照矩阵进行垂直反转 Bitmap inverted_Bitmap = Bitmap.createBitmap(src_bitmap, 0, (int) (src_bitmap.getHeight() * 0.5), src_bitmap.getWidth(), src_bitmap.getHeight() / 2, matrix, true); //2、得到合成的图片 Bitmap result = Bitmap.createBitmap(src_bitmap.getWidth(), (int) (src_bitmap.getHeight() * 1.5 + 10), Bitmap.Config.ARGB_8888); //将原图和倒影图画到合成图上 Canvas canvas = new Canvas(result); canvas.drawBitmap(src_bitmap, 0, 0, null); canvas.drawBitmap(inverted_Bitmap, 0, src_bitmap.getHeight() + 10, null); //3、设置遮罩效果 Paint paint = new Paint(); // 设置颜色 LinearGradient lg = new LinearGradient(0, (int) (src_bitmap.getHeight() + 10), 0, result.getHeight(), 0x70ffffff, 0x00ffffff, Shader.TileMode.CLAMP); paint.setShader(lg); // 设置模式为: 遮罩, 是取交集 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawRect(0, (int) (src_bitmap.getHeight() + 5), src_bitmap.getWidth(), result.getHeight(), paint); src_bitmap.recycle(); inverted_Bitmap.recycle(); return result; }xfermode的讲解请移步:http://blog.csdn.net/weiwozhiyi/article/details/50749622
3、自定义Gallery
为了实现3D的效果需要覆盖protected boolean getChildStaticTransformation(View child, Transformation t)方法,通过为transformation设置动画来实现图片3D的浏览效果。
t.clear();// 设置变换效果之前, 需要把Transformation中的上一个item的变换效果清楚 t.setTransformationType(Transformation.TYPE_MATRIX);// 设置变换效果的类型为矩阵类型接下来通过使用camera来为图片设置放大、透明度、旋转的效果
private void startTransformation(ImageView child, int rotateAngle, Transformation t) { camera.save();// 保存状态 int absRotateAngle = Math.abs(rotateAngle); // 取旋转角度的绝对值 //1、放大效果(中间的图片要比两边的图片要大) camera.translate(0, 0, 100); int zoom = -250 + absRotateAngle*2 ; camera.translate(0, 0, zoom); //2、 透明度(中间的图片是完全显示, 两边有一定的透明度) int alpha = 255 - 3 * absRotateAngle; child.setAlpha(alpha);// 透明度取值范围: 0 ~ 255, 0 就是完全隐藏, 255 完全显示 //3、旋转(在中间的图片没有旋转角度, 只要不在中间就有旋转角度) camera.rotateY(rotateAngle); Matrix matrix = t.getMatrix(); // 给matrix赋值 camera.getMatrix(matrix);// 把matrix矩阵给camera对象, camera对象就会把上面添加的效果转换成矩阵添加到matrix对象中
凡是大量用到Bitmap的地方都有可能发生OOM异常,为了解决OOM异常这里应用软引用来对图片进行缓存处理
强引用: String s = "abc"; list.add(s); 软引用: 如果若引用对象回收完之后,内存还是报警,继续回收软引用对象,还是继续内存报警, OOM outOfMemoryException内存溢出异常 SoftReference<Bitmap> softReference = new SoftReference<Bitmap>(bitmap); 弱引用: 如果虚引用对象回收完之后,内存还是报警,继续回收弱引用对象 虚引用: 虚拟机的内存不够使用,开始报警,这时候垃圾回收机制开始执行System.gc(); String a = "a";(定义了之后没有用这个对象则回收它) 如果没有对象回收了,回收虚引用的对象当然你如果不想自己去写这么多代码,github提供了3DGallery的库https://github.com/davidschreiber/FancyCoverFlow
使用步骤:
1、布局文件引用
<at.technikum.mti.fancycoverflow.FancyCoverFlow android:id="@+id/fancy_converflow" android:layout_width="match_parent" android:layout_height="match_parent"> </at.technikum.mti.fancycoverflow.FancyCoverFlow>2、对自定义控件进行设置
/** * 当然你也可以在xml进行设置 *fcf:maxRotation="45" *fcf:unselectedAlpha="0.3" *fcf:unselectedSaturation="0.0" *fcf:unselectedScale="0.4" *fcf:scaleDownGravity="0.5" */ fancy_converflow.setUnselectedAlpha(1.0f);//未选择的Item透明度 fancy_converflow.setUnselectedSaturation(0.0f);//未选中的饱和度 fancy_converflow.setUnselectedScale(0.5f);//未选中的缩放 fancy_converflow.setSpacing(20);//设置Item之间间隙 fancy_converflow.setMaxRotation(45);//设置最大的旋转角 fancy_converflow.setScaleDownGravity(0.5f);//从哪个位置进行缩放 fancy_converflow.setReflectionEnabled(true); fancy_converflow.setReflectionRatio(0.3f);//倒影的比例 fancy_converflow.setReflectionGap(10);//倒影和原图的间距 fancy_converflow.setActionDistance(FancyCoverFlow.ACTION_DISTANCE_AUTO);
ViewPager实现
滑动ViewPager页面显示动画效果,你需要去实现ViewPager.PageTransform类,重写public void transformPage(View page, float position) {方法
在Android官方文档提供了两种:ZoomOutPageTransformer、DepthPageTransformer
1、ZoomOutPageTransformer
代码
public void transformPage(View view, float position) { int pageWidth = view.getWidth(); int pageHeight = view.getHeight(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0); } else if (position <= 1) { // [-1,1] // Modify the default slide transition to shrink the page as well float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); float vertMargin = pageHeight * (1 - scaleFactor) / 2; float horzMargin = pageWidth * (1 - scaleFactor) / 2; if (position < 0) { view.setTranslationX(horzMargin - vertMargin / 2); } else { view.setTranslationX(-horzMargin + vertMargin / 2); } // Scale the page down (between MIN_SCALE and 1) view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); // Fade the page relative to its size. view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } }
2、DepthPageTransformer
代码
public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0); } else if (position <= 0) { // [-1,0] // Use the default slide transition when moving to the left page view.setAlpha(1); view.setTranslationX(0); view.setScaleX(1); view.setScaleY(1); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 - position); // Counteract the default slide transition view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } }更多关于ViewPager的内容请看鸿洋大神的:http://blog.csdn.net/lmj623565791/article/details/40411921/
效果
在一个屏幕显示多个Page
//页面宽度所占ViewPager的宽度的比例,默认为1 @Override public float getPageWidth(int position) { return 0.4f; }为每个Page添加间距
vp.setPageMargin(30);代码如下:
public class CustomTransform implements ViewPager.PageTransformer { private static final float MIN_SCALE=0.65f; private int MAX_ROTATION = 40; @Override public void transformPage(View page, float position) { float scaleFactor=Math.max(MIN_SCALE,1-Math.abs(position)); float rotate=20*Math.abs(position); if (position<-1){ // This page is way off-screen to the left. }else if (position <= 1){ // Modify the default slide transition to shrink the page as well page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); page.setRotationY(rotate); }else if (position>1) { // This page is way off-screen to the right. } } }
相关文章推荐
- 根据两点经纬度计算两点距离...工具类
- Android ANR
- 移植rtmpdump(rtmpdump)到android
- Android 隐藏标题栏
- Android 防止重复按钮点击
- Android studio项目迁移问题及解决方案
- Android 支付宝开发遇到的一些问题
- Android js和native交互的两种方法
- Android IntentService使用全面介绍及源码解析
- 关于Android电池管理系统(二)
- Android使用GridView内容填充满不出现滚动的设计
- Android 状态栏、titlebar的高度计算
- Android在Fragment中嵌套(添加)Fragment
- android常见笔试题
- android打包
- android打包
- Android中杀进程的几种方法 (1) - killBackgroundProcesses
- imx6 android开机启动守护进程
- Android四大基本组件介绍与生命周期
- Android wait notify sleep 与死锁问题举例