Android 自定义Gallery

MainActivity

package org.wp.activity;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class MainActivity extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		CoverFlow coverFlow = new CoverFlow(this);
		ImageAdapter imageAdapter = new ImageAdapter(this);
		imageAdapter.createReflectedImages();
		coverFlow.setAdapter(imageAdapter);

		coverFlow.setSpacing(-(int) convertDip2Pixel(this, 40));
		coverFlow.setSelection(2, true);
		coverFlow.setAnimationDuration(1000);
		coverFlow.setBackgroundColor(Color.WHITE);

		setContentView(coverFlow);
	}

	public class ImageAdapter extends BaseAdapter {
		private Integer[] mImageIds = { R.drawable.images1, R.drawable.images2,
				R.drawable.images3, R.drawable.images4, R.drawable.images5,
				R.drawable.images6, R.drawable.images7, R.drawable.images8,
				R.drawable.images9, R.drawable.images10 };

		private Context mContext;
		private ImageView[] mImages;

		public ImageAdapter(Context c) {
			mContext = c;
			mImages = new ImageView[mImageIds.length];
		}

		@Override
		public int getCount() {
			return Integer.MAX_VALUE;
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			return mImages[position % mImages.length];
		}

		public boolean createReflectedImages() {
			final int reflectionGap = 4;

			int index = 0;

			for (int imageId : mImageIds) {
				Bitmap originalBitmap = BitmapFactory.decodeStream(mContext
						.getResources().openRawResource(imageId));
				int width = originalBitmap.getWidth();
				int height = originalBitmap.getHeight();

				Matrix matrix = new Matrix();
				matrix.preScale(1, -1);

				Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap,
						0, height * 7 / 8, width, height / 8, matrix, false);

				Bitmap withReflectionBitmap = Bitmap.createBitmap(width,
								(height + height / 8 + reflectionGap), Config.ARGB_8888);

				Canvas canvas = new Canvas(withReflectionBitmap);
				canvas.drawBitmap(originalBitmap, 0, 0, null);

				Paint defaultPaint = new Paint();
				canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);

				canvas.drawBitmap(reflectionBitmap, 0, height + reflectionGap, null);

				Paint paint = new Paint();
				LinearGradient shader = new LinearGradient(0, originalBitmap.getHeight(), 
						0, withReflectionBitmap.getHeight(), 0x70ffffff, 0x00ffffff, 
						TileMode.MIRROR);
				paint.setShader(shader);
				paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

				canvas.drawRect(0, height, width, withReflectionBitmap.getHeight(), paint);

				ImageView imageView = new ImageView(mContext);
				imageView.setImageBitmap(withReflectionBitmap);
				imageView.setLayoutParams(new CoverFlow.LayoutParams(
						(int) convertDip2Pixel(mContext, 120),
						(int) convertDip2Pixel(mContext, 300)));
				imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
				// 消除图片移动过程中的锯齿
				BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
				drawable.setAntiAlias(true);

				mImages[index++] = imageView;
			}
			return true;
		}
	}

	public float convertDip2Pixel(Context context, int dip) {
		final float scale = context.getResources().getDisplayMetrics().density;
		float pixel = (int) (dip * scale + 0.5f);
		return pixel;
	}
}

 

CoverFlow

package org.wp.activity;

import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;

/**
 * protected void setStaticTransformationsEnabled (boolean enabled)
 * 
 * When this property is set to true, this ViewGroup supports static
 * transformations on children;
 * 
 * this causes getChildStaticTransformation(View, android.view.animation.Transformation) 
 * to be invoked when a child is drawn.
 * 
 * Any subclass overriding getChildStaticTransformation(View,
 * android.view.animation.Transformation) should set this property to true.
 * 
 * (Gallery ==> AbsSpinner ==> AdapterView<T extends Adapter> ==> ViewGroup)
 */
public class CoverFlow extends Gallery {
	/** 视角 **/
	private Camera mCamera = new Camera();
	/** Child ImageView 最大的旋转角度 **/
	private int mMaxRotationAngle = 45;
	/** Center Child Z轴最大缩放距离 **/
	private int mMaxZoom = -120;
	/** Coverflow 的中心位置 **/
	private int mCoverflowCenter;
	/** 反转变量 **/
	private int lastPosition = 0;

	public CoverFlow(Context context) {
		super(context);
		this.setStaticTransformationsEnabled(true);
	}

	public CoverFlow(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.setStaticTransformationsEnabled(true);
	}

	public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.setStaticTransformationsEnabled(true);
	}

	public int getmMaxRotationAngle() {
		return mMaxRotationAngle;
	}

	public void setmMaxRotationAngle(int mMaxRotationAngle) {
		this.mMaxRotationAngle = mMaxRotationAngle;
	}

	public int getmMaxZoom() {
		return mMaxZoom;
	}

	public void setmMaxZoom(int mMaxZoom) {
		this.mMaxZoom = mMaxZoom;
	}

	/** 获得CoverFlow的中心点 **/
	private int getCenterOfCoverflow() {
		return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
				+ getPaddingLeft();
	}

	/** 获得指定View的中心点 **/
	private int getCenterOfView(View view) {
		return view.getLeft() + view.getWidth() / 2;
	}

	/**
	 * This method is called every time the widget changes size 
	 * e.g. when we change the orientation of the phone from portrait to landscape. 
	 * In the onSizeChanged method we just get the centre position 
	 * of the coverflow widget.
	 */
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		mCoverflowCenter = getCenterOfCoverflow();
		super.onSizeChanged(w, h, oldw, oldh);
	}
	
	@Override
	protected int getChildDrawingOrder(int childCount, int i) {
		if (i == 0) lastPosition = 0;

		int centerPosition = getSelectedItemPosition()
				- getFirstVisiblePosition();

		// 当索引的位置是最后一个,返回中心点的child索引
		// 当索引的位置大于中心点child的索引,从右往左
		// 剩余的按正常顺序
		if (i == (childCount - 1)) {
			return centerPosition;
		} else if (i >= centerPosition) {
			lastPosition++;
			return childCount - lastPosition;
		} else {
			return i;
		}

	}

	@Override
	protected boolean getChildStaticTransformation(View child, Transformation t) {
		final int childCenter = getCenterOfView(child);
		final int childWidth = child.getWidth();
		int rotationAngle = 0;

		t.clear();
		// Indicates a transformation that applies a matrix only (alpha = 1.)
		t.setTransformationType(Transformation.TYPE_MATRIX);

		// 如果图片移动到中心点
		if (childCenter == mCoverflowCenter) {
			transformImageBitmap((ImageView) child, t, 0);
		} else {
			rotationAngle = (int) (((float) (mCoverflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
			// 最大旋转角度不超过mMaxRotationAngle
			if (Math.abs(rotationAngle) > mMaxRotationAngle) {
				rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle;
			}
			transformImageBitmap((ImageView) child, t, rotationAngle);
		}

		return true;
	}

	private void transformImageBitmap(ImageView child, Transformation t,
			int rotationAngle) {
		mCamera.save();
		final Matrix imageMatrix = t.getMatrix();
		final int imageWidth = child.getLayoutParams().width;
		final int imageHeight = child.getLayoutParams().height;
		final int rotation = Math.abs(rotationAngle);

		// 默认的缩小值
		mCamera.translate(0.0f, 0.0f, 100.0f);

		if (rotation < mMaxRotationAngle) {
			// 不断的放大
			float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
			mCamera.translate(0.0f, 0.0f, zoomAmount);
		}

		mCamera.rotateY(rotationAngle);
		mCamera.getMatrix(imageMatrix);

		imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
		imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));

		mCamera.restore();
	}
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值