Highlight text shown in display asynchronously
This commit is contained in:
parent
da98947dab
commit
3bc913ac81
@ -133,6 +133,7 @@ public class Display {
|
|||||||
if (this.view != view) {
|
if (this.view != view) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.view.onDestroy();
|
||||||
this.view = null;
|
this.view = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,30 +22,74 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import static android.util.TypedValue.COMPLEX_UNIT_SP;
|
||||||
|
import static android.util.TypedValue.applyDimension;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.method.ScrollingMovementMethod;
|
import android.text.method.ScrollingMovementMethod;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
import org.solovyev.android.Check;
|
import org.solovyev.android.Check;
|
||||||
import org.solovyev.android.calculator.view.TextHighlighter;
|
import org.solovyev.android.calculator.view.TextHighlighter;
|
||||||
import org.solovyev.android.views.AutoResizeTextView;
|
import org.solovyev.android.views.AutoResizeTextView;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import static android.util.TypedValue.COMPLEX_UNIT_SP;
|
|
||||||
import static android.util.TypedValue.applyDimension;
|
|
||||||
|
|
||||||
public class DisplayView extends AutoResizeTextView {
|
public class DisplayView extends AutoResizeTextView {
|
||||||
|
|
||||||
|
private class AsyncHighlighter extends AsyncTask<Void, Void, CharSequence> {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final String text;
|
||||||
|
@Nullable
|
||||||
|
private final TextHighlighter highlighter;
|
||||||
|
|
||||||
|
AsyncHighlighter(@NonNull String text) {
|
||||||
|
this.text = text;
|
||||||
|
this.highlighter = getTextHighlighter();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldAsync() {
|
||||||
|
return !TextUtils.isEmpty(text) && highlighter != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected CharSequence doInBackground(Void... params) {
|
||||||
|
if (highlighter == null) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return highlighter.process(text).getCharSequence();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(@NonNull CharSequence text) {
|
||||||
|
if (highlighterTask != this) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setText(text);
|
||||||
|
setTextColor(getTextColor().normal);
|
||||||
|
highlighterTask = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Engine engine;
|
private Engine engine;
|
||||||
@Nullable
|
@Nullable
|
||||||
private TextHighlighter textHighlighter;
|
private TextHighlighter textHighlighter;
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private DisplayState state = DisplayState.empty();
|
private DisplayState state = DisplayState.empty();
|
||||||
|
@Nullable
|
||||||
|
private AsyncHighlighter highlighterTask;
|
||||||
|
|
||||||
public DisplayView(Context context) {
|
public DisplayView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -95,32 +139,41 @@ public class DisplayView extends AutoResizeTextView {
|
|||||||
|
|
||||||
state = newState;
|
state = newState;
|
||||||
if (state.valid) {
|
if (state.valid) {
|
||||||
setText(highlightText(state));
|
asyncHighlightText(newState);
|
||||||
setTextColor(getTextColor().normal);
|
|
||||||
} else {
|
} else {
|
||||||
|
cancelAsyncHighlightText(false);
|
||||||
setText(App.unspan(getText()));
|
setText(App.unspan(getText()));
|
||||||
setTextColor(getTextColor().error);
|
setTextColor(getTextColor().error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cancelAsyncHighlightText(boolean applyLastState) {
|
||||||
|
if (highlighterTask == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
highlighterTask.cancel(false);
|
||||||
|
if (applyLastState) {
|
||||||
|
highlighterTask.onPostExecute(highlighterTask.text);
|
||||||
|
}
|
||||||
|
highlighterTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void asyncHighlightText(@NonNull DisplayState state) {
|
||||||
|
cancelAsyncHighlightText(false);
|
||||||
|
highlighterTask = new AsyncHighlighter(state.text);
|
||||||
|
if (highlighterTask.shouldAsync()) {
|
||||||
|
highlighterTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
highlighterTask.onPostExecute(state.text);
|
||||||
|
Check.isNull(highlighterTask);
|
||||||
|
}
|
||||||
|
|
||||||
public void setEngine(@Nullable Engine engine) {
|
public void setEngine(@Nullable Engine engine) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
public void onDestroy() {
|
||||||
private CharSequence highlightText(@Nonnull DisplayState state) {
|
cancelAsyncHighlightText(true);
|
||||||
final String text = state.text;
|
|
||||||
if (TextUtils.isEmpty(text)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
final TextHighlighter textHighlighter = getTextHighlighter();
|
|
||||||
if (textHighlighter == null) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return textHighlighter.process(text).getCharSequence();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user