Я разработал собственный компонент, в котором реализовал onClick, onLongClick и onTouchListener.Все работает нормально, за исключением того, что onLongClick и onClick вызываются дважды, даже если я совершаю действие только один раз.Что не так, пожалуйста, руководство к решению.Повторный вызов метода занимает заметное время, т. Е. ~ 1 сек.
Ниже приведен код:
CustomWidget:
@BindingMethods({
@BindingMethod(type = RecordingButton.class, attribute = "progress", method = "setProgress"),
})
public class RecordingButton extends RelativeLayout {
boolean isLongPressed;
boolean isPressed;
private Context mContext;
private int progressBackground, progressColor, progressBarWidth;
private int maxProgress, progress;
private LayoutRecordingBtnBinding itemViewBinding;
private OnRecordingButtonListener listener;
private ValueAnimator progressAnimator;
private View.OnTouchListener viewTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View pView, MotionEvent pEvent) {
pView.onTouchEvent(pEvent);
// We're only interested in when the button is released.
switch (pEvent.getAction()) {
case MotionEvent.ACTION_UP:
isPressed = false;
// We're only interested in anything if our speak button is currently pressed.
if (isLongPressed) {
AppLogger.d("usm_recording_button_2", "onTouch ACTION_UP is called to release longPress");
isLongPressed = false;
// Do something when the button is released.\
if (listener != null)
listener.onStopRecording();
} else {
setTintColor(R.color.fayvo_color);
}
break;
case MotionEvent.ACTION_DOWN:
isPressed = true;
setTintColor(R.color.trans_fayvo_color);
break;
}
return false;
}
};
public RecordingButton(Context context) {
super(context);
initializeView(context, null, 0);
}
public RecordingButton(Context context, AttributeSet attrs) {
super(context, attrs);
initializeView(context, attrs, 0);
}
public RecordingButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initializeView(context, attrs, defStyleAttr);
}
private void initializeView(Context context, AttributeSet attrs, int defStyleAttr) {
mContext = context;
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RecordingButton, defStyleAttr, 0);
try {
maxProgress = array.getInteger(R.styleable.RecordingButton_android_max, 30);
progress = array.getInteger(R.styleable.RecordingButton_android_progress, 0);
progressBarWidth = array.getDimensionPixelSize(R.styleable.RecordingButton_progressWidth, -1);
progressColor = array.getColor(R.styleable.RecordingButton_progressColor, Integer.MAX_VALUE);
progressBackground = array.getColor(R.styleable.RecordingButton_progressBackgroundColor, Integer.MAX_VALUE);
} finally {
array.recycle();
}
itemViewBinding = LayoutRecordingBtnBinding.inflate(LayoutInflater.from(mContext), this, true);
setListeners();
}
private void setListeners() {
this.setOnClickListener(view -> {
// check if recording is not running on long press already
// if (progressAnimator != null && progressAnimator.isRunning())
// return;
// AppLogger.d("usm_loading_btn_1", "onClick is called");
if (listener != null) {
AppLogger.d("usm_recording_button_0", "onClick is called");
listener.onClick();
}
});
/*itemViewBinding.ivCameraBtn*/
this.setOnLongClickListener(pView -> {
AppLogger.d("usm_recording_button_1.0", "onLongClick detected: already isLongPressed= " + isLongPressed + " ,isPressed= " + isPressed);
if (isLongPressed /*|| !isPressed*/) // method is calling twice , need to do action only once
return true;
setTintColor(R.color.trans_fayvo_color);
// Do something when your hold starts here.
isLongPressed = true;
AppLogger.d("usm_recording_button_1.1", "onLongClick is called");
animateInnerIcon(true);
if (listener != null)
listener.onLongClick();
return true;
});
this.setOnTouchListener(viewTouchListener);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
setValues();
}
private void setValues() {
try {
setProgress(progress);
setMaxProgress(maxProgress);
setProgressColor(progressColor);
setProgressBackgroundColor(progressBackground);
setProgressBarWidth(progressBarWidth);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setProgress(int progress) {
itemViewBinding.circularProgressBar.setProgress(progress);
}
public void setMaxProgress(int maxProgress) {
itemViewBinding.circularProgressBar.setProgressMax(maxProgress);
}
public void setProgressBarWidth(int strokeWidth) {
if (strokeWidth > -1)
itemViewBinding.circularProgressBar.setProgressBarWidth(strokeWidth);
}
public void setProgressColor(int color) {
this.progressColor = color;
if (progressColor != Integer.MAX_VALUE) {
itemViewBinding.circularProgressBar.setColor(progressColor);
}
}
public void setProgressBackgroundColor(int color) {
this.progressBackground = color;
if (progressBackground != Integer.MAX_VALUE) {
itemViewBinding.circularProgressBar.setBackgroundColor(progressBackground);
}
}
public void setTintColor(int tintColor) {
// itemViewBinding.ivCameraBtn.setForegroundTintList(new ColorStateList()[]);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
itemViewBinding.ivCameraBtn.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(mContext, tintColor)));
}
}
public void animateInnerIcon(boolean expand) {
float from = expand ? 0f : 1f;
float to = expand ? 1f : 0f;
Animator scaleXAnimator = ObjectAnimator.ofFloat(itemViewBinding.ivInnerIcon, "scaleX", from, to);
Animator scaleYAnimator = ObjectAnimator.ofFloat(itemViewBinding.ivInnerIcon, "scaleY", from, to);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
animatorSet.setInterpolator(new DecelerateInterpolator());
animatorSet.setDuration(expand ? 600 : 300);
animatorSet.start();
}
public void animateProgress() {
progressAnimator = ValueAnimator.ofFloat(0, maxProgress);
progressAnimator.addUpdateListener(animation -> {
try {
Float val = (Float) animation.getAnimatedValue();
itemViewBinding.circularProgressBar.setProgress(val);
} catch (Exception e) {
e.printStackTrace();
}
});
progressAnimator.setDuration(maxProgress * 1000);
progressAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
isLongPressed = false; // no action required on ActionUp of onTouch
if (listener != null)
listener.onStopRecording();
// reset();
}
});
progressAnimator.setInterpolator(new LinearInterpolator());
progressAnimator.start();
}
public void reset() {
AppLogger.d("usm_recording_button_2", "reset recording button");
if (progressAnimator != null)
progressAnimator.cancel();
itemViewBinding.circularProgressBar.setProgress(0);
/*itemViewBinding.ivInnerIcon.setScaleX(0f);
itemViewBinding.ivInnerIcon.setScaleY(0f);*/
if (itemViewBinding.ivInnerIcon.getScaleX() > 0)
animateInnerIcon(false);
}
public void setOnActionListener(OnRecordingButtonListener listener) {
this.listener = listener;
}
public interface OnRecordingButtonListener {
void onClick();
void onLongClick();
void onStopRecording();
}
}