2012-03-03 10 views
6

He creado una vista personalizada en Android para mostrar la pelota en la pantalla. Ahora lo que quiero es que cuando toque esa bola, explote en cuatro partes y cada parte se mueva en cuatro direcciones diferentes, es decir, arriba, abajo, izquierda, derecha. Sé que tengo que configurar el oyente táctil para detectar el toque en la pelota, pero ¿cómo crear un efecto de explosión? Este problema ahora se resuelve. Estoy mostrando varias bolas en la pantalla para que el usuario pueda hacer clic y explotar.Problema de clic de objeto personalizado en android

Aquí está mi vista personalizada:

public class BallView extends View { 
    private float x; 
    private float y; 
    private final int r; 
    public BallView(Context context, float x1, float y1, int r) { 
     super(context); 
     this.x = x1; 
     this.y = y1; 
     this.r = r; 
    } 
    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawCircle(x, y, r, mPaint); 
    } 

} 

SmallBall con propiedades similares, excepto uno que es un método de dirección y explotar para moverlo en la dirección y animación de la bandera para detenerlo en movimiento.

private final int direction; 
private boolean anim; 

public void explode() { 
    // plus or minus x/y based on direction and stop animation if anim flag is false 
    invalidate(); 
} 

Mi xml distribución es la siguiente:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:id="@+id/main_view" 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:background="#FF66FF33" /> 

estoy añadiendo BALLView y SmallBall a la clase de actividad como sigue:

final FrameLayout mainFrameLayout = (FrameLayout) findViewById(R.id.main_frame_layout); 

SmallBall[] smallBalls = new SmallBall[4]; 
smallBalls[0] = new SmallBall(getApplicationContext(), 105, 100, 10, 1, false); 
smallBalls[0].setVisibility(View.GONE); 
mainFrameLayout .addView(smallBalls[0]); 
// create and add other 3 balls with different directions. 

BallView ball = new BallView(getApplicationContext(), 100, 100, 25, smallBalls); 
listener = new MyListener(ball); 
ball.setOnClickListener(listener); 

mainFrameLayout.addView(ball); 

estoy añadiendo BALLView múltiple y su relativa Arreglo de SmallBall en diferentes posiciones. Ahora lo que sucede, no importa dónde haga clic en la pantalla, BallView comienza a explotar por última vez. Después de esa segunda, y así sucesivamente. Así que aquí están 2 números:

  1. ¿Por qué llama al evento OnClick/onTouch sin importar dónde haga clic en la pantalla? Solo debería llamar al evento listener cuando hago clic en un BallView particular.
  2. Y en segundo lugar, ¿por qué BallView comienza a explotar de forma inversa a cómo se agregan al diseño?

Mi clase de escucha:

public void onClick(View v) { 
     BallView ballView = (BallView) v; 
     ballView.setVisibility(View.GONE); 
     //get small balls associated with this ball. 
     //loop through small ball and call their explode method. 
    } 

he recortado código debido a la limitación de caracteres en cuestión.

+0

¿Qué problema tienes al codificar el efecto de explosión? ¿Quieres la animación del movimiento de las piezas o los gráficos de explosión? Sería mejor que pudieras proporcionar una imagen o algo que quisieras lograr. – noob

+0

@Creator: Lo que quiero es que cuando alguien haga clic en cualquier bola, explote en cuatro bolas pequeñas y cada pared se mueva en una de las cuatro direcciones. No estoy seguro sobre qué usar para esto ya que soy nuevo en Android. Puede ser una animación de piezas explosionadas será una buena opción. –

+0

Verifique mi respuesta – noob

Respuesta

1

No creo que tenga que codificar todo esto en un lienzo. Puede llamar al ball.setVisibility(View.GONE) en el Touch Listener y mostrar 4 bolas extra usando smallBall.setVisibility(View.Visible) por cada bola pequeña. De esta forma serás capaz de esconder una pelota grande y puedes mostrar bolas pequeñas. Ahora, para el efecto de movimiento, puede haber un método en cada pequeña bola donde se necesita pasar la dirección y se puede llamar así smallBall.explode (dirección). La implementación del método podría ser

explode(int direction){//can be String 
    if(direction=NORTH) 
    y--; 
    //other condition checks 
} 

El método de explotar comenzará a cambiar sus coordenadas X e Y, en base a la dirección pasado. Espero que esto te dé una pista sobre cómo implementarlo.

+0

Gracias. Lo intentaré y le haré saber. –

+0

¿Cómo llamar a explotar repetidamente para hacer que se mueva SmallBall? También estoy agregando bolas a FrameLayout, ahora cómo puedo agregar Bolas pequeñas a ese diseño después de llamar a ball.setVisibility (View.GONE) ;. –

+0

Ponlo en el método onDraw() de la smallBall y, si hay una llamada invalidada(), la llamará automáticamente cada vez. Solo recuerda tener una bandera o condición booleana que active el explosivo() y lo detenga cuando lo desees. – noob

0

Todo esto sucede porque no está especificando el objeto LayoutParameters of Ball. Lo que ocurre aquí es que cuando agrega un objeto Ball a Layout, ocupa espacio de todo el diseño y es por eso que reacciona al hacer clic en cualquier lugar de la pantalla.

Ahora, para la segunda cuestión, la razón es la misma. Asuma la situación de las placas, siempre aparece de manera LIFO. Aquí todos los objetos de Ball cubren toda la pantalla, así que considérelos como platos, entonces lo que está haciendo es colocar los platos uno encima del otro. Y es por eso que reacciona al método onClick de la última bola primero y luego al último y así sucesivamente.

Por lo tanto, ambos problemas se resolverán después de configurar los parámetros de diseño adecuados para los objetos de bola.

+0

No entiendo tu punto. ¿Puedes mostrar algún código de ejemplo? –

+0

@mark ¿qué parte? –

1

Bien, el problema es durante la creación de BallView y SmalBall como objetos View. Creo que puedo explicarlo completamente bien, así que tengan paciencia conmigo:

Un buen lugar para comenzar es con un pastel en capas. Piensa en pararte en la cocina y hacer un pastel como este: agregar una capa a la vez. Primero, la capa de chocolate, y luego la capa de vainilla y luego otra capa de chocolate. ¿Suena bien? Bien.

Por lo tanto, hay muchos círculos dibujados en un Canvas y, por separado, los objetos Ball se agregan como View s. Tenga en cuenta que un lienzo simplemente representa un rectángulo con el que el usuario puede interactuar, y está asociado con un View - FrameLayout en su código. Para todos los efectos, el Canvas está llenando por completo el FrameLayout. En su aplicación, el Canvas es la capa inferior de la torta, rellenando tanto el ancho como la altura del ContentView (o bandeja).

Cada llamada a m.addView(View v) está poniendo en esencia un nuevo View v en la parte superior de View sin embargo, muchos objetos que ya están contenidos en m. En términos de pastel, cada llamada al addView agrega otra capa a nuestro pastel de capas.

En su proyecto, desea agregar una capa al pastel pero no llenar toda la sartén. Si quieres poner un par de fresas en la parte superior, no quieres una capa completa de fresa.

De manera predeterminada, sus objetos BallView ocupan toda la pantalla. Cada uno se acumula sobre el siguiente, llenando todo el lienzo. Cuando hace clic, borra la última, porque la última está en la parte superior y ocupa el ancho y la altura de todo el lienzo, y en realidad es la única bola que el usuario puede hacer clic en.

Así que tiene que decirle a su BallViewView que los objetos sean del mismo tamaño que el círculo que está dibujando en el objeto Canvas.

Por lo tanto, hay un par de problemas aquí:

sólo se puede hacer con un posicionamiento absoluto RelativeLayout. Si quiere que BallView el usuario puede hacer clic para estar en la parte superior del círculo que se dibuja en el lienzo, necesita una manera de decirle al BallView donde se encuentra, y cambiar esa posición de forma dinámica. Actualmente está utilizando un FrameLayout, que es necesario para el Canvas - por lo que en su XML, agregue una pantalla completa <RelativeLayout>. Y luego, en su código, agregue los objetos BallView a este RelativeLayout en su lugar.

y luego, por último:

entra aquí:

Set the absolute position of a view

Buena suerte!

+0

Thnaks. Establecer parámetros de diseño ayuda. Buena explicación. –

Cuestiones relacionadas