Reputation: 265
I'm trying to make an animation with only 2 images and using a mask. But I do not know how. I can not use animation-list. I need help to do so. Thank you.
The effect of the animation would look like this:
public void makeMaskImage(ImageView mImageView, int mContent) {
Bitmap original = BitmapFactory.decodeResource(getResources(), mContent);
Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask);
Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mCanvas.drawBitmap(original, 0, 0, null);
mCanvas.drawBitmap(mask, 0, 0, paint);
paint.setXfermode(null);
mImageView.setImageBitmap(result);
mImageView.setScaleType(ImageView.ScaleType.CENTER);
mImageView.setBackgroundResource(R.drawable.img_b);
}
animation
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:fillEnabled="true"
android:interpolator="@android:anim/linear_interpolator">
<translate
android:duration="3000"
android:fromXDelta="-100%p"
android:toXDelta="0%p" />
</set>
Upvotes: 2
Views: 3522
Reputation: 265
I modified the class of Nicolas Simon and code works perfectly
public class RevealView extends ImageView {
private Bitmap secondBitmap;
private float mAnimationPercentage;
private Path mPath;
private Paint mPaint;
public RevealView(Context context) {
super(context);
init();
}
public RevealView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RevealView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setPercentage(0);
mPaint = new Paint();
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
mPath = new Path();
}
public void setPercentage(int p) {
if(p > 100) {
p = 100;
}
mAnimationPercentage = p / 100f;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap mRegularBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
if (mRegularBitmap != null && secondBitmap != null) {
//First draw your regular image
canvas.drawBitmap(mRegularBitmap, 0, 0, null);
//Then clip the canvas depending on the animation percentage, using a Path
mPath.reset();
mPath.moveTo((float) canvas.getWidth() * mAnimationPercentage, 0.0f);
mPath.lineTo((float) canvas.getWidth() * mAnimationPercentage, canvas.getHeight());
mPath.lineTo(canvas.getWidth(), canvas.getHeight());
mPath.lineTo(canvas.getWidth(), 0.0f);
mPath.close();
canvas.drawPath(mPath, mPaint);
canvas.clipPath(mPath);
//Then draw the gray bitmap on top
canvas.drawBitmap(secondBitmap, 0.0f, 0.0f, null);
}
}
public void setSecondBitmap(Bitmap secondBitmap) {
this.secondBitmap = secondBitmap;
}
}
MainActivity
@Override
public void onResume() {
super.onResume();
revealView.setSecondBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.img_1));
percentage = 0;
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (percentage <= 100) {
revealView.setPercentage(percentage);
percentage++;
} else {
cancel();
}
}
});
}
}, 0, 120);
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.animation.RevealView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/img_2" />
</RelativeLayout>
Upvotes: 1
Reputation: 5287
I would create a custom View for that, to work with the onDraw
method, and especially the clip
function.
This class is working for me, but is left very opened to modifications on your side.
An implementation would be as follow :
public class RevealView extends View {
private Bitmap mRegularBitmap;
private Bitmap mGrayScaleBitmap;
private float mAnimationPercentage;
private Path mPath;
private Paint mPaint;
public RevealView(Context context) {
super(context);
init();
}
public RevealView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RevealView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mRegularBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sign_in_up_icon);
mGrayScaleBitmap = toGrayScale(mRegularBitmap);
mAnimationPercentage = 0.0f;
mPaint = new Paint();
mPath = new Path();
}
public void reset() {
mAnimationPercentage = 0.0f;
}
public void setPercentage(float p) {
mAnimationPercentage = p;
}
private Bitmap toGrayScale(Bitmap origin) {
int width, height;
height = origin.getHeight();
width = origin.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(origin, 0, 0, paint);
return (bmpGrayscale);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//First draw your regular image
canvas.drawBitmap(mRegularBitmap, 0, 0, null);
//Then clip the canvas depending on the animation percentage, using a Path
mPath.reset();
mPath.moveTo((float)canvas.getWidth() * mAnimationPercentage, 0.0f);
mPath.lineTo((float)canvas.getWidth() * mAnimationPercentage, canvas.getHeight());
mPath.lineTo(canvas.getWidth(), canvas.getHeight());
mPath.lineTo(canvas.getWidth(), 0.0f);
mPath.close();
canvas.drawPath(mPath, mPaint);
canvas.clipPath(mPath);
//Then draw the gray bitmap on top
canvas.drawBitmap(mGrayScaleBitmap, 0.0f, 0.0f, null);
}
Then define your own animation, and simply call
myRevealView.setPercentage(float);
Depending on the Thread you're calling it, then either use
myRevealView.invalidate()//main thread
or
myRevealView.postInvalidate()//background thread
Upvotes: 1