I have a FrameLayout containing a subclassed SurfaceView and an ImageView. I want to do a TranslateAnimation on the ImageView. The only way I can make it work is to add a vacuous View to the FrameLayout. Otherwise, the ImageView gets clipped (to the bounds of the ImageView's position at the start of the animation) during the animation.
I'm curious as to why the empty sibling View allows the ImageView to animate correctly. The line that makes it work is marked with a comment in the code below.
public class Test5 extends Activity {
private static final String TAG = "Test5";
private MySurfaceView mMSV;
private ImageView mRectView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMSV = new MySurfaceView(this);
mRectView = new ImageView(this);
ShapeDrawable sd = new ShapeDrawable(new RectShape());
sd.getPaint().setColor(Color.RED);
sd.setIntrinsicWidth(300);
sd.setIntrinsicHeight(100);
mRectView.setImageDrawable(sd);
FrameLayout frameLayout = new FrameLayout(this);
frameLayout.addView(mMSV);
frameLayout.addView(mRectView, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT));
// I don't know why the following line prevents clipping during
// animation. It simply adds a vacuous View.
frameLayout.addView(new View(this));
setContentView(frameLayout);
} // onCreate
public class MySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas can = mMSV.getHolder().lockCanvas();
can.drawColor(Color.GRAY);
mMSV.getHolder().unlockCanvasAndPost(can);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
Log.v(TAG, String.format("ACTION_UP, w=%d, h=%d", mRectView
.getWidth(), mRectView.getHeight()));
Animation an = new TranslateAnimation(0f, 200f, 0f, 200f);
// Animation an = new RotateAnimation(0f, 90f);
an.setStartOffset(200);
an.setDuration(1000);
mRectView.startAnimation(an);
}
return true;
}
} // MySurfaceView
} // Test5
This is interesting... I guess that the size of the FrameLayout is changed when a vacuous view is added. Your frame layout does not fill the parent, I wonder if you change the layout params to fill parent, what would happen?
I simplified your code to this:
FrameLayout frameLayout = new FrameLayout(this);
frameLayout.addView(mMSV);
frameLayout.addView(mRectView, 50, 50);
frameLayout.addView(new View(this)); //expands frame layout
It seems that the FrameLayout size itself equal to the last added child view. If you set addView(new View(this)) before adding a rectangle then it reduces to 50 x 50 and animation is clipped. I assume that addView(new View(this)); expands FrameLayout to the full screen.
I don't know how you figured that out, but it seemed to work for me, too. I had just switched to using a SurfaceView, and noticed that the animations were getting clipped. Adding an empty View stopped the clipping.
the trick was setting setClipChildren to the layout that enclosed the view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With