added PrecomputedFutureTextSetterCompat with tests in the sample app
This commit is contained in:
parent
8e3d898b40
commit
c4a2bb94e2
@ -66,6 +66,7 @@ ext {
|
||||
'x-annotations' : 'androidx.annotation:annotation:1.1.0',
|
||||
'x-recycler-view' : 'androidx.recyclerview:recyclerview:1.0.0',
|
||||
'x-core' : 'androidx.core:core:1.0.2',
|
||||
'x-appcompat' : 'androidx.appcompat:appcompat:1.1.0',
|
||||
'commonmark' : "com.atlassian.commonmark:commonmark:$commonMarkVersion",
|
||||
'commonmark-strikethrough': "com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:$commonMarkVersion",
|
||||
'commonmark-table' : "com.atlassian.commonmark:commonmark-ext-gfm-tables:$commonMarkVersion",
|
||||
|
@ -22,6 +22,7 @@ dependencies {
|
||||
// @since 4.1.0 to allow PrecomputedTextSetterCompat
|
||||
// note that this dependency must be added on a client side explicitly
|
||||
compileOnly it['x-core']
|
||||
compileOnly it['x-appcompat']
|
||||
}
|
||||
|
||||
deps['test'].with {
|
||||
|
@ -0,0 +1,61 @@
|
||||
package io.noties.markwon;
|
||||
|
||||
import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
import androidx.core.text.PrecomputedTextCompat;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Please note this class requires `androidx.core:core` artifact being explicitly added to your dependencies.
|
||||
* This is intended to be used in a RecyclerView.
|
||||
*
|
||||
* @see io.noties.markwon.Markwon.TextSetter
|
||||
*/
|
||||
public class PrecomputedFutureTextSetterCompat implements Markwon.TextSetter {
|
||||
|
||||
/**
|
||||
* @param executor for background execution of text pre-computation,
|
||||
* if not provided the standard, single threaded one will be used.
|
||||
*/
|
||||
@NonNull
|
||||
public static PrecomputedFutureTextSetterCompat create(@Nullable Executor executor) {
|
||||
return new PrecomputedFutureTextSetterCompat(executor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static PrecomputedFutureTextSetterCompat create() {
|
||||
return new PrecomputedFutureTextSetterCompat(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private final Executor executor;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
PrecomputedFutureTextSetterCompat(@Nullable Executor executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(
|
||||
@NonNull TextView textView,
|
||||
@NonNull Spanned markdown,
|
||||
@NonNull TextView.BufferType bufferType,
|
||||
@NonNull Runnable onComplete) {
|
||||
|
||||
if (textView instanceof AppCompatTextView) {
|
||||
((AppCompatTextView) textView).setTextFuture(PrecomputedTextCompat.getTextFuture(
|
||||
markdown, ((AppCompatTextView) textView).getTextMetricsParamsCompat(), executor
|
||||
));
|
||||
|
||||
onComplete.run();
|
||||
} else {
|
||||
Log.w("Markwon, no-op", "PrecomputedFutureTextSetterCompat: textView provided is not an AppCompatTextView!");
|
||||
}
|
||||
}
|
||||
}
|
@ -54,6 +54,7 @@ dependencies {
|
||||
deps.with {
|
||||
implementation it['x-recycler-view']
|
||||
implementation it['x-core'] // for precomputedTextCompat
|
||||
implementation it['x-appcompat'] // for setTextFuture
|
||||
implementation it['okhttp']
|
||||
implementation it['prism4j']
|
||||
implementation it['debug']
|
||||
|
@ -28,6 +28,7 @@
|
||||
<activity android:name=".simpleext.SimpleExtActivity" />
|
||||
<activity android:name=".customextension2.CustomExtensionActivity2" />
|
||||
<activity android:name=".precomputed.PrecomputedActivity" />
|
||||
<activity android:name=".precomputed.PrecomputedFutureActivity" />
|
||||
|
||||
<activity
|
||||
android:name=".editor.EditorActivity"
|
||||
|
@ -30,6 +30,7 @@ import io.noties.markwon.sample.inlineparser.InlineParserActivity;
|
||||
import io.noties.markwon.sample.latex.LatexActivity;
|
||||
import io.noties.markwon.sample.notification.NotificationActivity;
|
||||
import io.noties.markwon.sample.precomputed.PrecomputedActivity;
|
||||
import io.noties.markwon.sample.precomputed.PrecomputedFutureActivity;
|
||||
import io.noties.markwon.sample.recycler.RecyclerActivity;
|
||||
import io.noties.markwon.sample.simpleext.SimpleExtActivity;
|
||||
import io.noties.markwon.sample.tasklist.TaskListActivity;
|
||||
@ -123,6 +124,10 @@ public class MainActivity extends Activity {
|
||||
activity = PrecomputedActivity.class;
|
||||
break;
|
||||
|
||||
case PRECOMPUTED_FUTURE_TEXT:
|
||||
activity = PrecomputedFutureActivity.class;
|
||||
break;
|
||||
|
||||
case EDITOR:
|
||||
activity = EditorActivity.class;
|
||||
break;
|
||||
|
@ -23,6 +23,8 @@ public enum Sample {
|
||||
|
||||
PRECOMPUTED_TEXT(R.string.sample_precomputed_text),
|
||||
|
||||
PRECOMPUTED_FUTURE_TEXT(R.string.sample_precomputed_future_text),
|
||||
|
||||
EDITOR(R.string.sample_editor),
|
||||
|
||||
INLINE_PARSER(R.string.sample_inline_parser),
|
||||
|
@ -0,0 +1,95 @@
|
||||
package io.noties.markwon.sample.precomputed;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.PrecomputedFutureTextSetterCompat;
|
||||
import io.noties.markwon.recycler.MarkwonAdapter;
|
||||
import io.noties.markwon.sample.R;
|
||||
|
||||
public class PrecomputedFutureActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_recycler);
|
||||
|
||||
final Markwon markwon = Markwon.builder(this)
|
||||
.textSetter(PrecomputedFutureTextSetterCompat.create())
|
||||
.build();
|
||||
|
||||
// create MarkwonAdapter and register two blocks that will be rendered differently
|
||||
final MarkwonAdapter adapter = MarkwonAdapter.builder(R.layout.adapter_appcompat_default_entry, R.id.text)
|
||||
.build();
|
||||
|
||||
final RecyclerView recyclerView = findViewById(R.id.recycler_view);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
adapter.setMarkdown(markwon, loadReadMe(this));
|
||||
|
||||
// please note that we should notify updates (adapter doesn't do it implicitly)
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String loadReadMe(@NonNull Context context) {
|
||||
InputStream stream = null;
|
||||
try {
|
||||
stream = context.getAssets().open("README.md");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return readStream(stream);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String readStream(@Nullable InputStream inputStream) {
|
||||
|
||||
String out = null;
|
||||
|
||||
if (inputStream != null) {
|
||||
BufferedReader reader = null;
|
||||
//noinspection TryFinallyCanBeTryWithResources
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line)
|
||||
.append('\n');
|
||||
}
|
||||
out = builder.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
// no op
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out == null) {
|
||||
throw new RuntimeException("Cannot read stream");
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
android:lineSpacingExtra="2dip"
|
||||
android:paddingTop="8dip"
|
||||
android:paddingBottom="8dip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#000"
|
||||
android:textSize="16sp"
|
||||
tools:text="Hello" />
|
@ -25,6 +25,8 @@
|
||||
|
||||
<string name="sample_precomputed_text"># \# PrecomputedText\n\nUsage of TextSetter and PrecomputedTextCompat</string>
|
||||
|
||||
<string name="sample_precomputed_future_text"># \# PrecomputedFutureText\n\nUsage of TextSetter and PrecomputedFutureTextSetterCompat</string>
|
||||
|
||||
<string name="sample_editor"># \# Editor\n\n`MarkwonEditor` sample usage to highlight user input in EditText</string>
|
||||
|
||||
<string name="sample_inline_parser"># \# Inline Parser\n\nUsage of custom inline parser</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user