动画后,FloatingActionButton不会返回原始大小

时间:2018-04-24 08:48:10

标签: android user-interface speech-recognition floating-action-button objectanimator

我写了一个小STT功能,其中有一个浮动按钮,点击后会发出脉动声,通知该应用正在收听。到目前为止,这很好地解决了一个恼人的行为,在某些情况下我的浮动按钮没有恢复到原始大小。

动画增加和减小按钮的大小,我猜它会陷入增加的状态,因此这种行为的随机性。我只是无法弄清楚如何捕获它并将大小设置为原始大小。

我的按钮的动作侦听器:

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

My Button扩展了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();

1 个答案:

答案 0 :(得分:1)

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

  

我无法弄清楚如何捕获它并将大小设置为原始大小。

您,即View,确实知道什么是“原始”尺寸,它是比例因子1f的大小。因此,在停止重复动画后,只需制作另一个动画,将比例设置为1f

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

此动画将始终运行,但如果您的按钮已处于“正常”尺寸,则无法显示。

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