diff --git a/library/src/main/java/com/github/amlcurran/showcaseview/ShowcaseView.java b/library/src/main/java/com/github/amlcurran/showcaseview/ShowcaseView.java index 77de4dd39..4666ff52b 100644 --- a/library/src/main/java/com/github/amlcurran/showcaseview/ShowcaseView.java +++ b/library/src/main/java/com/github/amlcurran/showcaseview/ShowcaseView.java @@ -600,7 +600,8 @@ public Builder setParent(ViewGroup parent, int index) { /** * Sets the paint that will draw the text as specified by {@link #setContentText(CharSequence)} - * or {@link #setContentText(int)} + * or {@link #setContentText(int)}. If you're using a TextAppearance (set by {@link #setStyle(int)}, + * then this {@link TextPaint} will override that TextAppearance. */ public Builder setContentTextPaint(TextPaint textPaint) { showcaseView.setContentTextPaint(textPaint); @@ -609,7 +610,8 @@ public Builder setContentTextPaint(TextPaint textPaint) { /** * Sets the paint that will draw the text as specified by {@link #setContentTitle(CharSequence)} - * or {@link #setContentTitle(int)} + * or {@link #setContentTitle(int)}. If you're using a TextAppearance (set by {@link #setStyle(int)}, + * then this {@link TextPaint} will override that TextAppearance. */ public Builder setContentTitlePaint(TextPaint textPaint) { showcaseView.setContentTitlePaint(textPaint); diff --git a/library/src/main/java/com/github/amlcurran/showcaseview/TextDrawer.java b/library/src/main/java/com/github/amlcurran/showcaseview/TextDrawer.java index 7e37eda61..c8391bf27 100644 --- a/library/src/main/java/com/github/amlcurran/showcaseview/TextDrawer.java +++ b/library/src/main/java/com/github/amlcurran/showcaseview/TextDrawer.java @@ -25,6 +25,7 @@ import android.text.SpannableString; import android.text.TextPaint; import android.text.TextUtils; +import android.text.style.MetricAffectingSpan; import android.text.style.TextAppearanceSpan; /** @@ -42,14 +43,17 @@ class TextDrawer { private final float padding; private final float actionBarOffset; - private Layout.Alignment detailTextAlignment = Layout.Alignment.ALIGN_NORMAL; - private Layout.Alignment titleTextAlignment = Layout.Alignment.ALIGN_NORMAL; - private CharSequence mTitle, mDetails; + private Layout.Alignment textAlignment = Layout.Alignment.ALIGN_NORMAL; + private SpannableString textString; + private DynamicLayout textLayout; + private MetricAffectingSpan textSpan; + + private Layout.Alignment titleAlignment = Layout.Alignment.ALIGN_NORMAL; + private SpannableString titleString; + private DynamicLayout titleLayout; + private MetricAffectingSpan titleSpan; + private float[] mBestTextPosition = new float[3]; - private DynamicLayout mDynamicTitleLayout; - private DynamicLayout mDynamicDetailLayout; - private TextAppearanceSpan mTitleSpan; - private TextAppearanceSpan mDetailSpan; private boolean hasRecalculated; @ShowcaseView.TextPosition private int forcedTextPosition = ShowcaseView.UNDEFINED; @@ -72,29 +76,29 @@ public void draw(Canvas canvas) { float[] textPosition = getBestTextPosition(); int width = Math.max(0, (int) mBestTextPosition[INDEX_TEXT_WIDTH]); - if (!TextUtils.isEmpty(mTitle)) { + if (!TextUtils.isEmpty(titleString)) { canvas.save(); if (hasRecalculated) { - mDynamicTitleLayout = new DynamicLayout(mTitle, titlePaint, - width, titleTextAlignment, 1.0f, 1.0f, true); + titleLayout = new DynamicLayout(titleString, titlePaint, + width, titleAlignment, 1.0f, 1.0f, true); } - if (mDynamicTitleLayout != null) { + if (titleLayout != null) { canvas.translate(textPosition[INDEX_TEXT_START_X], textPosition[INDEX_TEXT_START_Y]); - mDynamicTitleLayout.draw(canvas); + titleLayout.draw(canvas); canvas.restore(); } } - if (!TextUtils.isEmpty(mDetails)) { + if (!TextUtils.isEmpty(textString)) { canvas.save(); if (hasRecalculated) { - mDynamicDetailLayout = new DynamicLayout(mDetails, textPaint, - width, detailTextAlignment, 1.2f, 1.0f, true); + textLayout = new DynamicLayout(textString, textPaint, + width, textAlignment, 1.2f, 1.0f, true); } - float offsetForTitle = mDynamicTitleLayout != null ? mDynamicTitleLayout.getHeight() : 0; - if (mDynamicDetailLayout != null) { + float offsetForTitle = titleLayout != null ? titleLayout.getHeight() : 0; + if (textLayout != null) { canvas.translate(textPosition[INDEX_TEXT_START_X], textPosition[INDEX_TEXT_START_Y] + offsetForTitle); - mDynamicDetailLayout.draw(canvas); + textLayout.draw(canvas); canvas.restore(); } @@ -106,16 +110,16 @@ public void draw(Canvas canvas) { public void setContentText(CharSequence details) { if (details != null) { SpannableString ssbDetail = new SpannableString(details); - ssbDetail.setSpan(mDetailSpan, 0, ssbDetail.length(), 0); - mDetails = ssbDetail; + ssbDetail.setSpan(textSpan, 0, ssbDetail.length(), 0); + textString = ssbDetail; } } public void setContentTitle(CharSequence title) { if (title != null) { SpannableString ssbTitle = new SpannableString(title); - ssbTitle.setSpan(mTitleSpan, 0, ssbTitle.length(), 0); - mTitle = ssbTitle; + ssbTitle.setSpan(titleSpan, 0, ssbTitle.length(), 0); + titleString = ssbTitle; } } @@ -194,13 +198,13 @@ public void calculateTextPosition(int canvasW, int canvasH, boolean shouldCentre } public void setTitleStyling(int styleId) { - mTitleSpan = new TextAppearanceSpan(this.context, styleId); - setContentTitle(mTitle); + titleSpan = new TextAppearanceSpan(this.context, styleId); + setContentTitle(titleString); } public void setDetailStyling(int styleId) { - mDetailSpan = new TextAppearanceSpan(this.context, styleId); - setContentText(mDetails); + textSpan = new TextAppearanceSpan(this.context, styleId); + setContentText(textString); } public float[] getBestTextPosition() { @@ -208,23 +212,33 @@ public float[] getBestTextPosition() { } public boolean shouldDrawText() { - return !TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mDetails); + return !TextUtils.isEmpty(titleString) || !TextUtils.isEmpty(textString); } public void setContentPaint(TextPaint contentPaint) { textPaint.set(contentPaint); + if (textString != null) { + textString.removeSpan(textSpan); + } + textSpan = new NoOpSpan(); + setContentText(textString); } public void setTitlePaint(TextPaint textPaint) { titlePaint.set(textPaint); + if (titleString != null) { + titleString.removeSpan(titleSpan); + } + titleSpan = new NoOpSpan(); + setContentTitle(titleString); } public void setDetailTextAlignment(Layout.Alignment textAlignment) { - this.detailTextAlignment = textAlignment; + this.textAlignment = textAlignment; } public void setTitleTextAlignment(Layout.Alignment titleTextAlignment) { - this.titleTextAlignment = titleTextAlignment; + this.titleAlignment = titleTextAlignment; } public void forceTextPosition(@ShowcaseView.TextPosition int textPosition) { @@ -233,4 +247,16 @@ public void forceTextPosition(@ShowcaseView.TextPosition int textPosition) { } forcedTextPosition = textPosition; } + + private static class NoOpSpan extends MetricAffectingSpan { + @Override + public void updateDrawState(TextPaint tp) { + // No-op + } + + @Override + public void updateMeasureState(TextPaint p) { + // No-op + } + } } diff --git a/sample/src/main/java/com/github/amlcurran/showcaseview/sample/CustomTextActivity.java b/sample/src/main/java/com/github/amlcurran/showcaseview/sample/CustomTextActivity.java index 2fa9214b6..f08bad8b7 100644 --- a/sample/src/main/java/com/github/amlcurran/showcaseview/sample/CustomTextActivity.java +++ b/sample/src/main/java/com/github/amlcurran/showcaseview/sample/CustomTextActivity.java @@ -1,6 +1,7 @@ package com.github.amlcurran.showcaseview.sample; import android.app.Activity; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.os.Bundle; @@ -21,19 +22,21 @@ protected void onCreate(Bundle savedInstanceState) { TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG); paint.setTextSize(getResources().getDimension(R.dimen.abc_text_size_body_1_material)); paint.setStrikeThruText(true); + paint.setColor(Color.RED); paint.setTypeface(Typeface.createFromAsset(getAssets(), "RobotoSlab-Regular.ttf")); TextPaint title = new TextPaint(Paint.ANTI_ALIAS_FLAG); title.setTextSize(getResources().getDimension(R.dimen.abc_text_size_headline_material)); title.setUnderlineText(true); + title.setColor(Color.YELLOW); title.setTypeface(Typeface.createFromAsset(getAssets(), "RobotoSlab-Regular.ttf")); ShowcaseView showcaseView = new ShowcaseView.Builder(this) .withNewStyleShowcase() .setTarget(new ViewTarget(R.id.imageView, this)) + .setContentTextPaint(paint) .setContentTitle(R.string.custom_text_painting_title) .setContentText(R.string.custom_text_painting_text) - .setContentTextPaint(paint) .setContentTitlePaint(title) .build();