[转载]超炫的3D特效程序管理功能android – tankaixiong – 博客园.
tank我昨天我花了点时间重新整理了一下,加了很多注释希望让大家能够看的很明白
整理后在原来的基础上,实现一个超炫的3D特效程序管理功能,所以更有用途了,不仅仅只是显示图片了。
实现的效果:
用3D效果显示所有已安装的程序列表,点击某张图片时动态显示到最前一张,长按可以打开该程序。(如上篇博客展示的样子,这里不再贴出)
主要思路流程如下:
public void onCreate(Bundle savedInstanceState) { |
super .onCreate(savedInstanceState); |
final CoverFlow cf = new CoverFlow( this ); |
cf.setAdapter( new ImageAdapter( this )); |
ImageAdapter imageAdapter = new ImageAdapter( this ); |
cf.setAdapter(imageAdapter); |
cf.setAnimationDuration( 1500 ); |
cf.setOnItemClickListener( this ); |
cf.setOnItemLongClickListener(lonClick); |
第一步:
创建一个实体类来保存程序信息:
LauncherItem
import Android.content.ComponentName; |
import Android.graphics.drawable.Drawable; |
public class LauncherItem { |
LauncherItem(Drawable d, String s, ComponentName cn) { |
public Drawable getIcon() { |
public void setIcon(Drawable icon) { |
public String getName() { |
public void setName(String name) { |
public ComponentName getComponent() { |
public void setComponent(ComponentName component) { |
this .component = component; |
List<LauncherItem> lvalue; |
public void getLauncher() { |
lvalue = new ArrayList<LauncherItem>(); |
PackageManager pkgMgt = this .getPackageManager(); |
Intent it = new Intent(Intent.ACTION_MAIN); |
it.addCategory(Intent.CATEGORY_LAUNCHER); |
List<ResolveInfo> ra = pkgMgt.queryIntentActivities(it, 0 ); |
for ( int i = 0 ; i < ra.size(); i++) { |
ActivityInfo ai = ra.get(i).activityInfo; |
Drawable icon = ai.loadIcon(pkgMgt); |
String label = ai.loadLabel(pkgMgt).toString(); |
ComponentName c = new ComponentName(ai.applicationInfo.packageName, |
LauncherItem item = new LauncherItem(icon, label, c); |
public class ImageAdapter extends BaseAdapter { |
int mGalleryItemBackground; |
private Context mContext; |
public ImageAdapter(Context context) { |
TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery); |
mGalleryItemBackground = typedArray.getResourceId( |
R.styleable.Gallery_android_galleryItemBackground, 0 ); |
public Object getItem( int position) { |
public long getItemId( int position) { |
public View getView( int position, View convertView, ViewGroup parent) { |
ImageView iv = new ImageView(mContext); |
iv.setImageDrawable(lvalue.get(position).icon); |
iv.setImageBitmap(MyImgView.createReflectedImage(MyImgView |
.drawableToBitmap(lvalue.get(position).icon))); |
iv.setLayoutParams( new Gallery.LayoutParams( 80 , 60 )); |
package com.android.tank; |
import android.graphics.Bitmap; |
import android.graphics.Canvas; |
import android.graphics.LinearGradient; |
import android.graphics.Matrix; |
import android.graphics.Paint; |
import android.graphics.PixelFormat; |
import android.graphics.PorterDuffXfermode; |
import android.graphics.Bitmap.Config; |
import android.graphics.PorterDuff.Mode; |
import android.graphics.Shader.TileMode; |
import android.graphics.drawable.Drawable; |
* 添加倒影,原理,先翻转图片,由上到下放大透明度 |
public static Bitmap createReflectedImage(Bitmap originalImage) { |
final int reflectionGap = 4 ; |
int width = originalImage.getWidth(); |
int height = originalImage.getHeight(); |
Matrix matrix = new Matrix(); |
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0 , |
height / 2 , width, height / 2 , matrix, false ); |
Bitmap bitmapWithReflection = Bitmap.createBitmap(width, |
(height + height / 2 ), Config.ARGB_8888); |
Canvas canvas = new Canvas(bitmapWithReflection); |
canvas.drawBitmap(originalImage, 0 , 0 , null ); |
Paint defaultPaint = new Paint(); |
canvas.drawRect( 0 , height, width, height + reflectionGap, defaultPaint); |
canvas.drawBitmap(reflectionImage, 0 , height + reflectionGap, null ); |
Paint paint = new Paint(); |
LinearGradient shader = new LinearGradient( 0 , |
originalImage.getHeight(), 0 , bitmapWithReflection.getHeight() |
+ reflectionGap, 0x70ffffff , 0x00ffffff , TileMode.CLAMP); |
paint.setXfermode( new PorterDuffXfermode(Mode.DST_IN)); |
canvas.drawRect( 0 , height, width, bitmapWithReflection.getHeight() |
return bitmapWithReflection; |
public static Bitmap drawableToBitmap(Drawable drawable) { |
drawable.getIntrinsicWidth(), |
drawable.getIntrinsicHeight(), |
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 |
: Bitmap.Config.RGB_565); |
Canvas canvas = new Canvas(bitmap); |
drawable.setBounds( 0 , 0 , drawable.getIntrinsicWidth(), drawable |
package com.android.tank; |
import android.content.Context; |
import android.graphics.Camera; |
import android.graphics.Matrix; |
import android.util.AttributeSet; |
import android.view.View; |
import android.view.animation.Transformation; |
import android.widget.Gallery; |
import android.widget.ImageView; |
public class CoverFlow extends Gallery { |
private Camera mCamera = new Camera(); |
private int mMaxRotationAngle = 50 ; |
private int mMaxZoom = - 500 ; |
private int mCoveflowCenter; |
private boolean mAlphaMode = true ; |
private boolean mCircleMode = false ; |
public CoverFlow(Context context) { |
this .setStaticTransformationsEnabled( true ); |
public CoverFlow(Context context, AttributeSet attrs) { |
this .setStaticTransformationsEnabled( true ); |
public CoverFlow(Context context, AttributeSet attrs, int defStyle) { |
super (context, attrs, defStyle); |
this .setStaticTransformationsEnabled( true ); |
public int getMaxRotationAngle() { |
return mMaxRotationAngle; |
public void setMaxRotationAngle( int maxRotationAngle) { |
mMaxRotationAngle = maxRotationAngle; |
public boolean getCircleMode() { |
public void setCircleMode( boolean isCircle) { |
public boolean getAlphaMode() { |
public void setAlphaMode( boolean isAlpha) { |
public int getMaxZoom() { |
public void setMaxZoom( int maxZoom) { |
private int getCenterOfCoverflow() { |
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 |
private static int getCenterOfView(View view) { |
return view.getLeft() + view.getWidth() / 2 ; |
protected boolean getChildStaticTransformation(View child, Transformation t) { |
final int childCenter = getCenterOfView(child); |
final int childWidth = child.getWidth(); |
t.setTransformationType(Transformation.TYPE_MATRIX); |
if (childCenter == mCoveflowCenter) { |
transformImageBitmap((ImageView) child, t, 0 , 0 ); |
rotationAngle = ( int ) ((( float ) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle); |
if (Math.abs(rotationAngle) > mMaxRotationAngle) { |
rotationAngle = (rotationAngle < 0 ) ? -mMaxRotationAngle |
transformImageBitmap((ImageView) child, t, rotationAngle, |
( int ) Math.floor((mCoveflowCenter - childCenter)/ (childWidth== 0 ? 1 :childWidth))); |
* This is called during layout when the size of this view has changed. If |
* you were just added to the view hierarchy, you're called with the old |
* Current width of this view. |
* Current height of this view. |
* Old width of this view. |
* Old height of this view. |
protected void onSizeChanged( int w, int h, int oldw, int oldh) { |
mCoveflowCenter = getCenterOfCoverflow(); |
super .onSizeChanged(w, h, oldw, oldh); |
* Transform the Image Bitmap by the Angle passed |
* ImageView the ImageView whose bitmap we want to rotate |
* the Angle by which to rotate the Bitmap |
private void transformImageBitmap(ImageView child, Transformation t, |
int rotationAngle, int d) { |
final Matrix imageMatrix = t.getMatrix(); |
final int imageHeight = child.getLayoutParams().height; |
final int imageWidth = child.getLayoutParams().width; |
final int rotation = Math.abs(rotationAngle); |
mCamera.translate( 0 .0f, 0 .0f, 100 .0f); |
if (rotation <= mMaxRotationAngle) { |
float zoomAmount = ( float ) (mMaxZoom + (rotation * 1.5 )); |
mCamera.translate( 0 .0f, 0 .0f, zoomAmount); |
mCamera.translate( 0 .0f, 155 , 0 .0f); |
mCamera.translate( 0 .0f, ( 255 - rotation * 2 .5f), 0 .0f); |
((ImageView) (child)).setAlpha(( int ) ( 255 - rotation * 2.5 )); |
mCamera.rotateY(rotationAngle); |
mCamera.getMatrix(imageMatrix); |
imageMatrix.preTranslate(-(imageWidth / 2 ), -(imageHeight / 2 )); |
imageMatrix.postTranslate((imageWidth / 2 ), (imageHeight / 2 )); |
最后是表示层:
<? xml version = "1.0" encoding = "utf-8" ?> |
android:orientation = "vertical" android:layout_width = "fill_parent" |
android:layout_height = "fill_parent" > |
< Gallery android:id = "@+id/gallery" android:layout_width = "fill_parent" |
android:layout_height = "wrap_content" android:layout_marginTop = "30dp" /> |
< ImageSwitcher android:id = "@+id/imageswitcher" |
android:layout_width = "fill_parent" android:layout_height = "wrap_content" |
android:layout_marginTop = "30dp" /> |
好了,大概就这些了,整理这么多东东贴出可花了我不少时间呢,希望对大家有帮助!
这里提供源码下载的地址(请尊重tank的心血成果):
http://files.cnblogs.com/tankaixiong/MyApplicationMenu.rar