Как предотвратить касание вида до тех пор, пока функция анимации не отключится? - PullRequest
0 голосов
/ 10 октября 2019

У меня есть собственный класс Java, который расширяет FrameLayout, который расположен поверх другого пользовательского родительского представления, расширяющего FrameLayout

У меня есть следующая функция, которая отклоняет представление с анимацией -

private void dismissCard(final View view, int xPos) {
    view.animate()
        .x(xPos)
        .y(0)
        .setInterpolator(new AccelerateInterpolator())
        .setDuration(DURATION)
        .setListener(new Animator.AnimatorListener() {
          @Override
          public void onAnimationStart(Animator animator) {
            setOnTouchListener(null);
          }
          @Override
          public void onAnimationEnd(Animator animator) {
            ViewGroup viewGroup = (ViewGroup) view.getParent();
            if (viewGroup != null) {
              viewGroup.removeView(view);
            }
          }
          @Override
          public void onAnimationCancel(Animator animator) {
          }
          @Override
          public void onAnimationRepeat(Animator animator) {
          }
        });
  }

Проблема в том, что я переопределил функцию onTouch() для перемещения функциональности представления, и для каждого прикосновения я получаю родителя представления, который является настраиваемым представлением, получая все дочерние элементы представления и определяя, какое представление являетсяна вершине. Так что моя проблема в том, что, будучи анимированным, анимированный вид по-прежнему остается сверху, поэтому его можно перемещать в другой раз, пока анимация не исчезнет и не будет вызван viewGroup.removeView(view).

Вот мой onTouch() реализация -

@Override
  public boolean onTouch(final View view, MotionEvent motionEvent) {
    TinderStackLayout tinderStackLayout = ((TinderStackLayout) view.getParent());
    TinderCardView topCard = (TinderCardView) tinderStackLayout.getChildAt(tinderStackLayout.getChildCount() - 1);
    if (topCard.equals(view)) {
      switch (motionEvent.getAction()) {
        case MotionEvent.ACTION_DOWN:
          oldX = motionEvent.getX();
          oldY = motionEvent.getY();
          // cancel any current animations
          view.clearAnimation();
          return true;
        case MotionEvent.ACTION_UP:
          if (isCardBeyondLeftBoundary(view)) {
            Log.d("top card dismissed - ", topCard.usernameTextView.getText().toString());
            onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
            dismissCard(view, -(screenWidth * 2));
          } else if (isCardBeyondRightBoundary(view)) {
            showLawyerContactDetailsFragment(topCard);
            onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
            resetCard(view);
          } else {
            onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
            resetCard(view);
          }
          return true;
        case MotionEvent.ACTION_MOVE:
          newX = motionEvent.getX();
          newY = motionEvent.getY();
          dX = newX - oldX;
          dY = newY - oldY;
          float posX = view.getX() + dX;
          onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
          // Set new position
          view.setX(view.getX() + dX);
          view.setY(view.getY() + dY);
          setCardRotation(view, view.getX());
          updateAlphaOfBadges(posX);
          return true;
        default:
          return super.onTouchEvent(motionEvent);
      }
    }
    return super.onTouchEvent(motionEvent);
  }

Чего мне не хватает, так это способа заблокировать сенсорную способность, пока dismissCard() анимирует. Как я могу реализовать такую ​​вещь?

1 Ответ

1 голос
/ 10 октября 2019

Объявите логическую переменную (isAnimating) в классе, который вы анимируете, и установите для него значение true в onAnimationStart и false в onAnimationEnd.

доступ к этой переменной в вашем onTouch

@Override
  public boolean onTouch(final View view, MotionEvent motionEvent) {
    TinderStackLayout tinderStackLayout = ((TinderStackLayout) view.getParent());
    TinderCardView topCard = (TinderCardView) tinderStackLayout.getChildAt(tinderStackLayout.getChildCount() - 1);
    if (topCard.equals(view)&& !isAnimating) { //access event's only if animation is ended.
      switch (motionEvent.getAction()) {
        case MotionEvent.ACTION_DOWN:
          oldX = motionEvent.getX();
          oldY = motionEvent.getY();
          // cancel any current animations
          view.clearAnimation();
          return true;
        case MotionEvent.ACTION_UP:
          if (isCardBeyondLeftBoundary(view)) {
            Log.d("top card dismissed - ", topCard.usernameTextView.getText().toString());
            onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
            dismissCard(view, -(screenWidth * 2));
          } else if (isCardBeyondRightBoundary(view)) {
            showLawyerContactDetailsFragment(topCard);
            onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
            resetCard(view);
          } else {
            onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
            resetCard(view);
          }
          return true;
        case MotionEvent.ACTION_MOVE:
          newX = motionEvent.getX();
          newY = motionEvent.getY();
          dX = newX - oldX;
          dY = newY - oldY;
          float posX = view.getX() + dX;
          onCardSwipedListener.send(new TopCardMovedEvent(-(screenWidth)));
          // Set new position
          view.setX(view.getX() + dX);
          view.setY(view.getY() + dY);
          setCardRotation(view, view.getX());
          updateAlphaOfBadges(posX);
          return true;
        default:
          return super.onTouchEvent(motionEvent);
      }
    }
    return super.onTouchEvent(motionEvent);
  }

PS - лучшее решение - вернуть false, когда isAnimating равно true. В моем приложении я переопределил касание отправки в родительском классе и не позволяю никаким событиям достигать родителя или любого из его дочерних классов. .

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
 if (isAnimationOnGoing) {
        return false
 }
 return super.dispatchTouchEvent(ev)
}
...