Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making buttons automatically move around the screen

Tags:

android

I'm working on an Android app where there are around 6 buttons on the screen (which play a corresponding video when pressed). Here's a mockup of what the application looks like:

Android App

I want the buttons to automatically (and randomly) move around the screen. They should do this independently, meaning they can go in front of (or behind) other buttons -- they don't need to bump off of each other or anything like that. Ideally, it would be good if the buttons could actually move off canvas slightly (as seen in the image above with the button button going behind the action bar), but this is not essential.

How would I go about making the buttons move around like this?

like image 943
Jordan Avatar asked May 20 '13 03:05

Jordan


2 Answers

Recently, I've been playing with animations and attempted the similar. Here is the class. It basically bounces around the parent view (which you can alter the math to go further)

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);
        }
    };
}

Usage:

<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>
like image 173
JRomero Avatar answered Oct 18 '22 21:10

JRomero


I believe you need to make use of ViewPropertyAnimator. Refer this for clear details on how you go further. The path you should give to a view should be random every time. Clearly check this too for the things you have to take care.

An excerpt from the api guides:

For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.

like image 5
Kanth Avatar answered Oct 18 '22 21:10

Kanth