Пользовательский объект нажмите кнопку в Android - PullRequest
6 голосов
/ 03 марта 2012

Я создал собственный вид в Android для отображения мяча на экране. Теперь я хочу, чтобы, касаясь этого шара, он должен взорваться в четырех частях, и каждая часть должна двигаться в четырех разных направлениях, то есть вверх, вниз, влево, вправо. Я знаю, что мне нужно настроить сенсорный приемник для определения касания по мячу, но как создать эффект взрыва? Эта проблема теперь решена . Я показываю несколько шариков на экране, чтобы пользователь мог щелкнуть по ним и взорвать их.

Вот мой пользовательский вид:

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 со схожими свойствами, за исключением того, что это направление и метод разнесения, чтобы переместить его в направлении, и флаг анимации, чтобы остановить его движение.

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

Мой макет xml выглядит следующим образом:

<?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" />

Я добавляю BallView и SmallBall в класс действий следующим образом:

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

Я добавляю несколько BallView и их относительный массив SmallBall в разных позициях. Теперь, что происходит независимо от того, где я нажимаю на последний добавленный экран, BallView начинает взрываться. После этого второго последнего и так далее. Итак, вот 2 вопроса:

  1. Почему вызывается событие onClick / onTouch, независимо от того, где я нажимаю на экран? Он должен вызывать событие слушателя только когда я нажимаю на конкретный BallView.
  2. А во-вторых, почему BallView начинает взрываться в обратном порядке, как они добавляются в макет?

Мой класс слушателя:

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

Я обрезал код из-за рассматриваемого ограничения символов.

Ответы [ 3 ]

1 голос
/ 09 марта 2012

ОК, проблема заключается в создании BallView и SmalBall как View объектов. Я думаю, что могу полностью объяснить это достаточно хорошо, так что терпите меня:

Хорошее место для начала - слоеный пирог. Подумайте о том, чтобы стоять на кухне и готовить торт так: добавляйте по одному слою за раз. Сначала слой шоколада, затем слой ванили, а затем еще один слой шоколада. Звучит неплохо? Хорошо.

Итак, на Canvas нарисовано много кругов, и отдельно Ball объекты добавляются как View s. Обратите внимание, что Canvas просто представляет прямоугольник, с которым пользователь может взаимодействовать, и связан с View - FrameLayout в вашем коде. По сути, Canvas полностью заполняет FrameLayout. В вашем приложении Canvas - это нижний слой торта, заполняющий ширину и высоту ContentView (или кастрюли).

Каждый вызов m.addView(View v), по сути, помещает новый View v поверх любого количества View объектов, уже содержащихся в m. С точки зрения торта, каждый вызов addView добавляет еще один слой к нашему слою.

В вашем проекте вы хотите добавить слой к торту, но не заполнить всю кастрюлю. Вы хотите положить пару клубник сверху, вы не хотите полный слой клубники.

Итак, по умолчанию ваши BallView объекты занимают весь экран. Каждый накапливается поверх следующего, заполняя весь холст. Когда вы нажимаете, он удаляет последний - потому что последний находится сверху, и занимает ширину и высоту всего холста - и на самом деле это шар only , который пользователь может возможно нажмите.

Таким образом, вы должны указать, что ваши BallView View объекты имеют тот же размер, что и круг, который вы рисуете на объекте Canvas.

Итак, здесь есть пара проблем:

Вы можете сделать абсолютное позиционирование только с RelativeLayout. Если вы хотите, чтобы BallView, который пользователь мог щелкнуть, находился сверху круга, нарисованного на холсте, вам нужен способ сообщить BallView, где он находится, и динамически изменить это положение. В настоящее время вы используете FrameLayout, что необходимо для Canvas - поэтому в вашем XML добавьте полный экран <RelativeLayout>. А затем, в своем коде, вместо этого добавьте BallView объекты к этому RelativeLayout.

и, наконец,

иди сюда:

Установить абсолютную позицию вида

Удачи!

1 голос
/ 03 марта 2012

Не думаю, что вам нужно жестко закодировать все это в канве. Вы можете позвонить ball.setVisibility(View.GONE) в Touch Listener и показать 4 дополнительных шара, используя smallBall.setVisibility(View.Visible) для каждого маленького шара. Таким образом, вы сможете скрыть большой шар и показать маленькие шарики. Теперь для эффекта движения в каждом smallBall может быть метод, в котором необходимо передать направление, и вы можете вызывать его следующим образом smallBall.explode (direction) Реализация метода может быть

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

Метод разнесения начнет изменять их координаты x и y в зависимости от пройденного направления. Я надеюсь, что это даст вам подсказку о том, как это реализовать.

0 голосов
/ 05 марта 2012

Это все происходит, потому что вы не указываете LayoutParameters объекта Ball.Здесь происходит то, что когда вы добавляете объект Ball в Layout, он занимает пространство всего макета, и поэтому он реагирует на нажатие в любом месте экрана.

Теперь для второго вопроса причина та же.Предположим, положение тарелок, оно всегда выскакивает в LIFO манере.Здесь все объекты Ball покрывают весь экран, поэтому рассматривайте их как пластины, так что вы делаете, что ставите пластины поверх друг друга.И именно поэтому он реагирует на метод onClick с последним последним мячом, а затем вторым последним и т. Д.

Таким образом, обе ваши проблемы будут решены после установки правильных параметров макета для объектов Ball.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...