diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java index c08faa08e..eeb711a66 100644 --- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java +++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java @@ -107,7 +107,6 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do private MenuItem _saveMenuItem, _undoMenuItem, _redoMenuItem; private boolean _isPreviewVisible; private boolean _nextConvertToPrintMode = false; - private long _lineNumbersRefreshTime; // Line numbers refresh time on scroll changed public DocumentEditAndViewFragment() { @@ -141,19 +140,8 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { _textActionsBar = view.findViewById(R.id.document__fragment__edit__text_actions_bar); _webView = view.findViewById(R.id.document__fragment_view_webview); _primaryScrollView = view.findViewById(R.id.document__fragment__edit__content_editor__scrolling_parent); - _primaryScrollView.getViewTreeObserver().addOnScrollChangedListener(() -> - { - if (_lineNumbersView.isLineNumbersEnabled()) { - final long time = System.currentTimeMillis(); - if (time - _lineNumbersRefreshTime > 125) { - _lineNumbersRefreshTime = time; - _lineNumbersView.forceRefresh(); - } - } - }); _lineNumbersView = view.findViewById(R.id.document__fragment__edit__line_numbers_view); - _lineNumbersView.setEditText(_hlEditor); - _lineNumbersView.setLineNumbersEnabled(_appSettings.getDocumentLineNumbersEnabled(_document.path)); + _cu = new MarkorContextUtils(activity); // Using `if (_document != null)` everywhere is dangerous @@ -267,6 +255,9 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { } }); } + + _lineNumbersView.setup(_hlEditor, _primaryScrollView); + _lineNumbersView.setLineNumbersEnabled(_appSettings.getDocumentLineNumbersEnabled(_document.path)); } @Override diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java index 0f86c492c..39a452ecf 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java @@ -57,7 +57,6 @@ public class HighlightingEditor extends AppCompatEditText { private boolean _isDynamicHighlightingEnabled = true; private Runnable _hlDebounced; // Debounced runnable which recomputes highlighting private boolean _hlEnabled; // Whether highlighting is enabled - private boolean _numEnabled; // Whether show line numbers is enabled private final Rect _oldHlRect; // Rect highlighting was previously applied to private final Rect _hlRect; // Current rect private int _hlShiftThreshold = -1; // How much to scroll before re-apply highlight @@ -81,7 +80,6 @@ public HighlightingEditor(Context context, AttributeSet attrs) { } _hlEnabled = false; - _numEnabled = false; _oldHlRect = new Rect(); _hlRect = new Rect(); @@ -194,9 +192,7 @@ public void setDynamicHighlightingEnabled(final boolean enable) { recomputeHighlighting(); } - public boolean isDynamicHighlightingEnabled() { - return _isDynamicHighlightingEnabled; - } + // public boolean isDynamicHighlightingEnabled() { return _isDynamicHighlightingEnabled; } public void setHighlighter(final SyntaxHighlighterBase newHighlighter) { if (_hl != null) { diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java b/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java index c81839eb6..18c9a36a5 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java @@ -8,16 +8,30 @@ import android.text.Layout; import android.text.TextWatcher; import android.util.AttributeSet; +import android.view.View; +import android.view.ViewTreeObserver; import android.widget.EditText; +import android.widget.ScrollView; import androidx.appcompat.widget.AppCompatTextView; -/** - * @author Li Guanglin - */ +@SuppressWarnings("UnusedReturnValue") public class LineNumbersTextView extends AppCompatTextView { - private boolean lineNumbersEnabled; private LineNumbersDrawer lineNumbersDrawer; + private boolean lineNumbersEnabled; + private ScrollView scrollView; + private final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { + private long lastTime; + + @Override + public void onScrollChanged() { + final long time = System.currentTimeMillis(); + if (time - lastTime > 125) { + lastTime = time; + refresh(); + } + } + }; public LineNumbersTextView(Context context) { super(context); @@ -31,6 +45,14 @@ public LineNumbersTextView(Context context, AttributeSet attrs, int defStyleAttr super(context, attrs, defStyleAttr); } + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + if (isLineNumbersEnabled() && visibility == View.VISIBLE) { + refresh(); + } + } + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -39,11 +61,15 @@ protected void onDraw(Canvas canvas) { } } - public void forceRefresh() { - setText(""); // Use setText("") to activate LineNumbersTextView refresh + public void refresh() { + setText(""); // To activate LineNumbersTextView refresh + if (getWidth() == 0) { + lineNumbersDrawer.getEditText().postInvalidate(); + } } - public void setEditText(final EditText editText) { + public void setup(final EditText editText, ScrollView scrollView) { + this.scrollView = scrollView; lineNumbersDrawer = new LineNumbersDrawer(editText, this); } @@ -51,10 +77,16 @@ public void setLineNumbersEnabled(final boolean enabled) { lineNumbersEnabled = enabled; if (lineNumbersEnabled) { lineNumbersDrawer.prepare(); + if (scrollView != null) { + scrollView.getViewTreeObserver().addOnScrollChangedListener(onScrollChangedListener); + } } else { - lineNumbersDrawer.reset(); + lineNumbersDrawer.done(); + if (scrollView != null) { + scrollView.getViewTreeObserver().removeOnScrollChangedListener(onScrollChangedListener); + } } - forceRefresh(); + refresh(); } public boolean isLineNumbersEnabled() { @@ -62,8 +94,8 @@ public boolean isLineNumbersEnabled() { } static class LineNumbersDrawer { - public final EditText editText; - public final LineNumbersTextView textView; + private final EditText editText; + private final LineNumbersTextView textView; private final Paint paint = new Paint(); @@ -99,7 +131,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { @Override public void afterTextChanged(Editable editable) { if (isLayoutLineCountChanged() || isMaxNumberChanged()) { - textView.forceRefresh(); + textView.refresh(); } } }; @@ -112,6 +144,10 @@ public LineNumbersDrawer(final EditText editText, final LineNumbersTextView text paint.setTextAlign(Paint.Align.RIGHT); } + public EditText getEditText() { + return editText; + } + private boolean isOutOfLineNumbersArea() { final int margin = (int) (visibleArea.height() * 0.5f); final int top = visibleArea.top - margin; @@ -194,7 +230,7 @@ private int countLines(final CharSequence s, int start, int end) { return count; } - private void lineTracking(boolean enabled) { + private void setLineTracking(boolean enabled) { editText.removeTextChangedListener(lineTrackingWatcher); if (enabled) { @@ -211,7 +247,7 @@ private void lineTracking(boolean enabled) { * Prepare for drawing line numbers. */ public void prepare() { - lineTracking(true); + setLineTracking(true); textView.setVisibility(VISIBLE); editText.setPadding(EDITOR_PADDING_LEFT, editText.getPaddingTop(), editText.getPaddingRight(), editText.getPaddingBottom()); } @@ -289,10 +325,10 @@ public void draw(final Canvas canvas) { } /** - * Reset states related line numbers. + * Reset some states related line numbers. */ - public void reset() { - lineTracking(false); + public void done() { + setLineTracking(false); maxNumberDigits = 0; textView.setWidth(0); textView.setVisibility(GONE);