圖片切換馬賽克動畫效果

1、創建初始化界面的定義類

public class AniPlayer {
	private RelativeLayout mBox = null;
	private Context mContext = null;
	public static final AniPlayer INST = new AniPlayer();
	private boolean isPlaying = false;
	int nextSwitchingStyle = 0;
	private int[] imageResources = {
			R.drawable.bbb, R.drawable.aaa
	};
	int nextImageResource = 0;
	private Handler handler = null;

	public void play(Context context,RelativeLayout box) {
		if (isPlaying) {
			return;
		}
		isPlaying = true;

		if (handler == null) {
			handler = new Handler();
		}
		mContext = context;
		mBox = box;
		playNext();
	}

	private void playNext() {
		nextSwitchingStyle++;
		if (nextSwitchingStyle >= 1) {
			nextSwitchingStyle = 0;
		}
		int imgRes = imageResources[nextImageResource];
		nextImageResource++;
		if (nextImageResource >= 2) {
			nextImageResource = 0;
		}

		SwitchableImageView imgView = new SwitchableImageView(mContext);
		imgView.setImageResource(imgRes);
		imgView.setScaleType(ScaleType.FIT_XY);
		LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		mBox.addView(imgView, lp);
		//imgView.setSwitchingPercent(0.0f);

		ObjectAnimator animator = ObjectAnimator.ofFloat(imgView, "switchingPercent",
				//0.001f, 0.4f, 0.5f, 1.0f);
				//0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f);
				1.0f);
		animator.setDuration(5000);
		animator.addListener(new Animator.AnimatorListener() {

			@Override
			public void onAnimationStart(Animator animation) {
			}

			@Override
			public void onAnimationRepeat(Animator animation) {
			}

			@Override
			public void onAnimationEnd(Animator animation) {
				clearViewsNotOnTop(mBox);
				handler.postDelayed(new Runnable() {
					@Override
					public void run() {
						playNext();
					}
				}, 2000);
			}

			@Override
			public void onAnimationCancel(Animator animation) {
				isPlaying = false;
			}
		});

		animator.start();
	}

	private void clearViewsNotOnTop(RelativeLayout parent) {
		int count = parent.getChildCount();
		if (count >= 2) {
			parent.removeViews(0, count - 1);
		}
	}
}

2、創建馬賽克工具類
public class SwitchableImageView extends ImageView {

	protected float switchingPercent = 0;

	public SwitchableImageView(Context context) {
		super(context);
	}

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

	public SwitchableImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public void setSwitchingPercent(float switchingPercent) {
		this.switchingPercent = switchingPercent;
		switchingPercentChanged();
	}

	protected void switchingPercentChanged() {
		SwitchingStyle.馬賽克.switchingPercentChanged(this);
		invalidate();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		SwitchingStyle.馬賽克.onDraw(this, canvas);
	}

	public static enum SwitchingStyle {
		馬賽克 {
			@Override
			protected void onDraw(SwitchableImageView thiz, Canvas canvas) {
				thiz.drawMosaic(canvas);
			}
			@Override
			protected void switchingPercentChanged(SwitchableImageView thiz) {
				if (thiz.switchingPercent < 1.0f) {
					thiz.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
				} else {
					thiz.setLayerType(View.LAYER_TYPE_NONE, null);
				}
			}
		};

		private static final Paint CLEARING_PAINT;
		private static final Paint NORMAL_PAINT;

		static {
			// 預先創建,儘量別在onDraw中創建東西
			CLEARING_PAINT = new Paint();
			CLEARING_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
			NORMAL_PAINT = new Paint();
			NORMAL_PAINT.setColor(Color.BLACK);
		}

		protected abstract void switchingPercentChanged(SwitchableImageView thiz);
		protected abstract void onDraw(SwitchableImageView thiz, Canvas canvas);
	}

	// 以下是馬賽克相關的東西
	private int mosaicSize = 0;
	private int xCount = 0, yCount = 0;
	private HashSet<Integer> revealedMosaicSet = new HashSet<Integer>();
	private Random random = new Random();

	private void initMosaicData(int width, int height) {
		int[] xyCount = { 0, 0 };
		mosaicSize = calcMosaicSize(width, height, xyCount);
		xCount = xyCount[0];
		yCount = xyCount[1];
		revealedMosaicSet.clear();
	}

	private static int calcMosaicSize(int width, int height, int[] outXyCount) {
		int dimen = width > height ? width : height;
		int result = dimen / 10;
		if (outXyCount != null && outXyCount.length >= 2) {
			outXyCount[0] = Math.round((float)width / (float)result);
			outXyCount[1] = Math.round((float)height / (float)result);
		}
		return result;
	}

	private void drawMosaic(Canvas canvas) {
		if (switchingPercent == 0.0f) {
			initMosaicData(canvas.getWidth(), canvas.getHeight());
		}
		int expectedRevealedCount = Math.round(xCount * yCount * switchingPercent);
		while (revealedMosaicSet.size() < expectedRevealedCount) {
			revealOneMosaic();
		}
		for (int y=0; y < yCount; y++) {
			for (int x=0; x < xCount; x++) {
				int w = mosaicSize;
				int h = mosaicSize;
				if (x == xCount - 1) {
					w = canvas.getWidth() - x * mosaicSize;
				}
				if (y == yCount - 1) {
					h = canvas.getHeight() - y * mosaicSize;
				}
				if (!revealedMosaicSet.contains(x + y * xCount)) {
					canvas.drawRect(x * mosaicSize, y * mosaicSize,
							x * mosaicSize + w, y * mosaicSize + h, SwitchingStyle.CLEARING_PAINT);
				}
			}
		}
	}

	private void revealOneMosaic() {
		int r = random.nextInt(xCount * yCount - revealedMosaicSet.size());
		for (int i=0; i < xCount * yCount; i++) {
			if (!revealedMosaicSet.contains(i)) {
				if (r == 0) {
					revealedMosaicSet.add(i);
					break;
				}
				r--;
			}
		}
	}
}
效果如圖:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章