2017-07-26 9 views
0

カーソルが点滅しているカスタムビューがあります。私はHandlerを使用して点滅カーソルを作成し、500ミリ秒の遅延後にRunnableをそれに掲示します。アクティビティが一時停止したときに、カスタムビューで実行可能/ハンドラをキャンセルします。

ビューが含まれているアクティビティでは、ハンドラのコールバックを削除して点滅を停止します。しかし、私は別のアプリに切り替えると、ハンドラ/実行可能ファイルが継続していることに気がつきました。つまり、ログにはまだ点滅が表示されています。

私はちょうどthis

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

ような何かをするだろう。しかし、私のカスタムビューは、ライブラリの一部となりますので、私は他の開発者が使用して活動を制御することはできませんビューのコントロールを持っていた場合

私はonFocusChangedonScreenStateChanged、およびonDetachedFromWindowを試しましたが、ユーザーが別のアプリに切り替わったときにはうまくいきませんでした。

ここに私のコードです。私は問題に関連していないものを取り除いてそれを単純化した。

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

そして実行可能に:

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使用して個別のスレッドを起動していると思います

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

runメソッドを使用してスレッドを直接開始しているので。だから、コールバックを取り除くことで止まることはありません。

これが役に立ちます。

+0

それを止めます(フォーカスを失う、またはアクティビティを閉じるなどの)他の状況でコールバックを取り除くことによって、私はそれが最初に 'run'で起動するからだとは思いません。 – Suragch

関連する問題