【发布时间】:2019-03-21 14:53:55
【问题描述】:
我的 Android 应用中有一个搜索栏。我需要检测搜索栏的长点击事件以执行某些操作。建议我任何解决方案。我已经在搜索栏上尝试了 onLongClickListener,但它不起作用。
【问题讨论】:
-
在搜索栏或拇指上?
-
任一。最好有拇指。
我的 Android 应用中有一个搜索栏。我需要检测搜索栏的长点击事件以执行某些操作。建议我任何解决方案。我已经在搜索栏上尝试了 onLongClickListener,但它不起作用。
【问题讨论】:
在阅读文档和其他SeekBarLongClick 与开发人员有关的问题后,看起来LongClickListener 不适用于SeekBar。
不过,我可以建议一个解决方法:
SeekBar :您可以为 seekbar 实现 onTouch 事件,对于 MotionEvent.ACTION_DOWN 操作,您可以将超时设置为 1 秒,并将其视为 LongClick。如果调用了MotionEvent.ACTION_UP,则取消计时器。
Thumb :您可以实现 OnSeekBarChangeListener 并在 onStartTrackingTouch 事件上设置 1 秒超时,如果在超时期间未调用 onStopTrackingTouch 或 onProgressChanged,则将其视为 LongClick(如果调用了onStopTrackingTouch/onProgressChanged,则取消计时器。)
没有发布代码,因为我的 IDE 现在没有打开。但我希望你能找到使用这个逻辑的方法。 (如果您不了解我提到的事件,请阅读文档)
谢谢。
【讨论】:
一个自定义的SeekBar,处理onTouchEvent()中的逻辑
长按
当ACTION_DOWNpostDelay()长按可运行时,您可以根据需要修改LONG_CLICK_DELAY的值。 ACTION_MOVE ACTION_UP ACTION_CANCEL 移除runnable
点击
当ACTION_UP 检查ACTION_DOWN 运动事件参数时确保它是一个点击事件
mSeekBar.setEventListener(new DetectorSeekBar.IListener() {
@Override
public void onClick(DetectorSeekBar detectorSeekBar) {
Log.e("test", "click");
}
@Override
public void onLongClick(DetectorSeekBar detectorSeekBar) {
Log.e("test", "long click");
}
});
public class DetectorSeekBar extends AppCompatSeekBar {
//modified the value as you wish
private static final int LONG_CLICK_DELAY = 500;
private LongClickChecker mLongClickChecker;
private ClickChecker mClickChecker;
private IListener mListener;
public DetectorSeekBar(Context context) {
this(context, null);
}
public DetectorSeekBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DetectorSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLongClickChecker = new LongClickChecker(this);
mClickChecker = new ClickChecker(this);
}
public void setEventListener(IListener listener) {
mListener = listener;
mLongClickChecker.setLongClickListener(listener);
mClickChecker.setClickListener(listener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isEnabled()) {
postDelayed(mLongClickChecker, LONG_CLICK_DELAY);
mClickChecker.x = event.getX();
mClickChecker.y = event.getY();
mClickChecker.time = event.getEventTime();
}
break;
case MotionEvent.ACTION_MOVE:
removeCallbacks(mLongClickChecker);
mClickChecker.onMoveEvent();
break;
case MotionEvent.ACTION_UP:
removeCallbacks(mLongClickChecker);
if (isEnabled()
&& mClickChecker.checkCondition(event)) {
post(mClickChecker);
}
break;
case MotionEvent.ACTION_CANCEL:
removeCallbacks(mLongClickChecker);
removeCallbacks(mClickChecker);
break;
}
return super.onTouchEvent(event);
}
private static class LongClickChecker implements Runnable {
private WeakReference<IListener> mListenerRef;
private WeakReference<DetectorSeekBar> mViewRef;
LongClickChecker(DetectorSeekBar view) {
mViewRef = new WeakReference<>(view);
}
void setLongClickListener(IListener listener) {
mListenerRef = new WeakReference<>(listener);
}
@Override
public void run() {
if (mListenerRef != null && mListenerRef.get() != null
&& mViewRef != null && mViewRef.get() != null) {
mListenerRef.get().onLongClick(mViewRef.get());
}
}
}
private static class ClickChecker implements Runnable {
private long time = 0;
public float x;
public float y;
private boolean mMoved = false;
private WeakReference<IListener> mListenerRef;
private WeakReference<DetectorSeekBar> mViewRef;
ClickChecker(DetectorSeekBar view) {
mViewRef = new WeakReference<>(view);
}
@Override
public void run() {
if (mListenerRef != null && mListenerRef.get() != null
&& mViewRef != null && mViewRef.get() != null) {
mListenerRef.get().onClick(mViewRef.get());
}
}
void onMoveEvent() {
mMoved = true;
}
void setClickListener(IListener listener) {
mListenerRef = new WeakReference<>(listener);
}
boolean checkCondition(MotionEvent upEvent) {
if (upEvent != null) {
// have moved cancel click
if (mMoved) {
mMoved = false;
return false;
}
//ACTION_DOWN ACTION_UP time too long cancel click
boolean timeCorrect = upEvent.getEventTime() - time < LONG_CLICK_DELAY;
time = 0;
return timeCorrect;
}
return false;
}
}
public interface IListener {
void onClick(DetectorSeekBar detectorSeekBar);
void onLongClick(DetectorSeekBar detectorSeekBar);
}
}
【讨论】: