开发者

Why are View animations sometimes clipped?

开发者 https://www.devze.com 2023-02-06 19:08 出处:网络
I have a FrameLayout containing a subclassed SurfaceView and an ImageVi开发者_如何学Cew.I want to do a TranslateAnimation on the ImageView.The only way I can make it work is to add a vacuous View to t

I have a FrameLayout containing a subclassed SurfaceView and an ImageVi开发者_如何学Cew. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消