在android中以圆形路径移动图像

 RebeccaLd 发布于 2023-02-13 20:00

我有一个图像,我想在onClick()没有动画的按钮的圆形路径事件中移动它,

我不知道怎么做..有什么帮助?


这是我的主要课程

public class MainActivity extends Activity {
MyAnimation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    animation =new MyAnimation ();

}

我正在使用你给出的代码

public class MyAnimation extends Animation {
float cx,cy,prevX,prevY,r;

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    super.applyTransformation(interpolatedTime, t);

    float angle = (float) (interpolatedTime * 2 * Math.PI);
    // r = radius, cx and cy = center point, a = angle (radians)
    float x = (float) (cx + r * Math.cos(angle)) ; 
    float y = (float) (cy + r * Math.sin(angle));

    float dx = prevX - x;
    float dy = prevY - y;

    prevX = x;
    prevY = y;

    t.getMatrix().setTranslate(dx, dy);
}

}

这是我想要以圆形移动的xml图像.


Jeffrey Klar.. 26

我认为你有两个选择:要么你创建一个自定义动画,要么你创建你的ImageView,然后使用一个表面自己沿着路径绘制它.

第一个选项更容易,并且可能会给出更好的结果,因为在动画类中,时间是由你处理的Interpolators(线性时间,快速启动,结束正常等).我强烈建议你编写自定义动画,因为我不明白为什么你不想使用Animation类(动画图像正是你想要的).

编辑:我花了一些时间并实现了以下内容.它并不是一尘不染,而是以圆形路径为图像制作动画.

活动:

public class MainActivity extends Activity {

    private ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = (ImageView) findViewById(R.id.image);

        image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Animation anim = new MyAnimation(image, 100);
                anim.setDuration(3000);
                image.startAnimation(anim);
            }
        });
    }

}

动画类:

public class MyAnimation extends Animation {

    private View view;
    private float cx, cy;           // center x,y position of circular path
    private float prevX, prevY;     // previous x,y position of image during animation
    private float r;                // radius of circle
    private float prevDx, prevDy;


    /**
     * @param view - View that will be animated
     * @param r - radius of circular path
     */
    public MyAnimation(View view, float r){
        this.view = view;
        this.r = r;
    }

    @Override
    public boolean willChangeBounds() {
        return true;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        // calculate position of image center
        int cxImage = width / 2;
        int cyImage = height / 2;
        cx = view.getLeft() + cxImage;
        cy = view.getTop() + cyImage;

        // set previous position to center
        prevX = cx;
        prevY = cy;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        if(interpolatedTime == 0){
            t.getMatrix().setTranslate(prevDx, prevDy);
            return;
        }

        float angleDeg = (interpolatedTime * 360f + 90) % 360;
        float angleRad = (float) Math.toRadians(angleDeg);

        // r = radius, cx and cy = center point, a = angle (radians)
        float x = (float) (cx + r * Math.cos(angleRad));
        float y = (float) (cy + r * Math.sin(angleRad));


        float dx = prevX - x;
        float dy = prevY - y;

        prevX = x;
        prevY = y;

        prevDx = dx;
        prevDy = dy;


        t.getMatrix().setTranslate(dx, dy);
    }
}

XML布局:




    


你可能需要在这里和那里调整它以获得你想要的东西,但这可以作为基础.

1 个回答
  • 我认为你有两个选择:要么你创建一个自定义动画,要么你创建你的ImageView,然后使用一个表面自己沿着路径绘制它.

    第一个选项更容易,并且可能会给出更好的结果,因为在动画类中,时间是由你处理的Interpolators(线性时间,快速启动,结束正常等).我强烈建议你编写自定义动画,因为我不明白为什么你不想使用Animation类(动画图像正是你想要的).

    编辑:我花了一些时间并实现了以下内容.它并不是一尘不染,而是以圆形路径为图像制作动画.

    活动:

    public class MainActivity extends Activity {
    
        private ImageView image;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            image = (ImageView) findViewById(R.id.image);
    
            image.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Animation anim = new MyAnimation(image, 100);
                    anim.setDuration(3000);
                    image.startAnimation(anim);
                }
            });
        }
    
    }
    

    动画类:

    public class MyAnimation extends Animation {
    
        private View view;
        private float cx, cy;           // center x,y position of circular path
        private float prevX, prevY;     // previous x,y position of image during animation
        private float r;                // radius of circle
        private float prevDx, prevDy;
    
    
        /**
         * @param view - View that will be animated
         * @param r - radius of circular path
         */
        public MyAnimation(View view, float r){
            this.view = view;
            this.r = r;
        }
    
        @Override
        public boolean willChangeBounds() {
            return true;
        }
    
        @Override
        public void initialize(int width, int height, int parentWidth, int parentHeight) {
            // calculate position of image center
            int cxImage = width / 2;
            int cyImage = height / 2;
            cx = view.getLeft() + cxImage;
            cy = view.getTop() + cyImage;
    
            // set previous position to center
            prevX = cx;
            prevY = cy;
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if(interpolatedTime == 0){
                t.getMatrix().setTranslate(prevDx, prevDy);
                return;
            }
    
            float angleDeg = (interpolatedTime * 360f + 90) % 360;
            float angleRad = (float) Math.toRadians(angleDeg);
    
            // r = radius, cx and cy = center point, a = angle (radians)
            float x = (float) (cx + r * Math.cos(angleRad));
            float y = (float) (cy + r * Math.sin(angleRad));
    
    
            float dx = prevX - x;
            float dy = prevY - y;
    
            prevX = x;
            prevY = y;
    
            prevDx = dx;
            prevDy = dy;
    
    
            t.getMatrix().setTranslate(dx, dy);
        }
    }
    

    XML布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_
            android:layout_>
    
        <ImageView
            android:id="@+id/image"
            android:layout_
            android:layout_
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:src="@drawable/ic_launcher" />
    
    </RelativeLayout>
    

    你可能需要在这里和那里调整它以获得你想要的东西,但这可以作为基础.

    2023-02-13 20:04 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有