8

我正在开发一个 Android 应用程序,屏幕上有大约 6 个按钮(按下时会播放相应的视频)。这是应用程序的样机:

安卓应用

我希望按钮自动(随机)在屏幕上移动。他们应该独立地做这件事,这意味着他们可以在其他按钮的前面(或后面)——他们不需要相互碰撞或类似的东西。理想情况下,如果按钮实际上可以稍微移出画布会很好(如上图所示,按钮按钮位于操作栏后面),但这不是必需的。

我将如何让按钮像这样移动?

4

4 回答 4

6

最近,我一直在玩动画并尝试过类似的事情。这是课程。它基本上围绕父视图反弹(您可以更改数学以更进一步)

package com.example.animationtests.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

public class BouncingImageView extends ImageView {

    private View mParent;

    public BouncingImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public BouncingImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BouncingImageView(Context context) {
        super(context);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mParent = (View) getParent();
        getHandler().post(mRunnable);
    }

    @Override
    protected void onDetachedFromWindow() {
        getHandler().removeCallbacks(mRunnable);
        super.onDetachedFromWindow();
    }

    private final Runnable mRunnable = new Runnable() {
        private static final int DIRECTION_POSITIVE = 1;
        private static final int DIRECTION_NEGATIVE = -1;
        private static final int ANIMATION_STEPS = 1;
        private int mHorizontalDirection = DIRECTION_POSITIVE;
        private int mVerticalDirection = DIRECTION_NEGATIVE;

        public boolean mStarted = false;

        @Override
        public void run() {
            if (mParent == null) {
                return;
            }

            final float width = getMeasuredWidth();
            final float height = getMeasuredHeight();
            final float parentWidth = mParent.getMeasuredWidth();
            final float parentHeight = mParent.getMeasuredHeight();
            float x = getX();
            float y = getY();

            if (!mStarted) {
                /***
                 * Randomize initial position
                 */
                x = (float) Math.random() * (parentWidth - width);
                y = (float) Math.random() * (parentHeight - height);
                mHorizontalDirection = ((int) x % 2 == 0) ? DIRECTION_NEGATIVE : DIRECTION_POSITIVE;
                mVerticalDirection = ((int) y % 2 == 0) ? DIRECTION_NEGATIVE : DIRECTION_POSITIVE;
                mStarted = true;
            } else {
                if (mHorizontalDirection == DIRECTION_NEGATIVE) {
                    x -= ANIMATION_STEPS;
                } else {
                    x += ANIMATION_STEPS;
                }

                if (mVerticalDirection == DIRECTION_NEGATIVE) {
                    y -= ANIMATION_STEPS;
                } else {
                    y += ANIMATION_STEPS;
                }

                if (x - (width / 3) < 0) {
                    mHorizontalDirection = DIRECTION_POSITIVE;
                } else if (x + (width / 3) > (parentWidth - width)) {
                    mHorizontalDirection = DIRECTION_NEGATIVE;
                }

                if (y - (height / 3) < 0) {
                    mVerticalDirection = DIRECTION_POSITIVE;
                } else if (y + (width / 3) > (parentHeight - height)) {
                    mVerticalDirection = DIRECTION_NEGATIVE;
                }
            }

            setX(x);
            setY(y);

            getHandler().post(this);
        }
    };
}

用法:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".BouncingCircles" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true" >

        <com.example.animationtests.view.BouncingImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/light_dino" />

        <com.example.animationtests.view.BouncingImageView
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/light_dino" />

        <com.example.animationtests.view.BouncingImageView
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:src="@drawable/light_dino" />

        <com.example.animationtests.view.BouncingImageView
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:src="@drawable/light_dino" />
    </RelativeLayout>

</RelativeLayout>
于 2013-05-20T04:29:17.390 回答
5

我相信你需要使用ViewPropertyAnimator. 有关如何进一步发展的详细信息,请参阅此内容。您应该为视图提供的路径每次都应该是随机的。清楚地检查一点,以了解您必须注意的事项。

api指南的摘录:

例如,如果您为 a 设置动画button to move across the screen,则按钮绘制正确,但您可以单击按钮的实际位置不会改变,因此您必须实现自己的逻辑来处理此问题。

于 2013-05-20T04:14:34.847 回答
1

您可以在 RelativeLayout 中添加所有按钮并更改边距以定位按钮移动。
使用以下代码初始化位置:

    Button button = new Button();
    params = new RelativeLayout.LayoutParams(btnHeight,
                            btnWidth);
    params.leftMargin = leftMargin;
    params.topMargin = topMargin;
    rootview.addView(button, params);

要移动按钮,您可以使用TranslateAnimation

于 2013-05-20T04:18:00.603 回答
0

尝试这个

 ObjectAnimator mover = ObjectAnimator.ofFloat(aniView,
              "translationX", -500f, 0f);
          mover.setDuration(2000);

将此动画设置为您的按钮

于 2013-05-20T06:11:13.463 回答