Динамически расположите кнопки вокруг круга - PullRequest
12 голосов
/ 21 февраля 2012

Я все еще новичок в Android, поэтому я не совсем знаком со всеми компонентами представления. Я борюсь с динамическим выравниванием кнопок по кругу.

То, чего я пытаюсь добиться, это добавить n кнопок (n может измениться во время создания) к виду, который выглядит как прикрепленное изображение:

Я бы хотел избежать использования absoluteLayout (но я открыт для предложений, если это единственный способ решить эту проблему). Я уже придумал расчет для x / y позиций для кнопок (пока игнорируем размер кнопки):

int iNumberOfButtons = 10;
double dIncrease = Math.PI * 2 / iNumberOfButtons,
    dAngle = 0,
        x = 0,
        y = 0;

  for( int i = 0; i < iNumberOfButtons; i++ )
  {
    x = 100 * Math.cos( dAngle ) + 200;
    y = 100 * Math.sin( dAngle ) + 200;
    dAngle += dIncrease;
    // get button and set position?
  }

Я думал об использовании этого кода из пользовательского представления, но из того, что я видел, представление должно быть разделено на подклассы из ViewGroup, чтобы иметь метод addView, а затем, похоже, только absoluteLayout позволяет устанавливать позиции x, y ... Я не знаю, как реализовать эту функцию.

Я мог бы добавить некоторые анимации к этому представлению позже, поэтому использование SurfaceView может быть полезным, если это возможно, но это не является обязательным требованием.

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Мне кажется, я нашел решение, которое пытался достичь.

Я создаю свое собственное представление подклассов RelativeLayout. В onCreate () я установил

setWillNotDraw(false);

чтобы вызывать onDraw (). Затем я продолжаю в onDraw ():

int iHeight = getHeight();
int iWidth = getWidth();
int iNumberOfButtons = 10;
double dIncrease = Math.PI * 2 / iNumberOfButtons,
       dAngle = 0,
       x = 0,
       y = 0;

  for( int i = 0; i < iNumberOfButtons; i++ )
  {
    x = 200 * Math.cos( dAngle ) + iWidth/2;
    y = 200 * Math.sin( dAngle ) + iHeight/2;
    dAngle += dIncrease;
    Button xButton = new Button(m_xContext);
    xButton.setAdjustViewBounds(true);
    xButton.setBackgroundResource(R.drawable.some_image);
    LayoutParams xParams = (RelativeLayout.LayoutParams)xButton.getLayoutParams();
    if( xParams == null )
    {
      xParams = new RelativeLayout.LayoutParams( xButton.getBackground().getIntrinsicWidth(), xButton.getBackground().getIntrinsicHeight() );
    }
    xParams.leftMargin = (int)x - ( xButton.getBackground().getIntrinsicWidth() / 2 ) ;
    xParams.topMargin =  (int)y - ( xButton.getBackground().getIntrinsicHeight() / 2 );
    addView( xButton, xParams );
  }

Это дает мне желаемый результат, однако инициализация LayoutParams кажется (и, скорее всего, ошибочной) неправильной. Есть ли лучший способ сделать это?

2 голосов
/ 08 августа 2013

Может пригодиться следующий Лицензионный проект Apache 2.0: https://github.com/dmitry-zaitsev/CircleLayout

0 голосов
/ 21 февраля 2012

Вместо абсолютного макета вы можете использовать RelativeLayout, а для дочернего представления установить верхнее и левое поля.Как то так:

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...