Shahzeb
Shahzeb

Reputation: 3734

Apply Spannable to string in string.xml through parameter

I have the following String defined in string.xml

<string name="photo_heading"><xliff:g name="name">%s</xliff:g> shared a <xliff:g name="permission">%s</xliff:g><xliff:g name="photo">%s</xliff:g> with you.</string>

The String accepts 3 string parameters: name, permission, photo

I have two methods that set different style.

public Spannable getStyledItalic(String text) {
        Spannable sb = new SpannableString(text);
        sb.setSpan(new StyleSpan(Typeface.ITALIC), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        return sb;
    }

and

public Spannable getStyledName(String name) {
        Spannable sb = new SpannableString(name);
        sb.setSpan(new AbsoluteSizeSpan(LPConstants.FONT_SIZE_NAME), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        sb.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        sb.setSpan(new ForegroundColorSpan(mContext.getResources().getColor(R.color.app_primary)), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        return sb;
    }

Now I apply these styles to different parameters and return the string but this is not working. Here is what I am doing:

public String getHeading(Printrequest printRequest) {
        String name = printRequest.sentbyname;
        String permission;
        String photo;
        if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) {
            permission =  printRequest.mediaobject.permission;
        } else {
            permission = "";
        }
        if (printRequest.mediaobject.hyperphoto != null) {
            photo = " " + getStyledItalic(mContext.getString(R.string.hyperphoto));
        } else {
            photo = " " + mContext.getString(R.string.photo);
        }

        String heading = mContext.getString(R.string.photo_heading, getStyledName(name), getStyledItalic(permission), photo);

        return heading;
    }

I know we can concatenate Spannable with TextUtils.concat(...) but my case is different.

SOLUTION

Kindly check the solution below. @Krislarson solution is also another way of doing it.

Upvotes: 5

Views: 4129

Answers (2)

Shahzeb
Shahzeb

Reputation: 3734

I needed TextUtils.expandTemplate(...). Thanks to @pskink for pointing out and @krislarson for his efforts.

<string name="photo_heading"><xliff:g name="name">^1</xliff:g> shared a<xliff:g name="permission">^2</xliff:g> <xliff:g name="photo">^3</xliff:g> with you.</string>

and

public CharSequence getHeading(Printrequest printRequest) {
        String name = printRequest.sentbyname;
        String permission;
        CharSequence photo;
        if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) {
            permission =  " " + printRequest.mediaobject.permission;
        } else {
            permission = "";
        }
        if (printRequest.mediaobject.hyperphoto != null) {
            photo = getStyledItalic(mContext.getString(R.string.hyperphoto));
        } else {
            photo = mContext.getString(R.string.photo);
        }

        return TextUtils.expandTemplate(mContext.getString(R.string.photo_heading), getStyledName(mContext, name), getStyledItalic(permission), photo);
    }

Upvotes: 1

kris larson
kris larson

Reputation: 30985

Here is how to do this with a SpannableStringBuilder. Note that the return type has been changed to CharSequence to accomodate the Spannable string that is built. You can pass the return value directly to TextView.setText().

    public CharSequence getHeading(Printrequest printRequest) {
        String name = printRequest.sentbyname;
        String permission;
        if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) {
            permission =  printRequest.mediaobject.permission;
        } else {
            permission = "";
        }

        String photoHeading = mContext.getString(R.string.photo_heading);
        SpannableStringBuilder builder = new SpannableStringBuilder(photoHeading);

        int pos = builder.toString().indexOf("%s");
        builder.replace(pos, pos+2, getStyledName(name));
        pos = builder.toString().indexOf("%s");
        builder.replace(pos, pos+2, getStyledItalic(permission));
        pos = builder.toString().indexOf("%s");
        if (printRequest.mediaobject.hyperphoto != null) {
            builder.replace(pos, pos+2, getStyledItalic(mContext.getString(R.string.hyperphoto)));
            builder.insert(pos, " ");
        } else {
            builder.replace(pos, pos+2, mContext.getString(R.string.photo));
            builder.insert(pos, " ");
        }

        return builder;
    }

Upvotes: 5

Related Questions