text = text + CepVizyon.getPhoneCode() + "\n\n"
+ getText(R.string.currentversion) + CepVizyon.getLicenseText();
activationText.setText(text);
myTextView.setText(text);
CepVizyon.getPhoneCode()
の文字列の色を変更したい。これどうやってするの?
text = text + CepVizyon.getPhoneCode() + "\n\n"
+ getText(R.string.currentversion) + CepVizyon.getLicenseText();
activationText.setText(text);
myTextView.setText(text);
CepVizyon.getPhoneCode()
の文字列の色を変更したい。これどうやってするの?
回答:
Spannableはより柔軟です:
String text2 = text + CepVizyon.getPhoneCode() + "\n\n"
+ getText(R.string.currentversion) + CepVizyon.getLicenseText();
Spannable spannable = new SpannableString(text2);
spannable.setSpan(new ForegroundColorSpan(Color.WHITE), text.length(), (text + CepVizyon.getPhoneCode()).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
myTextView.setText(spannable, TextView.BufferType.SPANNABLE);
()
後text.length
ようlength
な方法ではない分野です。私はそれを自分で行いますが、編集は少なくとも6文字でなければなりません:)
Html.fromHtml(R.id.your_html_string);
色が必要な静的テキストがある場合は、文字列ファイルを介してコードなしで追加できます。
<string name="already_have_an_account">Already have an account? <font color='#01C6DB'>Login</font></string>
その後
<TextView
android:layout_width="wrap_content"
android:layout_height="64dp"
android:text="@string/already_have_an_account"/>
結果
これが機能するAPIバージョンはわかりませんが、これまでにテストされたAPI 19では機能しないため、おそらく最新のAPIバージョンの一部のみがこれをサポートしています。
編集:@hairraisinがコメントで言及されているように、フォントの色ではfgcolor
なくを使用してみてくださいcolor
、それはより低いAPIレベルで機能するはずですが、確認するためにさらにテストが必要です
<font fgcolor=...
API 15とAPI 25 を使用してテストに成功しました(ただし、特に19はテストしていません)
いいですよ!
Spannable spannable = new SpannableString("ABC In-Network DEF");
String str = spannable.toString();
iStart = str.indexOf("In-Network");
iEnd = iStart + 10;/*10 characters = in-network. */
SpannableString ssText = new SpannableString(spannable);
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
//your code at here.
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(true);
ds.setColor(getResources().getColor(R.color.green));
}
};
ssText.setSpan(clickableSpan, iStart, iEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextView.setText(ssText);
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
mTextView.setHighlightColor(Color.TRANSPARENT);
mTextView.setEnabled(true);
SpannableString
文字列の一部の色を変更するために使用するKotlinのソリューション。
val phoneCodeColor = ContextCompat.getColor(this, R.color.myColor)
val text = SpannableStringBuilder()
.color(phoneCodeColor) { append("${ CepVizyon.getPhoneCode() }") }
.append("\n\n")
.append(getString(R.string.currentversion))
.append(${ CepVizyon.getLicenseText() })
activationText.text = text
myTextView.text = text
以下はcolorize
、andybootの回答に基づく関数です。
/**
* Colorize a specific substring in a string for TextView. Use it like this: <pre>
* textView.setText(
* Strings.colorized("The some words are black some are the default.","black", Color.BLACK),
* TextView.BufferType.SPANNABLE
* );
* </pre>
* @param text Text that contains a substring to colorize
* @param word The substring to colorize
* @param argb The color
* @return the Spannable for TextView's consumption
*/
public static Spannable colorized(final String text, final String word, final int argb) {
final Spannable spannable = new SpannableString(text);
int substringStart=0;
int start;
while((start=text.indexOf(word,substringStart))>=0){
spannable.setSpan(
new ForegroundColorSpan(argb),start,start+word.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
substringStart = start+word.length();
}
return spannable;
}
私がすべてのアプリで頻繁に行っているテキストの一部に色を付けたいときはいつでもコードでこれを行うという考えが好きではありませんでした定義された色)私は自分で作成しましたMarkableTextView
。
アイデアは:
プロセスは次のとおりです。
最初に、特定の文字列でXMLタグを検索する方法が必要でしたRegex
。
<([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)(?:\s+([^>]*))?>([^>][^<]*)</\1\s*>
上記がXMLタグと一致するには、次の基準が必要です。
<a>
<a >
<a-a>
<a ..attrs..>
ではなく、< a>
<1>
<a></a>
ない終了タグ<a></b>
次に、属性にこれを使用します。
([a-zA-Z]+)\s*=\s*(['"])\s*([^'"]+?)\s*\2
それは同じ概念を持っています、そして、何かがフォーマットから出た場合、コンパイラが残りを処理するので、一般的に私は両方のために遠くに行く必要はありませんでした。
次に、抽出されたデータを保持できるクラスが必要です。
public class MarkableSheet {
private String attributes;
private String content;
private int outset;
private int ending;
private int offset;
private int contentLength;
public MarkableSheet(String attributes, String content, int outset, int ending, int offset, int contentLength) {
this.attributes = attributes;
this.content = content;
this.outset = outset;
this.ending = ending;
this.offset = offset;
this.contentLength = contentLength;
}
public String getAttributes() {
return attributes;
}
public String getContent() {
return content;
}
public int getOutset() {
return outset;
}
public int getContentLength() {
return contentLength;
}
public int getEnding() {
return ending;
}
public int getOffset() {
return offset;
}
}
何よりもまず、マッチをループするために長い間使用してきたこのクールなイテレータを追加します(作成者を思い出せません)。
public static Iterable<MatchResult> matches(final Pattern p, final CharSequence input) {
return new Iterable<MatchResult>() {
public Iterator<MatchResult> iterator() {
return new Iterator<MatchResult>() {
// Use a matcher internally.
final Matcher matcher = p.matcher(input);
// Keep a match around that supports any interleaving of hasNext/next calls.
MatchResult pending;
public boolean hasNext() {
// Lazily fill pending, and avoid calling find() multiple times if the
// clients call hasNext() repeatedly before sampling via next().
if (pending == null && matcher.find()) {
pending = matcher.toMatchResult();
}
return pending != null;
}
public MatchResult next() {
// Fill pending if necessary (as when clients call next() without
// checking hasNext()), throw if not possible.
if (!hasNext()) { throw new NoSuchElementException(); }
// Consume pending so next call to hasNext() does a find().
MatchResult next = pending;
pending = null;
return next;
}
/** Required to satisfy the interface, but unsupported. */
public void remove() { throw new UnsupportedOperationException(); }
};
}
};
}
MarkableTextView:
public class MarkableTextView extends AppCompatTextView {
public MarkableTextView(Context context) {
super(context);
}
public MarkableTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarkableTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setText(CharSequence text, BufferType type) {
// Intercept and process text
text = prepareText(text.toString());
super.setText(text, type);
}
public Spannable Markable;
private Spannable prepareText(String text) {
String parcel = text;
Multimap<String, MarkableSheet> markableSheets = ArrayListMultimap.create();
// Used to correct content position after tossing tags
int totalOffset = 0;
// Iterate through text
for (MatchResult match : matches(Markable.Patterns.XML, parcel)) {
// Get tag name
String tag = match.group(1);
// Match with a defined tag name "case-sensitive"
if (!tag.equals(Markable.Tags.MARKABLE)) {
// Break if no match
break;
}
// Extract data
String attributes = match.group(2);
String content = match.group(3);
int outset = match.start(0);
int ending = match.end(0);
int offset = totalOffset; // offset=0 since no preceded changes happened
int contentLength = match.group(3).length();
// Calculate offset for the next element
totalOffset = (ending - outset) - contentLength;
// Add to markable sheets
MarkableSheet sheet =
new MarkableSheet(attributes, content, outset, ending, offset, contentLength);
markableSheets.put(tag, sheet);
// Toss the tag and keep content
Matcher reMatcher = Markable.Patterns.XML.matcher(parcel);
parcel = reMatcher.replaceFirst(content);
}
// Initialize spannable with the modified text
Markable = new SpannableString(parcel);
// Iterate through markable sheets
for (MarkableSheet sheet : markableSheets.values()) {
// Iterate through attributes
for (MatchResult match : matches(Markable.Patterns.ATTRIBUTES, sheet.getAttributes())) {
String attribute = match.group(1);
String value = match.group(3);
// Apply styles
stylate(attribute,
value,
sheet.getOutset(),
sheet.getOffset(),
sheet.getContentLength());
}
}
return Markable;
}
最後に、スタイリング、それで私がこの答えのために作った非常にシンプルなスタイラーです:
public void stylate(String attribute, String value, int outset, int offset, int length) {
// Correct position
outset -= offset;
length += outset;
if (attribute.equals(Markable.Tags.TEXT_STYLE)) {
if (value.contains(Markable.Tags.BOLD) && value.contains(Markable.Tags.ITALIC)) {
Markable.setSpan(
new StyleSpan(Typeface.BOLD_ITALIC),
outset,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if (value.contains(Markable.Tags.BOLD)) {
Markable.setSpan(
new StyleSpan(Typeface.BOLD),
outset,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if (value.contains(Markable.Tags.ITALIC)) {
Markable.setSpan(
new StyleSpan(Typeface.ITALIC),
outset,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (value.contains(Markable.Tags.UNDERLINE)) {
Markable.setSpan(
new UnderlineSpan(),
outset,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
if (attribute.equals(Markable.Tags.TEXT_COLOR)) {
if (value.equals(Markable.Tags.ATTENTION)) {
Markable.setSpan(
new ForegroundColorSpan(ContextCompat.getColor(
getContext(),
R.color.colorAttention)),
outset,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if (value.equals(Markable.Tags.INTERACTION)) {
Markable.setSpan(
new ForegroundColorSpan(ContextCompat.getColor(
getContext(),
R.color.colorInteraction)),
outset,
length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
そしてMarkable
、定義を含むクラスは次のようになります。
public class Markable {
public static class Patterns {
public static final Pattern XML =
Pattern.compile("<([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)(?:\\s+([^>]*))?>([^>][^<]*)</\\1\\s*>");
public static final Pattern ATTRIBUTES =
Pattern.compile("(\\S+)\\s*=\\s*(['\"])\\s*(.+?)\\s*\\2");
}
public static class Tags {
public static final String MARKABLE = "markable";
public static final String TEXT_STYLE = "textStyle";
public static final String BOLD = "bold";
public static final String ITALIC = "italic";
public static final String UNDERLINE = "underline";
public static final String TEXT_COLOR = "textColor";
public static final String ATTENTION = "attention";
public static final String INTERACTION = "interaction";
}
}
今必要なのは文字列を参照することだけで、基本的には次のようになります。
<string name="markable_string">
<![CDATA[Hello <markable textStyle=\"underline\" textColor=\"interaction\">world</markable>!]]>
</string>
タグは必ずa CDATA Section
で囲み、でエスケープ"
してください\
。
私は、不要なコードを背後に詰め込む必要なしに、テキストの一部をさまざまな方法で処理するためのモジュラーソリューションとしてこれを作成しました。
私はこの小さな関数を作成しました。テキストに色を渡し、そのテキストの色にしたいものの開始インデックスと終了インデックス、および色自体を渡します
private fun colorMyText(inputText:String,startIndex:Int,endIndex:Int,textColor:Int):Spannable{
val outPutColoredText: Spannable = SpannableString(inputText)
outPutColoredText.setSpan(
ForegroundColorSpan(textColor), startIndex, endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
return outPutColoredText
}
txt_comment.text = colorMyText("Comentario: ${item.comentario}",0,13,Color.BLACK)
文字列を文字列リソースフォルダに格納する方法
<string name="textFromRes">
<font color="#FF0000">This is colored in red </font> This is not
</string>
TextViewで表示する方法?
String text = this.getResources().getString(R.string.textFromRes);
htmlText.setText(Html.fromHtml(text));
出力の文字列は次のようになります
<string name="textFromRes">
<font color="#FF0000">This is colored in red </font> This is not
<br />
<h1> This is h1 heading </h1>
<br />
<h3> This is h2 subheading</h3>
<br />
<b> This text is bold</b>
<br />
<i> This text is italic</i>
<br />
Android users expect your app to look and behave in a way that is
consistent with the platform. Not only should you follow material
design guidelines for visual and navigation patterns,
but you should also follow quality guidelines for compatibility,
performance, security, and more.
<br />
<br />
The following links provide everything you need to design a high quality Android app.
</string>
汎用のKotlin拡張関数を使用すると、次のようになります。
/**
* Change the color of a part of the text contained in this textView
*
* @param subStringToColorize has to already be set in the textView's text
* @param colorResId
*/
fun TextView.colorize(subStringToColorize: String, @ColorRes colorResId: Int) {
val spannable: Spannable = SpannableString(text)
val startIndex = text.indexOf(subStringToColorize, startIndex = 0, ignoreCase = false)
val endIndex = startIndex + subStringToColorize.length
val color = if (/* Your code for isMarshmallowOrUp() */ ) {
this.context.getColor(colorResId)
} else {
this.context.resources.getColor(colorResId)
}
spannable.setSpan(ForegroundColorSpan(color),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
this.setText(spannable, TextView.BufferType.SPANNABLE)
}
1つの方法は、myTextView
いくつかに分割するTextViews
ことです。そのうちの1つは電話コード専用です。次に、この特定の色を制御することTextView
は非常に簡単です。