-
-
Notifications
You must be signed in to change notification settings - Fork 314
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #154 from noties/develop
4.1.0
- Loading branch information
Showing
19 changed files
with
457 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
markwon-core/src/main/java/io/noties/markwon/PrecomputedTextSetterCompat.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package io.noties.markwon; | ||
|
||
import android.os.Build; | ||
import android.text.Spanned; | ||
import android.util.Log; | ||
import android.widget.TextView; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.core.text.PrecomputedTextCompat; | ||
|
||
import java.lang.ref.WeakReference; | ||
import java.util.concurrent.Executor; | ||
|
||
/** | ||
* Please note this class requires `androidx.core:core` artifact being explicitly added to your dependencies. | ||
* Please do not use with `markwon-recycler` as it will lead to bad item rendering (due to async nature) | ||
* | ||
* @see io.noties.markwon.Markwon.TextSetter | ||
* @since 4.1.0 | ||
*/ | ||
public class PrecomputedTextSetterCompat implements Markwon.TextSetter { | ||
|
||
/** | ||
* @param executor for background execution of text pre-computation | ||
*/ | ||
@NonNull | ||
public static PrecomputedTextSetterCompat create(@NonNull Executor executor) { | ||
return new PrecomputedTextSetterCompat(executor); | ||
} | ||
|
||
private final Executor executor; | ||
|
||
@SuppressWarnings("WeakerAccess") | ||
PrecomputedTextSetterCompat(@NonNull Executor executor) { | ||
this.executor = executor; | ||
} | ||
|
||
@Override | ||
public void setText( | ||
@NonNull TextView textView, | ||
@NonNull final Spanned markdown, | ||
@NonNull final TextView.BufferType bufferType, | ||
@NonNull final Runnable onComplete) { | ||
|
||
// insert version check and do not execute on a device < 21 | ||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { | ||
// it's still no-op, so there is no need to start background execution | ||
applyText(textView, markdown, bufferType, onComplete); | ||
return; | ||
} | ||
|
||
final WeakReference<TextView> reference = new WeakReference<>(textView); | ||
executor.execute(new Runnable() { | ||
@Override | ||
public void run() { | ||
try { | ||
final PrecomputedTextCompat precomputedTextCompat = precomputedText(reference.get(), markdown); | ||
if (precomputedTextCompat != null) { | ||
applyText(reference.get(), precomputedTextCompat, bufferType, onComplete); | ||
} | ||
} catch (Throwable t) { | ||
Log.e("PrecomputdTxtSetterCmpt", "Exception during pre-computing text", t); | ||
// apply initial markdown | ||
applyText(reference.get(), markdown, bufferType, onComplete); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
@Nullable | ||
private static PrecomputedTextCompat precomputedText(@Nullable TextView textView, @NonNull Spanned spanned) { | ||
|
||
if (textView == null) { | ||
return null; | ||
} | ||
|
||
final PrecomputedTextCompat.Params params; | ||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||
// use native parameters on P | ||
params = new PrecomputedTextCompat.Params(textView.getTextMetricsParams()); | ||
} else { | ||
|
||
final PrecomputedTextCompat.Params.Builder builder = | ||
new PrecomputedTextCompat.Params.Builder(textView.getPaint()); | ||
|
||
// please note that text-direction initialization is omitted | ||
// by default it will be determined by the first locale-specific character | ||
|
||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | ||
// another miss on API surface, this can easily be done by the compat class itself | ||
builder | ||
.setBreakStrategy(textView.getBreakStrategy()) | ||
.setHyphenationFrequency(textView.getHyphenationFrequency()); | ||
} | ||
|
||
params = builder.build(); | ||
} | ||
|
||
return PrecomputedTextCompat.create(spanned, params); | ||
} | ||
|
||
private static void applyText( | ||
@Nullable final TextView textView, | ||
@NonNull final Spanned text, | ||
@NonNull final TextView.BufferType bufferType, | ||
@NonNull final Runnable onComplete) { | ||
if (textView != null) { | ||
textView.post(new Runnable() { | ||
@Override | ||
public void run() { | ||
textView.setText(text, bufferType); | ||
onComplete.run(); | ||
} | ||
}); | ||
} | ||
} | ||
} |
Oops, something went wrong.