Android下のGallery表示技術分析(三)


前回の記事ではバックグラウンド効果を実現しましたが、3 D効果を実現する方法を見てみましょう.コードの2つに注意してください.
  • transformImageBitmap:画像の変形;
  • getChildStaticTransformation:変形後の形状を制御する;
  • public class Gallery3D extends Gallery {
    	//     
    	private Camera mCamera = new Camera();
    	//       
    	private int mMaxRotationAngle = 60;
    	//      
    	private int mMaxZoom = -120;
    	//    
    	private int mCoveflowCenter;
    
    	public Gallery3D(Context context) {
    		super(context);
    		//      ,  getChildStaticTransformation  
    		this.setStaticTransformationsEnabled(true);
    	}
    
    	public Gallery3D(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		this.setStaticTransformationsEnabled(true);
    	}
    
    	public Gallery3D(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 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;
    	}
    
    	/**
    	 *   gallery        (   gallery   )
    	 */
    	@Override
    	protected boolean getChildStaticTransformation(View child, Transformation t) {
    		//      view    
    		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);
    		} else {
    			//      gallery              
    			rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
    			//                    (-mMaxRotationAngle mMaxRotationAngle;)
    			if (Math.abs(rotationAngle) > mMaxRotationAngle) {
    				rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
    						: mMaxRotationAngle;
    			}
    			transformImageBitmap((ImageView) child, t, rotationAngle);
    		}
    
    		return true;
    	}
    
    	@Override
    	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    		mCoveflowCenter = getCenterOfCoverflow();
    		super.onSizeChanged(w, h, oldw, oldh);
    	}
    
    	/**
    	 *      
    	 * @param child
    	 * @param t
    	 * @param rotationAngle
    	 */
    	private void transformImageBitmap(ImageView child, Transformation t,
    			int rotationAngle) {
    		//        
    		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);
    
    		//  Z      camera   ,         。   Y    ,       ;X          。
    		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);
    		}
    
    		//  Y    ,          。    X    ,           。
    		mCamera.rotateY(rotationAngle);
    		mCamera.getMatrix(imageMatrix);
    		imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
    		imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
    		mCamera.restore();
    	}
    }