2012-02-20 9 views
10

Todavía soy nuevo en Android, así que no estoy totalmente familiarizado con todos los componentes de vista. Estoy luchando con la alineación de botones dinámicamente alrededor de un círculo.Organizar dinámicamente Botones alrededor de un círculo

Lo que estoy tratando de lograr es añadir botones de n (n puede cambiar en tiempo de creación) a un aspecto que se parece a la imagen adjunta:

me gustaría evitar el uso de AbsoluteLayout (pero estoy abierto a sugerencias si esa es la única forma de resolverlo). ya me ocurrió con un cálculo de las posiciones x/Y para los botones (ignorando el tamaño del botón por ahora):

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? 
    } 

Pensé en usar este código desde el interior de una vista personalizada pero por lo que he visto la vista necesita ser subclasificada de ViewGroup para tener el método addView y, nuevamente, solo absoluteLayout parece permitir establecer las posiciones x, y ... No sé cómo implementar esta característica.

Podría agregar algunas animaciones a esa vista más adelante, por lo que usar SurfaceView podría ser bueno si es posible, pero no es un requisito.

Respuesta

3

Creo que encontré la solución que traté de lograr.

Creo mi propia vista subclasificando RelativeLayout. En onCreate() configuro

setWillNotDraw(false); 

para que se llame a onDraw(). que siguen a continuación, en 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); 
    } 

Esto me da el resultado deseado, sin embargo, la inicialización de la LayoutParams siente (y lo más probable es) mal. ¿Hay una mejor manera de hacer esto?

+0

Me encuentro con otro problema con este enfoque. onDraw() recibe una llamada repetida que no es lo que quiero cuando configuro botones allí. Supongo que probablemente podría rodear la inicialización con un if y un booleano, pero ¿hay una forma aceptada de implementar el comportamiento que quiero? (por ejemplo, iniciar mi vista personalizada con los botones, dispuestos en círculo desde el centro, sin recurrir a onDraw?) –

0

En lugar del diseño absoluto, puede usar RelativeLayout y, a la vista secundaria, establecer los márgenes superior e izquierdo. Algo como esto:

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams(); 
params.leftMargin = x; 
params.topMargin = y; 
+0

Esa es una buena idea, su sugerencia logra lo que estaba tratando de hacer. Subclassed RelativeLayout para esto y creo los botones en onCreate. Sus LayoutParams (y los de la vista en sí) son nulos en este momento. ¿Cuál es la forma preferida de inicializarlos? Otro requisito que olvidé mencionar es que el círculo debe colocarse en el centro de la vista. Pensé que sería fácil agregar los valores que obtengo de getHeight() y getWidth() para compensar las posiciones, pero ambos métodos devuelven 0 (al igual que getMeasuredWidth() y Height). ¿Hay alguna manera de arreglar eso? –

Cuestiones relacionadas