Android Open Source - ListView3d List View3d






From Project

Back to project page ListView3d.

License

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.

Java Source Code

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);
  }
}




Java Source Code List

de.inovex.mtc.ListView3d.java
de.inovex.mtc.MTCRichGraphicsActivity.java
de.inovex.mtc.MyAdapter.java