I'm trying to do a shared element transition between two activities.
The first activity has a circle imageview and the second activity has a rectangular imageview. I just want the circle to transition from the first activity to the second activity where it becomes a square and back to the circle when I press back.
I find that the transition is not so neat - in the animation below, you can see that the rectangular imageview seem to reduce in size until it matches the size of the circle. The square imageview appears for a split second and and then the circle appears. I want to get rid of the square imageview so that the circle becomes the end point of the transition.
I have create a small test repo that you can download here: https://github.com/Winghin2517/TransitionTest
The code for my first activity - the imageview sits within the MainFragment
of my first activity:
public class MainFragment extends android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view, container,false);
final ImageView dot = (ImageView) view.findViewById(R.id.image_circle);
Picasso.with(getContext()).load(R.drawable.snow).transform(new PureCircleTransformation()).into(dot);
dot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(getContext(), SecondActivity.class);
View sharedView = dot;
String transitionName = getString(R.string.blue_name);
ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), sharedView, transitionName);
startActivity(i, transitionActivityOptions.toBundle());
}
});
return view;
}
}
This is my second activity which contains the rectangular imageview:
public class SecondActivity extends AppCompatActivity {
ImageView backdrop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
backdrop = (ImageView) findViewById(R.id.picture);
backdrop.setBackground(ContextCompat.getDrawable(this, R.drawable.snow));
}
@Override
public void onBackPressed() {
supportFinishAfterTransition();
super.onBackPressed();
}
}
This is the PureCircleTransformation class that I pass into Picasso to generate the circle:
package test.com.transitiontest;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;
public class PureCircleTransformation implements Transformation {
private static final int STROKE_WIDTH = 6;
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint avatarPaint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
avatarPaint.setShader(shader);
float r = size / 2f;
canvas.drawCircle(r, r, r, avatarPaint);
squaredBitmap.recycle();
return bitmap;
}
@Override
public String key() {
return "circleTransformation()";
}
}
I do understand that in my first activity, the circle is just 'cut' out by applying the Picasso transformation class and that the imageview is just a square layout cut out so that it appears as a circle. Maybe this is the reason why the animation looks like this as I'm transitioning from a rectangular to a square, but I really want the the transition to go from the rectangular to a circle.
I think there is a way to do this. In the whatsapp app, I can see the effect but I just cannot seem to figure out how they managed to do it - If you click on the profile picture of your friends on whatsapp, the app expands the circle imageview to a square. Clicking back will return the square to the circle.