Изменение реакции SlidingDrawer на трекбол или курсор
(обратите внимание, что поведение, описанное в этом вопросе, появилось только из-за чего-то еще, казалось бы, не связанного с тем, что мы делали. См.принято отвечать.)
у нас есть Android активность с GridView
и SlidingDrawer
внутри RelativeLayout
. То, как это действие реагирует на трекбол (или клавиши курсора), довольно странно. Фокус будет перемещаться между элементами в GridView, но всякий раз, когда курсор перемещается в направлении "из" в GridView. (например, вверх, когда вверху, слева, когда уже в крайнем левом элементе) выдвижной ящик открывается или закрывается. Примечательно, что фокус остается на том же элементе в GridView---он не перемещается в выдвижной ящик.
с трекболом это особенно ужасно, так как вращение трекбола мимо вашего реального места назначения заставит выдвижной ящик неоднократно открываться и закрываться.
мы определили, что мы можем отключить трекбол полностью путем переопределения onTrackballEvent()
. Мы бы предпочли, чтобы трекбол и курсор работали нормально на GridView, но не заставляли выдвижной ящик открываться или закрываться. В принципе, мы также хотели бы, чтобы трекбол сосредоточился на различном содержимом выдвижного ящика, когда он открыт.
как?
3 ответов
вы можете создать пользовательский вид, простирающийся GridView
и SlidingDrawer
и использование пользовательских реализаций onInterceptTouchEvent
и onTouchEvent
на GridView
и пользовательская реализация только для onInterceptTouchEvent
на SlidingDrawer
. Возможно, Вам не потребуется реализовывать custom SlidingDrawer
в зависимости от того, какие пользовательские взаимодействия могут быть вызваны на handle
для вашего custom GridView
, дайте ему интерфейс, возможно, определенный следующим образом:
public interface MyGridViewListener {
public boolean shouldPreventScroll();
}
возврат, если ваш заказ SlidingDrawer
is открытый. это возвращаемое значение будет использоваться для определения, следует ли выполнять действия(для onInterceptTouchEvent
и onTouchEvent
методов) на GridView
. Итак, когда SlidingDrawer
открывается, действия выполняются на GridView
не вызовет ничего, на SlidingDrawer
.
действие:
MyGridView gridView = (MyGridView) findViewById(R.id.gridView);
gridView.setMyGridViewListener(new MyGridViewListener() {
@Override
public boolean shouldPreventScroll() {
return slidingDrawer.isOpened();
}
});
MyCustomGridView:
shouldIntercept
будет вызываться всякий раз, когда какое-либо событие touch/track происходит на GridView
.
private boolean shouldIntercept() {
boolean shouldIntercept = false;
if(myGridViewListener != null) {
shouldIntercept = myGridViewListener.shouldPreventScroll();
}
return shouldIntercept;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return shouldIntercept() ? true : super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return shouldIntercept() ? true : super.onTouchEvent(ev);
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
return shouldIntercept() ? true : super.onTrackballEvent(event);
}
public MyGridViewListener getMyGridViewListener() {
return myGridViewListener;
}
public void setMyGridViewListener(
MyGridViewListener myGridViewListener) {
this.myGridViewListener = myGridViewListener;
}
я надеюсь, что это указывает вам на правильное направление или, по крайней мере, помогает
играя с пользовательским выдвижным ящиком, я установил расположение ручки на какое-то нечетное значение, что-то вроде
handle.layout(0, 0,0, 0);
чтобы ручка исчезла, но перетаскивание пальца со стороны экрана все равно откроет выдвижной ящик, чего я не хотел, поэтому я установил
handle.layout(10000, 10000, 10000, 10000);
который переместил его за пределы видимой области, и ящик больше не мог быть вытащен вручную путем перетаскивания со стороны экрана. Посмотрев на исходный код свое положение ручки которая определяет сползать ящика, получает освобожданным ручки и ее должен разрешить вашу проблему.
Если вам нужно открыть/закрыть ящик, вызовите animateOpen () / animateClose ()
как оказалось, мы вызвали эту проблему из-за несвязанной глупости. Мы хотели меню ключ для открытия и закрытия SlidingDrawer
. Мы сделали это, переопределив onPrepareOptionsMenu()
:
public boolean onPrepareOptionsMenu (Menu menu) {
slidingDrawer.animateToggle();
return true;
}
это отлично работает; но оказывается, что его можно вызвать, когда меню не будет открыто. В частности, если Activity
использует setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT)
, затем необработанное ключевое событие завершится доступом к меню. Это включает движение trackball от края экран.
менее глупый способ получить желаемое поведение -
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_MENU) {
slidingDrawer.animateToggle();
}
return super.onKeyUp(keyCode,event);
}
между тем, мы можем заставить трекбол двигаться в SlidingDrawer
, когда он открыт, создав SlidingDrawer.OnDrawerOpenListener
которых звонки
slidingDrawer.getContent().requestFocus();
наконец-то это кажется хорошей идеей, чтобы позвонить
slidingDrawer.getHandle().setFocusable(false);