Home » Android » android – Making buttons automatically move around the screen

android – Making buttons automatically move around the screen

Posted by: admin June 15, 2020 Leave a comment

Questions:

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?

How to&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>

Answer:

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.

Answer:

You could add all the buttons in a RelativeLayout and changing the margin to position the button move.
Initialize the position using code below:

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

To move the button, you could use TranslateAnimation

Answer:

Try this

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

set this animation to your button