2011-11-29 72 views
6

(請注意,在這個問題上所描述的行爲纔出現的,因爲別的事情看似無關,我們正在做。見the accepted answer變化SlidingDrawer如何響應軌跡球或光標

我們有一個Android的活動有GridViewSlidingDrawerRelativeLayout之內。這個活動響應軌跡球(或光標鍵)的方式很奇怪。焦點將在GridView中的項目之間移動,但每當光標向GridView方向「移出」時移動。 (例如,當在頂部時向上,在已經在最左邊的物品時離開)滑動抽屜打開或關閉。值得注意的是,焦點停留在GridView中的同一個項目上 - 它不會移動到滑動抽屜。

使用軌跡球時,這特別可怕,因爲旋轉軌跡球經過您的真實目的地將導致滑動抽屜反覆打開和關閉。

我們已確定我們可以通過重寫onTrackballEvent()來完全關閉軌跡球。我們希望軌跡球和光標在GridView上正常工作,但不會導致滑動抽屜打開或關閉。原則上,我們還希望軌跡球在打開時專注於滑動抽屜的各種內容。

怎麼樣?

回答

0

事實證明,我們通過愚蠢的無關位導致此問題。我們希望MENU鍵可以打開和關閉SlidingDrawer。我們通過覆蓋onPrepareOptionsMenu()來做到這一點:

public boolean onPrepareOptionsMenu (Menu menu) { 
    slidingDrawer.animateToggle(); 
    return true; 
} 

這工作正常;但事實證明,當菜單不打開時可以調用它。特別是,如果Activity使用setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT),則未處理的按鍵事件將最終訪問該菜單。這包括離屏幕邊緣的軌跡球運動。

越少愚蠢的方式獲得所需的行爲是

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); 
3

可以考慮創建擴展GridViewSlidingDrawer和使用的onInterceptTouchEventonTouchEvent自定義實現爲GridView和自定義視圖只是onInterceptTouchEventSlidingDrawer自定義實現。您可能不需要實施這取決於用戶交互可在handle

觸發您的自定義GridView定製SlidingDrawer,給它這樣也許定義的接口:

public interface MyGridViewListener { 
    public boolean shouldPreventScroll(); 
} 

回報,如果您的自定義SlidingDrawer被打開。此返回值將用於確定是否應在GridView上執行操作(對於onInterceptTouchEventonTouchEvent方法)。因此,當打開SlidingDrawer時,在GridView上執行的操作不會觸發SlidingDrawer上的任何操作。

活動:

MyGridView gridView = (MyGridView) findViewById(R.id.gridView); 
gridView.setMyGridViewListener(new MyGridViewListener() { 
    @Override 
    public boolean shouldPreventScroll() { 
     return slidingDrawer.isOpened(); 
    } 
}); 

MyCustomGridView:每當一些觸摸/跟蹤事件的發生GridView shouldIntercept將被調用。

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

我希望這點你在正確的方向,或至少幫助

+0

有用的想法。它給了我一個想法,在自定義的'SlidingDrawer'中重寫'open()'併發出一個堆棧跟蹤,這導致了在接受的答案中描述的解決方案。 –

1

雖然與自定義滑動抽屜玩弄我的手柄的佈局設置爲一些奇怪的價值,像

handle.layout(0, 0,0, 0); 

使手柄消失,但拖動從屏幕上仍然打開滑動抽屜,這是我不想要的東西的一側手指,所以我設置

handle.layout(10000, 10000, 10000, 10000); 

移動到可視區域外,並且不能再通過從屏幕側面拖動手動拉出抽屜。在查看源代碼中確定抽屜滑動的手柄位置後,擺脫手柄,它應該可以解決您的問題。

如果您需要打開/關閉抽屜調用animateOpen()/ animateClose()