Add OrderedListItemSpan measure utility method
This commit is contained in:
parent
cb917e7391
commit
b2a467ffe9
@ -36,7 +36,6 @@ dependencies {
|
|||||||
implementation it['okhttp']
|
implementation it['okhttp']
|
||||||
implementation it['prism4j']
|
implementation it['prism4j']
|
||||||
implementation it['debug']
|
implementation it['debug']
|
||||||
implementation it['better-link-movement']
|
|
||||||
implementation it['dagger']
|
implementation it['dagger']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import me.saket.bettermovementmethod.BetterLinkMovementMethod;
|
|
||||||
import ru.noties.debug.Debug;
|
import ru.noties.debug.Debug;
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
public class MainActivity extends Activity {
|
||||||
@ -71,7 +70,7 @@ public class MainActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onMarkdownReady(CharSequence markdown) {
|
public void onMarkdownReady(CharSequence markdown) {
|
||||||
|
|
||||||
Markwon.setText(textView, markdown, BetterLinkMovementMethod.getInstance());
|
Markwon.setText(textView, markdown);
|
||||||
|
|
||||||
gifProcessor.process(textView);
|
gifProcessor.process(textView);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ task clean(type: Delete) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task wrapper(type: Wrapper) {
|
task wrapper(type: Wrapper) {
|
||||||
gradleVersion '4.8.1'
|
gradleVersion '4.10.2'
|
||||||
distributionType 'all'
|
distributionType 'all'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,6 @@ ext {
|
|||||||
'okhttp' : 'com.squareup.okhttp3:okhttp:3.9.0',
|
'okhttp' : 'com.squareup.okhttp3:okhttp:3.9.0',
|
||||||
'prism4j' : 'ru.noties:prism4j:1.1.0',
|
'prism4j' : 'ru.noties:prism4j:1.1.0',
|
||||||
'debug' : 'ru.noties:debug:3.0.0@jar',
|
'debug' : 'ru.noties:debug:3.0.0@jar',
|
||||||
'better-link-movement' : 'me.saket:better-link-movement-method:2.2.0',
|
|
||||||
'dagger' : "com.google.dagger:dagger:$daggerVersion"
|
'dagger' : "com.google.dagger:dagger:$daggerVersion"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip
|
|
||||||
|
@ -15,6 +15,7 @@ import org.commonmark.parser.Parser;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import ru.noties.markwon.renderer.SpannableRenderer;
|
import ru.noties.markwon.renderer.SpannableRenderer;
|
||||||
|
import ru.noties.markwon.spans.OrderedListItemSpan;
|
||||||
import ru.noties.markwon.tasklist.TaskListExtension;
|
import ru.noties.markwon.tasklist.TaskListExtension;
|
||||||
|
|
||||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||||
@ -100,6 +101,12 @@ public abstract class Markwon {
|
|||||||
unscheduleDrawables(view);
|
unscheduleDrawables(view);
|
||||||
unscheduleTableRows(view);
|
unscheduleTableRows(view);
|
||||||
|
|
||||||
|
// @since 2.0.1 we must measure ordered-list-item-spans before applying text to a TextView.
|
||||||
|
// if markdown has a lot of ordered list items (or text size is relatively big, or block-margin
|
||||||
|
// is relatively small) then this list won't be rendered properly: it will take correct
|
||||||
|
// layout (width and margin) but will be clipped if margin is not _consistent_ between calls.
|
||||||
|
OrderedListItemSpan.measure(view, text);
|
||||||
|
|
||||||
// update movement method (for links to be clickable)
|
// update movement method (for links to be clickable)
|
||||||
view.setMovementMethod(movementMethod);
|
view.setMovementMethod(movementMethod);
|
||||||
view.setText(text);
|
view.setText(text);
|
||||||
|
@ -4,10 +4,44 @@ import android.graphics.Canvas;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.Layout;
|
import android.text.Layout;
|
||||||
|
import android.text.Spanned;
|
||||||
|
import android.text.TextPaint;
|
||||||
import android.text.style.LeadingMarginSpan;
|
import android.text.style.LeadingMarginSpan;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class OrderedListItemSpan implements LeadingMarginSpan {
|
public class OrderedListItemSpan implements LeadingMarginSpan {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process supplied `text` argument and supply TextView paint to all OrderedListItemSpans
|
||||||
|
* in order for them to measure number.
|
||||||
|
* <p>
|
||||||
|
* NB, this method must be called <em>before</em> setting text to a TextView (`TextView#setText`
|
||||||
|
* internally can trigger new Layout creation which will ask for leading margins right away)
|
||||||
|
*
|
||||||
|
* @param textView to which markdown will be applied
|
||||||
|
* @param text parsed markdown to process
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
public static void measure(@NonNull TextView textView, @NonNull CharSequence text) {
|
||||||
|
|
||||||
|
if (!(text instanceof Spanned)) {
|
||||||
|
// nothing to do here
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final OrderedListItemSpan[] spans = ((Spanned) text).getSpans(
|
||||||
|
0,
|
||||||
|
text.length(),
|
||||||
|
OrderedListItemSpan.class);
|
||||||
|
|
||||||
|
if (spans != null) {
|
||||||
|
final TextPaint paint = textView.getPaint();
|
||||||
|
for (OrderedListItemSpan span : spans) {
|
||||||
|
span.margin = (int) (paint.measureText(span.number) + .5F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final SpannableTheme theme;
|
private final SpannableTheme theme;
|
||||||
private final String number;
|
private final String number;
|
||||||
private final Paint paint = ObjectsPool.paint();
|
private final Paint paint = ObjectsPool.paint();
|
||||||
@ -27,8 +61,8 @@ public class OrderedListItemSpan implements LeadingMarginSpan {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLeadingMargin(boolean first) {
|
public int getLeadingMargin(boolean first) {
|
||||||
// @since 1.0.3
|
// @since 2.0.1 we return maximum value of both (now we should measure number before)
|
||||||
return margin > 0 ? margin : theme.getBlockMargin();
|
return Math.max(margin, theme.getBlockMargin());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,11 +78,16 @@ public class OrderedListItemSpan implements LeadingMarginSpan {
|
|||||||
|
|
||||||
theme.applyListItemStyle(paint);
|
theme.applyListItemStyle(paint);
|
||||||
|
|
||||||
final int numberWidth = (int) (p.measureText(number) + .5F);
|
// if we could force usage of #measure method then we might want skip this measuring here
|
||||||
|
// but this won't hold against new values that a TextView can receive (new text size for
|
||||||
|
// example...)
|
||||||
|
final int numberWidth = (int) (paint.measureText(number) + .5F);
|
||||||
|
|
||||||
// @since 1.0.3
|
// @since 1.0.3
|
||||||
int width = theme.getBlockMargin();
|
int width = theme.getBlockMargin();
|
||||||
if (numberWidth > width) {
|
if (numberWidth > width) {
|
||||||
|
// let's keep this logic here in case a user decided not to call #measure and is fine
|
||||||
|
// with current implementation
|
||||||
width = numberWidth;
|
width = numberWidth;
|
||||||
margin = numberWidth;
|
margin = numberWidth;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user