Setting a button's position to random points o

2019-05-15 22:37发布

问题:

Below, I've got both the Java and XML code, basically I'm trying to click a fixed button, and make the 2nd button jump around the screen at random points

XML Explanation: So, I've got a relative layout with two buttons... One of them is fixed at the bottom of the screen... and I want to set the other one's position randomly.

Screen opens, Click the fixed button... and the other button's position should change randomly.

Say I click the fixed button again and agin, the other button should jump around randomly.

<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=".Rrand" >

    <Button
        android:id="@+id/rbb1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Button" />

    <Button
        android:id="@+id/bss"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:onClick="aa"
        android:text="Button" />

</RelativeLayout>

JAVA Explanation And here I've got the OnClick function for the fixed button.

►b = The button that's supposed to jump around

First of all, we get the screen dimensions, and then using LayoutParams, set the buttons position using the random function.

   public void Clicky(View v) {
            b = (Button) findViewById(R.id.rbb1);

    ///Getting the Screen dimensions for API 1+

            LayoutParams params = (LayoutParams) b.getLayoutParams();
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);

    ///Setting the buttons paramaters, again for API 1+

            params.leftMargin = b.getWidth()
                    + new Random().nextInt(metrics.widthPixels - b.getWidth());
            params.topMargin = b.getHeight()
                    + new Random().nextInt(metrics.heightPixels - b.getHeight());
            b.setLayoutParams(params);

        }

Random Function for the X coordinate:

b.getWidth()+ new Random().nextInt(metrics.widthPixels - b.getWidth());

Minimum value = b.getWidth().

So, IN THEORY, the button should never ever even partially appear a little out the screen.

In the parameters for nextInt, I use [Screenwidth - Button Width] ... So, IN THEORY, it should never go out of the screen from the other side too...

Problem Yet it does. Approximately half the time, the button does not even appear on the screen... The problem has to be in the Random Function (I think so) ... I just want it to appear on random spots on the screen.

I reckon the problem is simply logical, because I have all the functions I need..

This didn't work ►Setting a Margin on the button and the Relative Layour. ►Removing all button dimension parameter from the random function.

That is, using:

new Random().nextInt(metrics.widthPixels)

So, what did I get wrong ?

回答1:

Since you add b.getWidth() to the random value, you have to change the random value to metrics.widthPixels - 2*b.getWidth(), because otherwize the offset could be metrics.widthPixels - b.getWidth() + b.getWidth which explains why it is out of border to the right and to the bottom sometimes. So it should look like this:

params.leftMargin = b.getWidth()
                + new Random().nextInt(metrics.widthPixels - 2*b.getWidth());
params.topMargin = b.getHeight()
                + new Random().nextInt(metrics.heightPixels - 3*b.getHeight());
b.setLayoutParams(params);

NOTE: In this version, the button will never touch the left edge or top edge of the screen.


If you want to the button also to (possibly) touch the upper and/or left border, don't add width/height to margin:

params.leftMargin = new Random().nextInt(metrics.widthPixels - b.getWidth());
params.topMargin = new Random().nextInt(metrics.heightPixels - 2*b.getHeight());
b.setLayoutParams(params);

Edit:
I changed the calculation of the top margin so the button woun't be at the same position as the fixed button.



回答2:

Here is the solution:

public class OpenArea extends Activity {

    private RelativeLayout loOPenArea;
    private ImageView imageView;
    private DisplayMetrics metrics;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_open);

        metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        loOPenArea = (RelativeLayout) findViewById(R.id.lo_open_area);
    }

    public void addView(View v) {
        imageView = new ImageView(this);
        imageView.setImageResource(R.mipmap.ic_launcher);
        loOPenArea.addView(imageView);

        int leftMargin = new Random().nextInt(metrics.widthPixels - imageView.getWidth());;
        int topMargin = new Random().nextInt(metrics.heightPixels - 2*imageView.getHeight());;

        setMargins(imageView, leftMargin, topMargin, 0, 0);
    }

    private void setMargins(View view, int left, int top, int right, int bottom) {
        if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
            p.setMargins(left, top, right, bottom);
            view.requestLayout();
        }
    }
}

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/lo_open_area"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_marginBottom="50dp">

    </RelativeLayout>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="-50dp"
        android:onClick="addView"
        android:text="+" />
</LinearLayout>