当前位置: 代码迷 >> Android >> Android中animation坐标的有关问题
  详细解决方案

Android中animation坐标的有关问题

热度:66   发布时间:2016-05-01 18:02:20.0
Android中animation坐标的问题
各位好,小弟最近在学习Animation相关的东西,遇到了这样一个问题。

我新建了一个ViewGroup,里面放了数个image,想实现这样的功能,点一下ViewGroup,这数个image的位置就会发生变化。

变化主要有两种:
1.由环形排列变成普通的排列(每行4个);
2.由普通排列(每行4个)变成环形排列;

问题是,我的 onLayout方法里每个image的坐标和performAnimation方法里起始坐标/终止坐标是一样的,但在模拟器上实际显示起来的位置确是不同的,这是为什么呢?

主要代码如下:

Java code
@Override    protected void onLayout(boolean arg0, int l, int t, int r, int b)    {        Log.i(TAG, "OnLayout()");        if (isCircleLayout())        {            // circle layout 如果要排成环形            int childCount = getChildCount();            if (childCount < 1)            {                Log.w(TAG, "Not enough childs");                return;            }            final double angle = Math.PI / childCount * 2;            final int radius = 150;            for (int i = 0; i < childCount; i++)            {                View child = getChildAt(i);                int width = child.getMeasuredWidth();                int height = child.getMeasuredHeight();                int left = (int) (centerX + radius * Math.cos(angle * i) - width / 2);                int top = (int) (centerY + radius * Math.sin(angle * i) - height / 2);                int right = left + width;                int bottom = top + height;                Log.i(TAG, "Child " + i + " circle POINT{"); // 这里打了一下log看了下                Log.i(TAG, "left = " + left);                Log.i(TAG, "top = " + top);                Log.i(TAG, "right = " + right);                Log.i(TAG, "bottom = " + bottom);                Log.i(TAG, "}");                child.layout(left, top, right, bottom);            }        }        else        {            // square layout 如果是普通的排列(每行4个)            int childCount = getChildCount();            // int childEveryLine = (int) Math.sqrt(childCount);            int childEveryLine = 4;            Log.i(TAG, "We put >" + childEveryLine + "< childs every line");            if (childEveryLine == 0)            {                // no need to layout if there isn't any child                Log.w(TAG, "No childs found");                return;            }            // begin layout from left-top area            int startX = 0;            int startY = 0;            for (int i = 0; i < childCount; i++)            {                View child = getChildAt(i);                int width = child.getMeasuredWidth();                int height = child.getMeasuredHeight();                // put {childEveryLine} childs every line                if (i != 0 && i % childEveryLine == 0)                {                    startX = 0;                    startY += height;                }                child.layout(startX, startY, startX + width, startY + height);                Log.i(TAG, "Child " + i + " square POINT{");                Log.i(TAG, "left = " + startX);                Log.i(TAG, "top = " + startY);                Log.i(TAG, "right = " + (startX + width));                Log.i(TAG, "bottom = " + (startY + height));                Log.i(TAG, "}");                startX += width;            }        }    }    private Handler mHandler = new Handler();    public void performAnimation(boolean fromCircleToSquare)    {        Log.i(TAG, "PerformAnimation() {");        int childCount = getChildCount();        for (int i = 0; i < childCount; i++)        {            View child = getChildAt(i);            Log.i(TAG,                    "Location" + i + ": (" + child.getLeft() + ", "                            + child.getTop() + ")");            final double radius = 150; //排列成半径是150的圆,和上面的半径是一样一样的            final double angle = Math.PI / childCount * 2;            final int width = child.getMeasuredWidth();            final int height = child.getMeasuredHeight();            final int childEveryLine = 4;            AnimationRunnable mRunnable = null;            if (fromCircleToSquare)            {                /* from circle to square */                // make translate animation                int fromX = (int) (centerX + radius * Math.cos(angle * i) - width / 2);                int fromY = (int) (centerY + radius * Math.sin(angle * i) - height / 2);                int toX = (i % childEveryLine) * width;                int toY = (int) (i / childEveryLine) * height;                // make rotate animation                int fromDegrees = 360 / childCount * i;                int toDegrees = 0;                Log.i(TAG, "Child " + i + " {"); // 这里又打了下log,确认和上边的坐标是一样的                Log.i(TAG, "fromX = " + fromX);                Log.i(TAG, "fromY = " + fromY);                Log.i(TAG, "toX = " + toX);                Log.i(TAG, "toY = " + toY);                // Log.i(TAG, "fromDegrees = " + fromDegrees);                // Log.i(TAG, "toDegrees = " + toDegrees);                Log.i(TAG, "}");                mRunnable = new AnimationRunnable(child, fromX, fromY, toX,                        toY, fromDegrees, toDegrees, 5000);            }            else            {                /* from square to circle */                // make translate animation                int fromX = (i % childEveryLine) * width;                int fromY = (int) (i / childEveryLine) * height;                int toX = (int) (centerX + radius * Math.cos(angle * i) - width / 2);                int toY = (int) (centerY + radius * Math.sin(angle * i) - height / 2);                // make rotate animation                int fromDegrees = 0;                int toDegrees = 360 / childCount * i;                Log.i(TAG, "Child " + i + " {");                Log.i(TAG, "fromX = " + fromX);                Log.i(TAG, "fromY = " + fromY);                Log.i(TAG, "toX = " + toX);                Log.i(TAG, "toY = " + toY);                // Log.i(TAG, "fromDegrees = " + fromDegrees);                // Log.i(TAG, "toDegrees = " + toDegrees);                Log.i(TAG, "}");                mRunnable = new AnimationRunnable(child, fromX, fromY, toX,                        toY, fromDegrees, toDegrees, 5000);            }            if (mRunnable != null)            {                mHandler.post(mRunnable);            }        }        Log.i(TAG, "}");    }// 这个类是专门用来start animation的    class AnimationRunnable implements Runnable    {        private View mView;        private Animation mTrans;        private Animation mRotate;        private int mDuration;        public AnimationRunnable(View v, int fromX, int fromY, int toX,                int toY, int fromDegrees, int toDegrees, int duration)        {            mView = v;            mTrans = new TranslateAnimation(fromX, toX, fromY, toY);            // mRotate = new RotateAnimation(fromDegrees, toDegrees,            // Animation.RELATIVE_TO_SELF, 0.5F,            // Animation.RELATIVE_TO_SELF, 0.5F);            mDuration = duration;        }        @Override        public void run()        {            AnimationSet set = new AnimationSet(true);            set.setDuration(mDuration);            set.addAnimation(mTrans);            // set.addAnimation(mRotate);            mView.startAnimation(set);        }    };    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)    {        Log.i(TAG, "OnMeasure()");        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int childCount = getChildCount();        for (int i = 0; i < childCount; i++)        {            View child = getChildAt(i);            child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);        }        getCenter(); // 这人方法是用来得到屏幕中心点的    }
  相关解决方案