FloatingActionButton 不会 return 到动画后的原始大小

FloatingActionButton does not return to original size after animation

我写了一个小的 STT 功能,有一个浮动按钮,点击后会跳动以通知应用程序正在侦听。到目前为止,这对于我的浮动按钮在某些情况下不会 return 到其原始大小的一个烦人的行为非常有效。

动画增大和减小按钮的大小,我猜它卡在增大状态,因此这种行为具有随机性。我只是不知道如何抓住它并将大小设置为原始大小。

我的按钮的动作侦听器:

 private View.OnTouchListener setVoiceButtonOnClick()
   {
      return new View.OnTouchListener()
      {
         @Override
         public boolean onTouch(View v, MotionEvent event)
         {
            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
               if(!voiceButton.isInitialized())
                  voiceButton.initAnimationValues();

               voiceButton.setPressed(true);
               listen();
            }
            return true;
         }
      };
   }

我的按钮扩展了 FloatingActionButton,并执行以下操作:

public class FloatingVoiceButton extends FloatingActionButton
{

   public static final float DEFAULT_ANIMATION_FACTOR = 1.2f;
   private boolean isInitialized = false;
   private int originalHeight;
   private int originalWidth;
   private boolean isAnimationRunning;

   private ObjectAnimator animator;


   public FloatingVoiceButton(Context context)
   {
      super(context);
   }

   public void initAnimationValues()
   {
      isInitialized = true;
      isAnimationRunning = false;
      originalHeight = getMeasuredHeight();
      originalWidth = getMeasuredWidth();

      animator = ObjectAnimator.ofPropertyValuesHolder(
              this,
              PropertyValuesHolder.ofFloat("scaleX", DEFAULT_ANIMATION_FACTOR),
              PropertyValuesHolder.ofFloat("scaleY", DEFAULT_ANIMATION_FACTOR));
      animator.setDuration(200);
      animator.setRepeatCount(ObjectAnimator.INFINITE);
      animator.setRepeatMode(ObjectAnimator.REVERSE);
   }

   public boolean isInitialized()
   {
      return isInitialized;
   }



   public void resetButtonSize()
   {
      setMeasuredDimension(originalWidth, originalHeight);
   }


   public boolean isAnimationRunning()
   {
      return isAnimationRunning;
   }


   public void animate(boolean doAnimation)
   {
      isAnimationRunning = doAnimation;

      if(doAnimation)
         animator.start();
      else
      {
         animator.end();
         setPressed(false);
         resetButtonSize();
         //destroyDrawingCache(); tried these without success
         //postInvalidate();
      }
   }
}

最后,我使用 RecognitionListener 控制按钮开始和结束动画:

public class InputVoiceRecognitionListener implements RecognitionListener
{
   private EditText targetEditText;
   private String originalContent;
   private final String DELIMITER = "\n\n";
   private FloatingVoiceButton button;

   public InputVoiceRecognitionListener(EditText editText, FloatingVoiceButton button)
   {
      targetEditText = editText;
      originalContent = editText.getText().toString();
      this.button = button;
   }

   @Override
   public void onReadyForSpeech(Bundle params)
   {
      button.animate(true);
   }

   @Override
   public void onBeginningOfSpeech()
   {
      originalContent = targetEditText.getText().toString();
   }

   @Override
   public void onRmsChanged(float rmsdB)
   {}

   @Override
   public void onBufferReceived(byte[] buffer)
   {}

   @Override
   public void onEndOfSpeech()
   {
      if(button.isAnimationRunning())
         button.animate(false);
   }

   @Override
   public void onError(int error)
   {
      if(button.isAnimationRunning())
         button.animate(false);
   }

   @Override
   public void onResults(Bundle results)
   {
setRecognizedText(results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION));
   }

   @Override
   public void onPartialResults(Bundle partialResults)
   {
               setRecognizedText(partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION));
   }

   @Override
   public void onEvent(int eventType, Bundle params)
   {

   }

   private void setRecognizedText(ArrayList<String> matches)
   {
      String result = "";

      if(matches != null)
         result = matches.get(0);

      if((originalContent.trim()).length() > 0)
      {
         if(!originalContent.endsWith("\n\n"))
            result = originalContent + DELIMITER + result;
         else result = originalContent + result;
      }

      targetEditText.setText(result);
      targetEditText.setSelection(result.length());
   }
}

编辑

这是为我做的:

resettingAnimator = ObjectAnimator.ofPropertyValuesHolder(
          this,
          PropertyValuesHolder.ofFloat("scaleX", 1.0f),
          PropertyValuesHolder.ofFloat("scaleY", 1.0f));
  resettingAnimator.setDuration(0);
  resettingAnimator.setRepeatCount(1);

并在我完成主要动画后调用 resettingAnimator.start();

解决此问题的简单方法是在停止重复动画后定义另一个动画。

I just can't figure out how to catch that and set the size to the original one.

你,也就是 View,知道什么是 "original" 大小,它是比例因子 1f 的大小。所以在停止重复动画后,只需制作另一个动画以将比例设置为 1f

PropertyValuesHolder.ofFloat("scaleX", 1f)
PropertyValuesHolder.ofFloat("scaleY", 1f))

此动画将始终 运行,但如果您的按钮已经处于 "normal" 大小,则该动画将不可见。

考虑到这一点,我建议您使用 isAnimationRunning() 以外的其他标志,或者通过 Fab 的某些状态(例如选择),或者一些手动设置的任意布尔值。