2015-02-10 77 views
2

我有一定数量的填充线性布局。我想要一个图像按钮随机放置在该线性布局内的任何位置,而不会超出布局范围。这里是我的XML代码:如何让ImageButton随机定位在线性布局中? (Android)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 
<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:textSize="45dp" 
    android:text="Text 1" 
    android:id="@+id/text1" /> 
<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:textSize="30dp" 
    android:text="Text 2" 
    android:id="@+id/text2" /> 
<LinearLayout 
    android:id="@+id/lay1" 
    android:layout_width="match_parent" 
    android:layout_height="450dp" 
    android:layout_margin="20dp"> 

<ImageButton 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:textSize="25dp" 
    android:src="@drawable/ib" 
    android:id="@+id/button1"/> 

</LinearLayout> 
</LinearLayout> 

我想要的ImageButton button1进行布局lay1内随意摆放。

我试着得到布局的宽度和高度,并将它们送入一个随机函数中,然后我用它来为图像按钮提供一个左边距和顶边距,但是当我这样做时,我的应用程序不断崩溃。以下是Java代码:

ImageButton b = (ImageButton) findViewById(R.id.button1); 
LinearLayout l = (LinearLayout) findViewById(R.id.lay1); 
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) b.getLayoutParams(); 
int width = l.getWidth(); 
int height= l.getHeight(); 
params.leftMargin = new Random().nextInt(width); 
params.topMargin = new Random().nextInt(height); 
b.setLayoutParams(params); 

上述方法不起作用,我的应用程序在我打开此活动时总是崩溃。有人可以帮我吗?

+0

你说的随机是什么意思?在“屏幕上的任何位置”是随机的还是随机的,如“在n个可能的位置之一中”是随机的? – 2015-02-10 13:18:53

+0

等待答案。我会试试看。 – GIGAMOLE 2015-02-10 13:24:53

+1

你已经有一个宽度和高度?你可以检查你是否在那里? 如果是这样,你需要添加一个ViewTreeObserver.OnGlobalLayoutListener – SnyersK 2015-02-10 13:24:54

回答

0

我有一个部分解决方案给你。 以下代码将按钮放置在随机位置但是它可以放在屏幕上。你应该可以通过随机生成器来防止这种情况。

public class MainActivity extends ActionBarActivity { 

int width, height; 
LinearLayout linearLayout; 
Button button; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    linearLayout = (LinearLayout) findViewById(R.id.ll); 
    linearLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 
      Log.v(getClass().getSimpleName(), "onGlobalLayout"); 
      width = linearLayout.getWidth(); 
      height = linearLayout.getHeight(); 

      placeButton(); 

      if (Build.VERSION.SDK_INT >= 16) { 
       linearLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      } else { 
       linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
      } 
     } 
    }); 

    button = (Button) findViewById(R.id.button); 
} 

private void placeButton() { 
    Log.v(getClass().getSimpleName(), "width: " + width + " Height: " + height); 
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) button.getLayoutParams(); 

    Random rand = new Random(); 

    params.leftMargin = rand.nextInt(width); 
    params.topMargin = rand.nextInt(height); 

    Log.v(getClass().getSimpleName(), "left: " + params.leftMargin + " top: " + params.topMargin); 
    button.setLayoutParams(params); 
    button.invalidate(); 
} 

}

你只是等待你的LinearLayout要绘制。然后你得到它的宽度和高度,并把按钮放在随机的地方。

注意 这将在您旋转屏幕时移动按钮。你可以只添加OnGlobalLayoutListener如果savedInstanceState == null

1

你的方法看起来不错,但你也必须考虑图像的大小。
所以我把这样的:

params.leftMargin = new Random().nextInt(width - b.getWidth()); 
params.topMargin = new Random().nextInt(height - b.getHeight()); 

现在你得要更具体的了解您遇到的崩溃。

编辑:另外SnyersK是正确的,如果你在元素得到他们的尺寸之前经历了那段代码,那么你将需要使用ViewTreeObserver。

+0

你能否告诉我如何使用ViewTreeObserver的确切代码?我试图使用它,但它并不适合我,我不熟悉ViewTreeObserver的工作方式,所以我不能真正解决这个问题。 – 2015-02-10 14:04:26

0

只是代替你的代码防止这种这种

ImageButton b = (ImageButton) findViewById(R.id.button1); 
LinearLayout l = (LinearLayout) findViewById(R.id.lay1); 
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)l.getLayoutParams(); 
int width = l.getWidth(); 
int height= l.getHeight(); 
params.leftMargin = new Random().nextInt(width); 
params.topMargin = new Random().nextInt(height); 
l.setLayoutParams(params);