Динамически расположить кнопки по кругу
Я все еще новичок в 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 ответов
Я думаю, что нашел решение, которое я пытался достичь.
Я создаю свой собственный подкласс представления 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 чувствует (и, скорее всего, ошибается). Есть ли лучший способ сделать это?
может быть полезен следующий лицензионный проект Apache 2.0:https://github.com/dmitry-zaitsev/CircleLayout
вместо абсолютного макета вы можете использовать RelativeLayout и дочерний вид, установите верхнее и левое поля. Что-то вроде этого:--2-->
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;