2012-04-05 7 views

Antwort

10

ist eigentlich ziemlich einfach. Sie müssen ListView erweitern und onDrawChild() überschreiben. Dort können Sie 3D-Transformationsmatrizen anwenden, um den gewünschten Effekt zu erzielen. Ich habe ein funktionierendes Beispiel auf meinem github Oder Sie können einen Blick auf diese question werfen, die ziemlich ähnlich ist.

Für Ihre Bequemlichkeit ist meine Implementierung eines 3D-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 Paint mPaint; 

    public ListView3d(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 
     // get top left coordinates 
     final int top = child.getTop(); 
     final int left = child.getLeft(); 
     Bitmap bitmap = child.getDrawingCache(); 
     if (bitmap == null) { 
      child.setDrawingCacheEnabled(true); 
      child.buildDrawingCache(); 
      bitmap = child.getDrawingCache(); 
     } 

     final int centerY = child.getHeight()/2; 
     final int centerX = child.getWidth()/2; 
     final int radius = getHeight()/2; 
     final int absParentCenterY = getTop() + getHeight()/2; 
     final int absChildCenterY = child.getTop() + centerX; 
     final int distanceY = absParentCenterY - absChildCenterY; 
     final int absDistance = Math.min(radius, Math.abs(distanceY)); 

     final float translateZ = (float) Math.sqrt((radius * radius) - (absDistance * absDistance)); 

     double radians = Math.acos((float) absDistance/radius); 
     double degree = 90 - (180/Math.PI) * radians; 

     mCamera.save(); 
     mCamera.translate(0, 0, radius - translateZ); 
     mCamera.rotateX((float) degree); // remove this line.. 
     if (distanceY < 0) { 
      degree = 360 - degree; 
     } 
     mCamera.rotateY((float) degree); // and change this to rotateX() to get a 
              // wheel like effect 
     mCamera.getMatrix(mMatrix); 
     mCamera.restore(); 

     // create and initialize the paint object 
     if (mPaint == null) { 
      mPaint = new Paint(); 
      mPaint.setAntiAlias(true); 
      mPaint.setFilterBitmap(true); 
     } 
     //highlight elements in the middle 
     mPaint.setColorFilter(calculateLight((float) degree)); 

     mMatrix.preTranslate(-centerX, -centerY); 
     mMatrix.postTranslate(centerX, centerY); 
     mMatrix.postTranslate(left, top); 
     canvas.drawBitmap(bitmap, mMatrix, mPaint); 
     return false; 
    } 

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

Prost

+0

Wenn ich versuche, das Projekt durch Git herunterladen können Eclipse-finden keine Projekte drin. Ich habe versucht, als Zip und direkt von Git herunterzuladen. Das gleiche Problem. Auch versucht, Ihr Projekt zu konfigurieren, aber es geht viele Fehler –

+0

Ich habe nicht gerne Projektdateien in meinen Repositories. Aber das sollte kein Problem sein, da Sie einfach folgendes tun können: 1. Download als zip. 2. Extrahiere in einen Ordner deiner Wahl. 3. In eclipse tu new-> Android Project-> Projekt aus existierender Quelle erstellen. 4. Setzen Sie das Build-Ziel auf Android 4 oder entfernen Sie die Hardware-Beschleunigung aus dem Manifest. Vielleicht müssen Sie auch das Projekt säubern. – Renard

+0

Mit einigen Korrekturen, habe ich Ihren Code zu arbeiten, aber es gibt ein anderes Problem: Wie man Position zu vorgewählter Reihe ändert? Außerdem, wie man Zeilen übereinander legt. Wie hier: [link] (http://img6.imageshack.us/img6/1375/snor1.jpg) –