2012-04-05 3 views

답변

10

실제로 매우 간단하다. ListView를 확장하고 onDrawChild()를 재정의해야합니다. 거기에서 원하는 효과를 얻기 위해 3D 변형 행렬을 적용 할 수 있습니다. 나는 작동 예제가 내 github 또는 이것 좀 봐 수 있습니다 question 꽤 비슷합니다.

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

건배

+0

내가 힘내을 통해 프로젝트를 다운로드하려고하면, 이클립스는 거기에 어떤 프로젝트를 찾을 수 없습니다 : 여러분의 편의를 위해

이 내 차원의 ListView의 구현입니다. 나는 Zip과 git에서 직접 다운로드를 시도했다. 같은 문제. 또한 프로젝트를 구성하려고했지만 많은 오류가 발생합니다 –

+0

내 저장소에 프로젝트 파일을 갖고 싶지 않습니다. 하지만 다음과 같이하면됩니다. 1. zip으로 다운로드하십시오. 2. 원하는 폴더로 추출하십시오. 3. 이클립스에서 new-> Android Project-> 기존 소스에서 프로젝트 만들기를 수행합니다. 4. Build target을 android 4로 설정하거나 manifest에서 hardwareacceleration을 제거하십시오. 어쩌면 당신은 또한 프로젝트를 청소해야합니다. – Renard

+0

일부 수정, 나는 작동하도록 코드를 가지고 있지만 또 다른 문제가 있습니다 : 선택한 행에 위치를 변경하는 방법? 또한 서로 겹칠 행을 만드는 방법. 여기처럼 : [link] (http://img6.imageshack.us/img6/1375/snor1.jpg) –