2015-02-10 3 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 возможных положений»? –

+0

Ждите ответа. Я попробую. – GIGAMOLE

+1

У вас уже есть ширина и высота? не могли бы вы проверить, есть ли у вас там 0? Если это так, вам нужно добавить ViewTreeObserver.OnGlobalLayoutListener – SnyersK

ответ

0

У меня есть частичное решение для вас. Следующий код помещает кнопку в случайном месте BUT можно отложить экран. Вы должны быть в состоянии предотвратить это, играя со случайным генератором.

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

Теперь тебе придется быть более конкретным о аварии вы столкнулись.

EDIT: Также SnyersK прав, если вы просматриваете этот фрагмент кода до того, как элемент получил свои размеры, тогда вам нужно будет использовать ViewTreeObserver.

+0

Не могли бы вы дать мне точный код о том, как я могу использовать ViewTreeObserver? Я попытался использовать его, но это не помогло мне, я не знаком с тем, как работает ViewTreeObserver, поэтому я не могу это исправить. –

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); 
Смежные вопросы