PC上不说了一些很炫的界面效果很多,其实android上也可以实现很多很COOL的特效。

先看一下效果吧!

相册功能的效果:

下面是加载的andriod 里的程序,用3D效果列出来。这个可以做为android开机后的首页应该也很cool!

图片的效果是有倒影,有层次重叠的3D效果,左右图片之间切换,图片任意滑动,

还可以点击的任意后面的图片就会跑到最前面,有点像苹果的相册

这个实现起来其实并不复杂,原理我现在大致讲一下:

首先准备图片存入数组中,用Gallery实现图片的切换这个简单这里不多讲,这里要注意的层次重叠效果

只要设置图片相应的大小和位置的间距及摆放就可以了。

讲下实现倒影的原理,添加倒影,先翻转图片并设置好位置,再由上到下放大透明度也就是渐渐变淡了。


昨天我花了点时间重新整理了一下,加了很多注释希望让大家能够看的很明白


整理后在原来的基础上,实现一个超炫的3D特效程序管理功能,所以更有用途了,不仅仅只是显示图片了。

实现的效果:
用3D效果显示所有已安装的程序列表,点击某张图片时动态显示到最前一张,长按可以打开该程序。(如上篇博客展示的样子,这里不再贴出)

主要思路流程如下:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// 实例化launcher列表,得到应用程序的信息列表(包括图片)
getLauncher();

final CoverFlow cf = new CoverFlow(this);//重写Garry的getChildStaticTransformation ,产生层叠和放大效果
//填充我的要的图片 http://www.cnblogs.com/tankaixiong/(原)
cf.setAdapter(new ImageAdapter(this));
//自定义图片的填充方式
ImageAdapter imageAdapter = new ImageAdapter(this);
cf.setAdapter(imageAdapter);
cf.setAnimationDuration(1500);
cf.setOnItemClickListener(this);
cf.setOnItemLongClickListener(lonClick);
setContentView(cf);

}


第一步:
创建一个实体类来保存程序信息:

LauncherItem

package com.android.tank;

import android.content.ComponentName;
import android.graphics.drawable.Drawable;

public class LauncherItem {
Drawable icon;
String name;
ComponentName component;

LauncherItem(Drawable d, String s, ComponentName cn) {
icon = d;
name = s;
component = cn;
}

public Drawable getIcon() {
return icon;
}

public void setIcon(Drawable icon) {
this.icon = icon;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public ComponentName getComponent() {
return component;
}

public void setComponent(ComponentName component) {
this.component = component;
}

};
第二步:存入

//这里保存从应用程序中获取到的信息LIST(包括图片的信息),你也可以自己定一个图片集合
List<LauncherItem> lvalue;

// 获得app 列表信息
public void getLauncher() {
lvalue = new ArrayList<LauncherItem>();

PackageManager pkgMgt = this.getPackageManager();//这个方法是关键

// to query all launcher & load into List<>
Intent it = new Intent(Intent.ACTION_MAIN);
it.addCategory(Intent.CATEGORY_LAUNCHER);

List<ResolveInfo> ra = pkgMgt.queryIntentActivities(it, 0);//查询
//存入集合中 http://www.cnblogs.com/tankaixiong/(原)
for (int i = 0; i < ra.size(); i++) {
ActivityInfo ai = ra.get(i).activityInfo;

// String ainfo = ai.toString();
Drawable icon = ai.loadIcon(pkgMgt);
String label = ai.loadLabel(pkgMgt).toString();
ComponentName c = new ComponentName(ai.applicationInfo.packageName,
ai.name);

LauncherItem item = new LauncherItem(icon, label, c);

lvalue.add(item);
}

}

第三步:重写baseadapter
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
private Context mContext;

public ImageAdapter(Context context) {
mContext = context;
TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);
mGalleryItemBackground = typedArray.getResourceId(
R.styleable.Gallery_android_galleryItemBackground, 0);
}

// 第1点改进,返回一个很大的值,例如,Integer.MAX_VALUE
public int getCount() {
return resIds.length;
}

public Object getItem(int position) {
return position;
}

public long getItemId(int position) {
return 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));

return iv;
}

第四步:处理图片,产生特效
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 class MyImgView {

/**
* 添加倒影,原理,先翻转图片,由上到下放大透明度
* http://www.cnblogs.com/tankaixiong/(原)
* @param originalImage
* @return
*/
public static Bitmap createReflectedImage(Bitmap originalImage) {
// The gap we want between the reflection and the original image
final int reflectionGap = 4;

int width = originalImage.getWidth();
int height = originalImage.getHeight();

// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);

// Create a Bitmap with the flip matrix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);

// Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);

// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap http://www.cnblogs.com/tankaixiong/(原)
Paint defaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
// Draw in the reflection
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

// Create a shader that is a linear gradient that covers the reflection
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);

return bitmapWithReflection;
}
//drawable 类型转化为bitmap
public static Bitmap drawableToBitmap(Drawable drawable) {

Bitmap bitmap = Bitmap
.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
// canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}

}

第五步:

重写Garry 来达到层叠效果。
package com.android.tank;

import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;
//自己定义的Gallery
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) {
super(context);
this.setStaticTransformationsEnabled(true);
}

public CoverFlow(Context context, AttributeSet attrs) {
super(context, 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() {
return mCircleMode;
}

public void setCircleMode(boolean isCircle) {
mCircleMode = isCircle;
}

public boolean getAlphaMode() {
return mAlphaMode;
}

public void setAlphaMode(boolean isAlpha) {
mAlphaMode = isAlpha;
}

public int getMaxZoom() {
return mMaxZoom;
}

public void setMaxZoom(int maxZoom) {
mMaxZoom = maxZoom;
}

private int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
+ getPaddingLeft();
}

private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
//重写Garray方法 ,产生层叠和放大效果
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
final int childCenter = getCenterOfView(child);
final int childWidth = child.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (childCenter == mCoveflowCenter) {
transformImageBitmap((ImageView) child, t, 0, 0);
} else {
rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
// Log.d("test", "recanglenum:"+Math.floor ((mCoveflowCenter -
// childCenter) / childWidth));
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
transformImageBitmap((ImageView) child, t, rotationAngle,
(int) Math.floor((mCoveflowCenter - childCenter)/ (childWidth==0?1:childWidth)));
}
return true;
}

/**
* 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
* values of 0.
* http://www.cnblogs.com/tankaixiong/(原)
* @param w
* Current width of this view.
* @param h
* Current height of this view.
* @param oldw
* Old width of this view.
* @param oldh
* 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
* http://www.cnblogs.com/tankaixiong/(原)
* @param imageView
* ImageView the ImageView whose bitmap we want to rotate
* @param t
* transformation
* @param rotationAngle
* the Angle by which to rotate the Bitmap
*/
private void transformImageBitmap(ImageView child, Transformation t,
int rotationAngle, int d) {
mCamera.save();
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);
// As the angle of the view gets less, zoom in
if (rotation <= mMaxRotationAngle) {
float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
mCamera.translate(0.0f, 0.0f, zoomAmount);
if (mCircleMode) {
if (rotation < 40)
mCamera.translate(0.0f, 155, 0.0f);
else
mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f);
}
if (mAlphaMode) {
((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));
mCamera.restore();
}
}

最后是表示层:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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" />
</LinearLayout>

好了,大概就这些了,整理这么多东东贴出可花了我不少时间呢,希望对大家有帮助!

这里提供源码下载的地址(请尊重tank的心血成果):

http://files.cnblogs.com/tankaixiong/MyApplicationMenu.rar

更多相关文章

  1. Android导入SVG矢量图
  2. [置顶] Android客户端与服务端(jsp)之间json的传输与解析【附效果
  3. Android(安卓)应用开发 之使用LruCache和DiskLruCache来在内存和
  4. 实现ListView的条目下自动隐藏显示Button的方法
  5. Android添加图片水印
  6. Android(安卓)10适配要点,作用域存储
  7. (4.2.2.3)【android开源工具】【Android(安卓)UI设计与开发】第18
  8. Loading Large Bitmaps Efficiently 有效的加载大图片
  9. Android(安卓)菜单开发自定义效果

随机推荐

  1. android 让自己的app成为launcher
  2. Android短信发送和监控
  3. Android的简单的广播的例子
  4. Android 101 for iOS Developers
  5. Android 各种机型兼容问题
  6. Android: Runtime.exec()的陷阱
  7. Android(安卓)开发中的  AsyncTask 的
  8. android中比较两张图片的相似度
  9. Adding prebuilt shared library to Andr
  10. android 启动报错