Back to project page ListView3d.
The source code is released under:
Apache License
If you think the Android project ListView3d listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package de.inovex.mtc; /*from w ww .j a v a 2 s . c o m*/ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Camera; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LightingColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.widget.ListView; public class ListView3d extends ListView { /** Ambient light intensity */ private static final int AMBIENT_LIGHT = 55; /** Diffuse light intensity */ private static final int DIFFUSE_LIGHT = 200; /** Specular light intensity */ private static final float SPECULAR_LIGHT = 70; /** Shininess constant */ private static final float SHININESS = 200; /** The max intensity of the light */ private static final int MAX_INTENSITY = 0xFF; private final Camera mCamera = new Camera(); private final Matrix mMatrix = new Matrix(); /** Paint object to draw with */ private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG); public ListView3d(Context context, AttributeSet attrs) { super(context, attrs); //anti aliasing wont work with hardware acceleration //thats why the icons have a one pixel wide transparent border mPaint.setAntiAlias(true); } @Override protected boolean drawChild(Canvas canvas, View child, long drawingTime) { Bitmap bitmap = getChildDrawingCache(child); // (top,left) is the pixel position of the child inside the list final int top = child.getTop(); final int left = child.getLeft(); // center point of child final int childCenterY = child.getHeight() / 2; final int childCenterX = child.getWidth() / 2; //center of list final int parentCenterY = getHeight() / 2; //center point of child relative to list final int absChildCenterY = child.getTop() + childCenterY; //distance of child center to the list center final int distanceY = parentCenterY - absChildCenterY; //radius of imaginary cirlce final int r = getHeight() / 2; prepareMatrix(mMatrix, distanceY, r); mMatrix.preTranslate(-childCenterX, -childCenterY); mMatrix.postTranslate(childCenterX, childCenterY); mMatrix.postTranslate(left, top); canvas.drawBitmap(bitmap, mMatrix, mPaint); return false; } private void prepareMatrix(final Matrix outMatrix, int distanceY, int r){ //clip the distance final int d = Math.min(r, Math.abs(distanceY)); //use circle formula final float translateZ = (float) Math.sqrt((r * r) - (d * d)); //solve for t: d = r*cos(t) double radians = Math.acos((float) d / r); double degree = 90 - (180 / Math.PI) * radians; mCamera.save(); mCamera.translate(0, 0, r-translateZ); mCamera.rotateX((float) degree); if (distanceY < 0) { degree = 360 - degree; } mCamera.rotateY((float) degree); mCamera.getMatrix(outMatrix); mCamera.restore(); // highlight elements in the middle mPaint.setColorFilter(calculateLight((float) degree)); } private Bitmap getChildDrawingCache(final View child){ Bitmap bitmap = child.getDrawingCache(); if (bitmap == null) { child.setDrawingCacheEnabled(true); child.buildDrawingCache(); bitmap = child.getDrawingCache(); } return bitmap; } private LightingColorFilter calculateLight(final float rotation) { final double cosRotation = Math.cos(Math.PI * rotation / 180); int intensity = AMBIENT_LIGHT + (int) (DIFFUSE_LIGHT * cosRotation); int highlightIntensity = (int) (SPECULAR_LIGHT * Math.pow(cosRotation, SHININESS)); if (intensity > MAX_INTENSITY) { intensity = MAX_INTENSITY; } if (highlightIntensity > MAX_INTENSITY) { highlightIntensity = MAX_INTENSITY; } final int light = Color.rgb(intensity, intensity, intensity); final int highlight = Color.rgb(highlightIntensity, highlightIntensity, highlightIntensity); return new LightingColorFilter(light, highlight); } }