如何将按钮的位置设置为屏幕上的随机点?

How to set a button's position to random points on screen?

我试图让一个按钮出现在屏幕上的随机位置,但由于某种原因它一直熄灭。我试图玩弄这些价值观,但它似乎并没有解决问题。我对此进行了很多搜索,甚至尝试关注 this,但没有成功。我在 Activity 的 onCreate 方法中使用以下代码块来实现它。

setContentView(R.layout.button_press);

        button = findViewById(R.id.my_button);
        button.setClickable(true);
        button.setOnClickListener(this);

        final Button button = (Button) findViewById(R.id.my_button);
        displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        loOPenArea = (RelativeLayout) findViewById(R.id.open_area_press);

        int leftMargin = new Random().nextInt(displaymetrics.widthPixels - 5*button.getWidth());
        int topMargin = new Random().nextInt(displaymetrics.heightPixels - 5*button.getHeight());

        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) button.getLayoutParams();
        p.setMargins(leftMargin, topMargin, 0, 0);

        button.setLayoutParams(p);

这里是布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".ButtonPress"
    android:background="#03B0F5"
    >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/open_area_press">

    <TextView
        android:id="@+id/button_press"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:background="#FFFFFF"
        android:text="@string/button_press"
        android:textSize="50sp"
        android:textColor="#03B0F5"

        />

    <androidx.appcompat.widget.AppCompatButton
        android:id = "@+id/my_button"
        android:layout_width = "150dp"
        android:layout_below="@+id/button_press"
        android:height="150dp"
        android:layout_height = "wrap_content"
        android:background="@drawable/rounded_corners"
        android:text = "Press Here"
        android:textColor="#03B0F5"
        android:textSize="20sp"
        />



</RelativeLayout>

</LinearLayout>

有时按钮根本不显示在屏幕上或在某些地方被挤压(见右下角):

让按钮出现在随机屏幕位置似乎是一项微不足道的任务,但我已经尝试解决它好几天并寻找解决方案,但 none 的解决方案似乎完美无缺。

如果您发布的代码在 onCreate() 中被调用,那么它被调用得太早了。您将不得不等待第一个布局来确定要移动的按钮的位置和大小。您可以使用 ViewTreeObserver.OnGlobalLayoutListener.

// Wait until the first layout to get buton size and placement to compute x/y placement range.
button.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        button.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        // Capture width and x/y placement ranges here
    }
}

第二个问题是保证金的计算。我假设您希望将按钮放置在从其初始位置到屏幕右侧和底部的任何位置,但不要太远以至于按钮被切断。计算看起来像这样。

// Button will have a horizontal margin from zero to the width of its parent less
// the width of the button less the initial left side of the button which is likely
// to be the initial margin.
buttonMaxXMargin = loOPenArea.getWidth() - button.getWidth() - button.getLeft();
// Similar for the vertical placement.
buttonMaxYMargin = loOPenArea.getHeight() - button.getHeight() - button.getTop();

此代码必须运行在全局布局侦听器运行之后。

关于按钮放置的控制视图是其父视图 open_area_press。该按钮将在其父级边界内从其初始 x/y 位置移动到最大位置,即父级宽度减去按钮宽度和父级高度减去按钮高度。

如果你将这些想法引入你的代码,你应该会有一个更快乐的结果。