2017-07-26 22 views
0

我有一個具有閃爍光標的自定義視圖。我使用Handler閃爍光標並在延遲500毫秒後發佈Runnable在活動暫停時取消自定義視圖中的可運行/處理程序

當視圖處於活動狀態時,我想通過刪除處理程序上的回調來停止閃爍。不過,我注意到,當我切換到另一個應用程序時,處理程序/ runnable繼續執行,即日誌表示它仍在閃爍。

如果我有看法的控制,我只想做一些像this

@Override 
protected void onPause() { 
    handler.removeCallbacks(runnable); 
    super.onPause(); 
} 

但我的自定義視圖將是一個庫的一部分,所以我不擁有控制權的活動,其他開發者使用我的自定義視圖英寸

我試過onFocusChanged,onScreenStateChangedonDetachedFromWindow但這些都不工作,當用戶切換到另一個應用程序。

這是我的代碼。我通過刪除與問題無關的任何內容來簡化它。

public class MyCustomView extends View { 

    static final int BLINK = 500; 
    private Handler mBlinkHandler; 

    private void init() { 
     // ... 
     mBlinkHandler = new Handler(); 

     mTextStorage.setOnChangeListener(new MongolTextStorage.OnChangeListener() { 
      @Override 
      public void onTextChanged(/*...*/) { 
       // ... 
       startBlinking(); 
      } 
     }); 
    } 

    Runnable mBlink = new Runnable() { 
     @Override 
     public void run() { 
      mBlinkHandler.removeCallbacks(mBlink); 
      if (shouldBlink()) { 
       // ... 
       Log.i("TAG", "Still blinking..."); 
       mBlinkHandler.postDelayed(mBlink, BLINK); 
      } 
     } 
    }; 

    private boolean shouldBlink() { 
     if (!mCursorVisible || !isFocused()) return false; 
     final int start = getSelectionStart(); 
     if (start < 0) return false; 
     final int end = getSelectionEnd(); 
     if (end < 0) return false; 
     return start == end; 
    } 

    void startBlinking() { 
     mBlink.run(); 
    } 

    void stopBlinking() { 
     mBlinkHandler.removeCallbacks(mBlink); 
    } 

    @Override 
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 
     if (focused) { 
      startBlinking(); 
     } else { 
      stopBlinking(); 
     } 
     super.onFocusChanged(focused, direction, previouslyFocusedRect); 
    } 

    @Override 
    public void onScreenStateChanged(int screenState) { 
     switch (screenState) { 
      case View.SCREEN_STATE_ON: 
       startBlinking(); 
       break; 
      case View.SCREEN_STATE_OFF: 
       stopBlinking(); 
       break; 
     } 
    } 

    public void onAttachedToWindow() { 
     super.onAttachedToWindow(); 
     startBlinking(); 
    } 

    @Override 
    public void onDetachedFromWindow() { 
     super.onDetachedFromWindow(); 
     stopBlinking(); 
    } 
} 
+0

希望這有助於:http://androidxref.com/1.6/xref/frameworks/base/core/java/android/widget/TextView.java#6607 – pskink

+0

@pskink,好主意。我需要回到Android源代碼並進一步研究它。任何你連接到舊版本的TextView而不是當前版本的原因?是否因爲那是當時更簡單的實施? – Suragch

+0

是的,正好,現在它......我不知道它現在是如何工作的(我懶得去挖掘它) - 有像mEditor.makeBlink()這樣的東西,所以它可能會產生一些東西 – pskink

回答

0

我猜你是單獨啓動線程使用thread.run(),而不是僅僅做一個方法,並調用它遞歸事情是這樣的:

public void blink(){ 
    mBlinkHandler.postDelayed(mBlink, BLINK); 
} 

而且在可運行:

Runnable mBlink = new Runnable() { 
    @Override 
    public void run() { 
     mBlinkHandler.removeCallbacks(mBlink); 
     if (shouldBlink()) { 
      // ... 
      Log.i("TAG", "Still blinking..."); 
      blink(); 
     } 
    } 
}; 

由於您使用run方法直接啓動線程。所以它不會停止通過刪除回調。

希望這會有所幫助。

+0

它會阻止它通過消除其他情況下的回調(比如失去焦點或關閉活動),所以我不認爲這是因爲我最初使用'run'啓動它。 – Suragch

相關問題