我们专业课有Android的学习,最后老师让做一个简单的Android应用程序.我在网上找些资料,加上自己改造一下做了一个3D相册.

程序仿照Android的相册功能,调用Gallery类对相片进行浏览.实现3D效果.其中不足的地方就是里面的图片都是写死的.这一点可以改进.程序中使用Png格式图片,注意图片不要太大,500*500一下最好.

首先:

GalleryFlow.java 类 用来实现图片放映查看效果.

   1: package com.android.CustomGallery;
   2:  
   3: import android.content.Context;
   4: import android.graphics.Camera;
   5: import android.graphics.Matrix;
   6: import android.util.AttributeSet;
   7: import android.util.Log;
   8: import android.view.View;
   9: import android.view.animation.Transformation;
  10: import android.widget.Gallery;
  11: import android.widget.ImageView;
  12:  
  13: public class GalleryFlow extends Gallery {
  14:  
  15:         /**
  16:          * Graphics Camera used for transforming the matrix of ImageViews
  17:          */
  18:         private Camera mCamera = new Camera();
  19:  
  20:         /**
  21:          * The maximum angle the Child ImageView will be rotated by
  22:          */
  23:         private int mMaxRotationAngle = 60;
  24:  
  25:         /**
  26:          * The maximum zoom on the centre Child
  27:          */
  28:         private int mMaxZoom = -120;
  29:  
  30:         /**
  31:          * The Centre of the Coverflow
  32:          */
  33:         private int mCoveflowCenter;
  34:  
  35:         public GalleryFlow(Context context) {
  36:                 super(context);
  37:                 this.setStaticTransformationsEnabled(true);
  38:         }
  39:  
  40:         public GalleryFlow(Context context, AttributeSet attrs) {
  41:                 super(context, attrs);
  42:                 this.setStaticTransformationsEnabled(true);
  43:         }
  44:  
  45:         public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {
  46:                 super(context, attrs, defStyle);
  47:                 this.setStaticTransformationsEnabled(true);
  48:         }
  49:  
  50:         /**
  51:          * Get the max rotational angle of the image
  52:          * 
  53:          * @return the mMaxRotationAngle
  54:          */
  55:         public int getMaxRotationAngle() {
  56:                 return mMaxRotationAngle;
  57:         }
  58:  
  59:         /**
  60:          * Set the max rotational angle of each image
  61:          * 
  62:          * @param maxRotationAngle
  63:          *            the mMaxRotationAngle to set
  64:          */
  65:         public void setMaxRotationAngle(int maxRotationAngle) {
  66:                 mMaxRotationAngle = maxRotationAngle;
  67:         }
  68:  
  69:         /**
  70:          * Get the Max zoom of the centre image
  71:          * 
  72:          * @return the mMaxZoom
  73:          */
  74:         public int getMaxZoom() {
  75:                 return mMaxZoom;
  76:         }
  77:  
  78:         /**
  79:          * Set the max zoom of the centre image
  80:          * 
  81:          * @param maxZoom
  82:          *            the mMaxZoom to set
  83:          */
  84:         public void setMaxZoom(int maxZoom) {
  85:                 mMaxZoom = maxZoom;
  86:         }
  87:  
  88:         /**
  89:          * Get the Centre of the Coverflow
  90:          * 
  91:          * @return The centre of this Coverflow.
  92:          */
  93:         private int getCenterOfCoverflow() {
  94:                 //Log.e("CoverFlow Width+Height", getWidth() + "*" + getHeight());
  95:                 return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
  96:                                 + getPaddingLeft();
  97:         }
  98:  
  99:         /**
 100:          * Get the Centre of the View
 101:          * 
 102:          * @return The centre of the given view.
 103:          */
 104:         private static int getCenterOfView(View view) {
 105:                 /*Log.e("ChildView Width+Height", view.getWidth() + "*"
 106:                                 + view.getHeight());*/
 107:                 return view.getLeft() + view.getWidth() / 2;
 108:         }
 109:  
 110:         /**
 111:          * {@inheritDoc}
 112:          * 
 113:          * @see #setStaticTransformationsEnabled(boolean)
 114:          */
 115:         protected boolean getChildStaticTransformation(View child, Transformation t) {
 116:  
 117:                 final int childCenter = getCenterOfView(child);
 118:                 final int childWidth = child.getWidth();
 119:                 int rotationAngle = 0;
 120:  
 121:                 t.clear();
 122:                 t.setTransformationType(Transformation.TYPE_MATRIX);
 123:  
 124:                 if (childCenter == mCoveflowCenter) {
 125:                         transformImageBitmap((ImageView) child, t, 0);
 126:                 } else {
 127:                         rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
 128:                         if (Math.abs(rotationAngle) > mMaxRotationAngle) {
 129:                                 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
 130:                                                 : mMaxRotationAngle;
 131:                         }
 132:                         transformImageBitmap((ImageView) child, t, rotationAngle);
 133:                 }
 134:  
 135:                 return true;
 136:         }
 137:  
 138:         /**
 139:          * This is called during layout when the size of this view has changed. If
 140:          * you were just added to the view hierarchy, you're called with the old
 141:          * values of 0.
 142:          * 
 143:          * @param w
 144:          *            Current width of this view.
 145:          * @param h
 146:          *            Current height of this view.
 147:          * @param oldw
 148:          *            Old width of this view.
 149:          * @param oldh
 150:          *            Old height of this view.
 151:          */
 152:         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 153:                 mCoveflowCenter = getCenterOfCoverflow();
 154:                 super.onSizeChanged(w, h, oldw, oldh);
 155:         }
 156:  
 157:         /**
 158:          * Transform the Image Bitmap by the Angle passed
 159:          * 
 160:          * @param imageView
 161:          *            ImageView the ImageView whose bitmap we want to rotate
 162:          * @param t
 163:          *            transformation
 164:          * @param rotationAngle
 165:          *            the Angle by which to rotate the Bitmap
 166:          */
 167:         private void transformImageBitmap(ImageView child, Transformation t,
 168:                         int rotationAngle) {
 169:                 mCamera.save();
 170:                 final Matrix imageMatrix = t.getMatrix();
 171:                 final int imageHeight = child.getLayoutParams().height;
 172:                 final int imageWidth = child.getLayoutParams().width;
 173:                 final int rotation = Math.abs(rotationAngle);
 174:  
 175:                 // 在Z轴上正向移动camera的视角,实际效果为放大图片。
 176:                 // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
 177:                 mCamera.translate(0.0f, 0.0f, 100.0f);
 178:  
 179:                 // As the angle of the view gets less, zoom in
 180:                 if (rotation < mMaxRotationAngle) {
 181:                         float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
 182:                         mCamera.translate(0.0f, 0.0f, zoomAmount);
 183:                 }
 184:  
 185:                 // 在Y轴上旋转,对应图片竖向向里翻转。
 186:                 // 如果在X轴上旋转,则对应图片横向向里翻转。
 187:                 mCamera.rotateY(rotationAngle);
 188:                 mCamera.getMatrix(imageMatrix);
 189:                 // Preconcats matrix相当于右乘矩阵,Postconcats matrix相当于左乘矩阵。
 190:                 imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
 191:                 imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
 192:                 mCamera.restore();
 193:         }
 194: }

ageAdapter.java 图片适配器类,用来将文件中的图片资源加载到应用程序

   1: package com.android.CustomGallery;
   2:  
   3: import android.content.Context;
   4: import android.graphics.Bitmap;
   5: import android.graphics.BitmapFactory;
   6: import android.graphics.Canvas;
   7: import android.graphics.LinearGradient;
   8: import android.graphics.Matrix;
   9: import android.graphics.Paint;
  10: import android.graphics.PorterDuffXfermode;
  11: import android.graphics.Bitmap.Config;
  12: import android.graphics.PorterDuff.Mode;
  13: import android.graphics.Shader.TileMode;
  14: import android.graphics.drawable.BitmapDrawable;
  15: import android.view.View;
  16: import android.view.ViewGroup;
  17: import android.widget.BaseAdapter;
  18: import android.widget.ImageView;
  19:  
  20: /*
  21: * Copyright (C) 2010 Neil Davies
  22: *
  23: * Licensed under the Apache License, Version 2.0 (the "License");
  24: * you may not use this file except in compliance with the License.
  25: * You may obtain a copy of the License at
  26: *
  27: * http://www.apache.org/licenses/LICENSE-2.0
  28: *
  29: * Unless required by applicable law or agreed to in writing, software
  30: * distributed under the License is distributed on an "AS IS" BASIS,
  31: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  32: * See the License for the specific language governing permissions and
  33: * limitations under the License.
  34: * 
  35: * This code is base on the Android Gallery widget and was Created 
  36: * by Neil Davies neild001 'at' gmail dot com to be a Coverflow widget
  37: * 
  38: * @author Neil Davies
  39: */
  40: public class ImageAdapter extends BaseAdapter {
  41:         int mGalleryItemBackground;
  42:         private Context mContext;
  43:  
  44:         private int[] mImageIds;
  45:  
  46:         private ImageView[] mImages;
  47:  
  48:         public ImageAdapter(Context c, int[] ImageIds) {
  49:                 mContext = c;
  50:                 mImageIds = ImageIds;
  51:                 mImages = new ImageView[mImageIds.length];
  52:         }
  53:  
  54:         public boolean createReflectedImages() {
  55:                 // The gap we want between the reflection and the original image
  56:                 final int reflectionGap = 4;
  57:                 
  58:  
  59:  
  60:                 int index = 0;
  61:                 for (int imageId : mImageIds) {
  62:                         Bitmap originalImage = BitmapFactory.decodeResource(mContext
  63:                                         .getResources(), imageId);
  64:                         int width = originalImage.getWidth();
  65:                         int height = originalImage.getHeight();
  66:  
  67:                         // This will not scale but will flip on the Y axis
  68:                         Matrix matrix = new Matrix();
  69:                         matrix.preScale(1, -1);
  70:  
  71:                         // Create a Bitmap with the flip matrix applied to it.
  72:                         // We only want the bottom half of the image
  73:                         Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
  74:                                         height / 2, width, height / 2, matrix, false);
  75:  
  76:                         // Create a new bitmap with same width but taller to fit
  77:                         // reflection
  78:                         Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
  79:                                         (height + height / 2), Config.ARGB_8888);
  80:  
  81:                         // Create a new Canvas with the bitmap that's big enough for
  82:                         // the image plus gap plus reflection
  83:                         Canvas canvas = new Canvas(bitmapWithReflection);
  84:                         // Draw in the original image
  85:                         canvas.drawBitmap(originalImage, 0, 0, null);
  86:                         // Draw in the gap
  87:                         Paint deafaultPaint = new Paint();
  88:                         canvas.drawRect(0, height, width, height + reflectionGap,
  89:                                         deafaultPaint);
  90:                         // Draw in the reflection
  91:                         canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
  92:  
  93:                         // Create a shader that is a linear gradient that covers the
  94:                         // reflection
  95:                         Paint paint = new Paint();
  96:                         LinearGradient shader = new LinearGradient(0, originalImage
  97:                                         .getHeight(), 0, bitmapWithReflection.getHeight()
  98:                                         + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
  99:                         // Set the paint to use this shader (linear gradient)
 100:                         paint.setShader(shader);
 101:                         // Set the Transfer mode to be porter duff and destination in
 102:                         paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
 103:                         // Draw a rectangle using the paint with our linear gradient
 104:                         canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
 105:                                         + reflectionGap, paint);
 106:                         //解决图片的锯齿现象
 107:                         BitmapDrawable bd = new BitmapDrawable(bitmapWithReflection);
 108:                         bd.setAntiAlias(true);
 109:  
 110:                         ImageView imageView = new ImageView(mContext);
 111:                         //imageView.setImageBitmap(bitmapWithReflection);
 112:                         imageView.setImageDrawable(bd);
 113:                         imageView.setLayoutParams(new GalleryFlow.LayoutParams(160, 240));
 114:                         // imageView.setScaleType(ScaleType.MATRIX);
 115:                         mImages[index++] = imageView;
 116:  
 117:                 }
 118:                 return true;
 119:         }
 120:  
 121:         public int getCount() {
 122:                 return mImageIds.length;
 123:         }
 124:  
 125:         public Object getItem(int position) {
 126:                 return position;
 127:         }
 128:  
 129:         public long getItemId(int position) {
 130:                 return position;
 131:         }
 132:  
 133:         public View getView(int position, View convertView, ViewGroup parent) {
 134:  
 135:                 // Use this code if you want to load from resources
 136:                 /*
 137:                  * ImageView i = new ImageView(mContext);
 138:                  * i.setImageResource(mImageIds[position]); i.setLayoutParams(new
 139:                  * CoverFlow.LayoutParams(350,350));
 140:                  * i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 141:                  * 
 142:                  * //Make sure we set anti-aliasing otherwise we get jaggies
 143:                  * BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
 144:                  * drawable.setAntiAlias(true); return i;
 145:                  */
 146:  
 147:                 return mImages[position];
 148:         }
 149:  
 150:         /**
 151:          * Returns the size (0.0f to 1.0f) of the views depending on the 'offset' to
 152:          * the center.
 153:          */
 154:         public float getScale(boolean focused, int offset) {
 155:                 /* Formula: 1 / (2 ^ offset) */
 156:                 return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
 157:         }
 158:  
 159: }
 

MainActivity.java 用来显示界面

   1: package com.android.CustomGallery;
   2:  
   3: /**
   4: * 一个实现了3D效果的Gallery,就像iPhone中的相册浏览一样炫……
   5: */
   6: import android.app.Activity;
   7: import android.os.Bundle;
   8:  
   9: public class MainActivity extends Activity {
  10:         /** Called when the activity is first created. */
  11:         @Override
  12:         public void onCreate(Bundle savedInstanceState) {
  13:                 super.onCreate(savedInstanceState);
  14:  
  15:                 setContentView(R.layout.main);
  16:  
  17:                 int[] images = { R.drawable.photo1, R.drawable.photo2,
  18:                                 R.drawable.photo3, R.drawable.photo4, R.drawable.photo5,
  19:                                 R.drawable.photo6, R.drawable.photo7, R.drawable.photo8, };
  20:  
  21:                 ImageAdapter adapter = new ImageAdapter(this, images);
  22:                 adapter.createReflectedImages();
  23:  
  24:                 GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.gallery_flow);
  25:                 galleryFlow.setAdapter(adapter);
  26:  
  27:         }
  28: }

main.xml 程序设置文件

   1: "1.0" encoding="utf-8"?>
   2: "http://schemas.android.com/apk/res/android"
   3:     android:orientation="vertical"
   4:     android:layout_width="fill_parent"
   5:     android:layout_height="fill_parent"
   6:     >
   7:
   8:         android:id="@+id/gallery_flow"
   9:         android:layout_width="fill_parent"
  10:         android:layout_height="fill_parent"
  11:         />

Android 一个3D相册源码的更多相关文章

  1. android 近百个源码项目【转】

    http://www.cnblogs.com/helloandroid/articles/2385358.html Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多 ...

  2. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  3. Ubuntu 14.04 LTS 下 android 2.3.5 源码编译过程

    Ubuntu 14.04 LTS 下 android 2.3.5 源码编译过程   在新的Ubuntu 64位系统下去编译早期的安卓源码是会出现很多问题的,因为64位系统在安装完成后,很多32位的兼容 ...

  4. android版猜拳游戏源码分享

    android版猜拳游戏源码分享安卓版猜拳游戏源码,该文件中带有安装测试包的,这个游戏源码比较简单的,现在有两个代码,一个自定义VIEW的,一个就是普通的imageView图片,游戏非常适合一些新手的 ...

  5. Android -- 带你从源码角度领悟Dagger2入门到放弃

    1,以前的博客也写了两篇关于Dagger2,但是感觉自己使用的时候还是云里雾里的,更不谈各位来看博客的同学了,所以今天打算和大家再一次的入坑试试,最后一次了,保证最后一次了. 2,接入项目 在项目的G ...

  6. Android -- 带你从源码角度领悟Dagger2入门到放弃(二)

    1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...

  7. 一个普通的 Zepto 源码分析(二) - ajax 模块

    一个普通的 Zepto 源码分析(二) - ajax 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块,以 ...

  8. [Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法

    博客首页:http://www.cnblogs.com/kezhuang/p/关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下<[Andr ...

  9. 编译Android 4.4.2源码

    在之前的文章中,和大家分享了在天朝下下载android 4.4.2源码的过程(详见下载android4.4.2源码全过程(附已下载的源码)),现在写下编译的笔记. 虽然在android doc中,有提 ...

随机推荐

  1. tensroflow中如何计算特征图的输出及padding大小

    根据tensorflow中的conv2d函数,我们先定义几个基本符号 1.输入矩阵 W×W,这里只考虑输入宽高相等的情况,如果不相等,推导方法一样,不多解释. 2.filter矩阵 F×F,卷积核 3 ...

  2. 35)类和结构体类比---this

    那么,为啥  Test a(10)  , Test  b(20)   然后  我a.getI()  取到的是10,而不是20     就能将那个  10  给  a  对象的  m1    是因为有 ...

  3. c语言中对字段宽度的理解?

    /************************************************************************* > File Name: printf.c ...

  4. Cell theory|Bulk RNA-seq|Cellar heterogeneity|Micromanipulation|Limiting dilution|LCM|FACS|MACS|Droplet|10X genomics|Human cell atlas|Spatially resolved transcriptomes|ST|Slide-seq|SeqFISH|MERFISH

    生物信息学 Cell theory:7个要点 All known living things are made up of one or more cells. All living cells ar ...

  5. 使用OkHttp上传图片到服务器

    Okhttp上传图片方法,就像网页那样,使用Form的Post. 首先创建requestBody,然后Builder构建Query:最后Response返回服务器请求,最后把response.body ...

  6. 一个简单的jQuery回调函数例子

    jQuery回调函数简单使用 比如说,我们想要点击某个按钮后触发事件, 先把一些指定内容给隐藏掉, 然后跳出相关信息的对话框. 如果使用普通的方法, 不用回调函数的话, 会有怎么样的效果呢? 效果是先 ...

  7. The Maximum Unreachable Node Set

    题目描述 In this problem, we would like to talk about unreachable sets of a directed acyclic graph G = ( ...

  8. [LC] 114. Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1 ...

  9. Android 7.0终极开发者预览版全攻略!

    近日,Google的工程部副总裁Dave Burke在官方博客上正式发布开发者预览版5,此预览版是android 7.0 “牛轧糖”正式发布前最后一个预览版,同时也是在性能.功能上等多方面的表现上最接 ...

  10. LabVIEW的优点

    知道Labview的英文全称是什么吗?Labview的创始公司的名字是什么吗?哈哈,其实这就是NI(National Instruments)美国国家仪器公司创造Labview的初衷:代替传统测量仪器 ...