Android.widget.TextView рдореЗрдВ рдорд╛рд░реНрдХрдЕрдк рдкрд╛рда

рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореБрдЭреЗ рдПрдХ Android рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдПрдХ рдмрд╣реБрдд рд╣реА рдЪрддреБрд░ рдЪреИрдЯ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрджреЗрд╢ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛: рд╕рдВрджреЗрд╢ рдХреЗ рд▓реЗрдЦрдХ рдХрд╛ рдирд╛рдо рдЙрд╕ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкрд╛рда рдмреЙрдХреНрд╕ рдореЗрдВ рдбрд╛рд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдпрджрд┐ рдпрд╣ рдПрдХ рдирдП рдмрдирд╛рдП рдЧрдП рдЧреЗрдо рд╕рддреНрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕рдВрджреЗрд╢ рд╣реИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рдЦреЗрд▓ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕реА рддрд░рд╣ред ред рдореБрдЦреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдПрдХ рд╕рдВрджреЗрд╢ рдмрдирд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдереА рдЬрд┐рд╕рдореЗрдВ рдХрдИ рд▓рд┐рдВрдХ рд╣реЛрддреЗ рдереЗ, рдЬреЛ рдЕрдиреБрд╕рдВрдзрд╛рди рдХреА рджрд┐рд╢рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рдереЗред

рд╡реЗрдмрд╡реНрдпреВ , рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг, рдирд┐рд░реНрдгрдп рдХреА рдЧрдВрднреАрд░рддрд╛ рдХреЗ рдХрд╛рд░рдг рдЦрд╛рд░рд┐рдЬ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛: рдореИрдВрдиреЗ рдкрд░реАрдХреНрд╖рдг рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП 100 рдпрд╛ рдХреЛрдИ рдЙрджрд╛рд╣рд░рдг рднреА рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдерд╛, рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рддреБрд░рдВрдд рд╕реНрдкрд╖реНрдЯ рдерд╛ рдХрд┐ рдпрд╣ рд╕реНрдХреНрд╡реИрдбрд░рд┐рдВрдЧ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред

рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╕рдмрд╕реЗ рд╕рд╛рдзрд╛рд░рдг TextView рдореЗрдВ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд░реВрдк рд╕реЗ рднрдпрд╛рдирдХ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЖрдЙрдЯ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдЕрд▓рдЧ рддрддреНрд╡ рдпрд╛ рдкреВрд░реЗ рдкреГрд╖реНрда рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ WebView рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рд╣рд▓реНрдХрд╛ рд╣реИред

рдореИрдВрдиреЗ рдЕрдкрдиреА рдЬрд╝рд░реВрд░рдд рдХреА рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдФрд░ рдХреБрдЫ рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рдЪреАрдЬрд╝реЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛, рдЬрд┐рдирдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдиреБрдХрд╕рд╛рди рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ (рд╣рд╛рд▓рд╛рдБрдХрд┐ рдмрд╣реБрдд рддреЗрдЬрд╝ рдирд╣реАрдВ рдереЗ)ред рдпрд╣ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рд╕рдм рдХреБрдЫ рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдореЗрдВ рд▓рдЧрднрдЧ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рдлреА рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рд╣рд╛рдпрддрд╛ рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рд╣реИред

рдХрд╛рд░реНрдп


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рджреЛ рдЧрддрд┐рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВрдЧреЗ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдПрдХ TextView рд╣реИ рдЬреЛ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЖрдк рджреВрд╕рд░реА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреЙрд▓ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рдо рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗ рдХрд┐ рдорд╛рд░реНрдХрдЕрдк рдФрд░ рдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рдкрд╛рда рдХреЗ рдкреГрд╖реНрда рдХреИрд╕реЗ рдмрдирд╛рдПрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рд▓рд┐рдВрдХ рдХрд░реЗрдВред

рдкреГрд╖реНрдареЛрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рддрд╛рд░ рд╕реЗ рд▓реА рдЧрдИ рд╣реИ, рдФрд░ рдЪрд┐рддреНрд░ рдЦреАрдВрдЪрдиреЗ рдпреЛрдЧреНрдп рд╕рдВрд╕рд╛рдзрди рд╣реИрдВред рдХреЛрдб рдореЗрдВ рдЫреЛрдЯреЗ рдкрд░рд┐рд╡рд░реНрддрди рдЕрдиреНрдп рд╕реНрдерд╛рдиреЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред



рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдирд┐рд░реНрдорд╛рдг


рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ, рд╣рдо рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдмрдирд╛рддреЗ рд╣реИрдВ:

AndroidMainfest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.markup.tutorial" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/title_activity_main"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".AnotherActivity" android:exported="false"> <intent-filter> <data android:scheme="activity-run" android:host="AnotherActivityHost" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest> 

рдкреНрд░рдХрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдгред рдпрджрд┐ рдкрд╣рд▓реА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рддреЛ рджреВрд╕рд░реА ( рдЕрдиреНрдпрддрд╛ ) рдореЗрдВ рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╡рд░рдг рд╣реИрдВред

Android: рдирд┐рд░реНрдпрд╛рддрд┐рдд = "рдЭреВрдард╛" рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рд╕рдВрдХрд▓рдХ рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рди рджреЗ рдХрд┐ рд╣рдо рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдП рдЧрдП рдШрдЯрдХ рдореЗрдВ рдХреБрдЫ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рднреВрд▓ рдЧрдПред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдПрдХ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╕рдЬрд╛рд╡рдЯреА рдХреНрд╖рдг, рд▓реЗрдХрд┐рди рдХрдо рдкреАрд▓реЗ рддреНрд░рд┐рдХреЛрдг - рд╢рд╛рдВрддред

рдЖрд╢рдп-рдлрд╝рд┐рд▓реНрдЯрд░ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдпрд╣ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреИрд╕реЗ рдФрд░ рдХрд┐рди рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рд╢реБрд░реВ рд╣реЛрдЧреАред

<data android: scheme = "activity-run" android: host = "AnotherActivityHost" /> рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЖрдк рдлреЙрд░реНрдо рдЧрддрд┐рд╡рд┐рдзрд┐- рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: // AnotherActivityHost? params ...

рдЧрддрд┐рд╡рд┐рдзрд┐ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рд╕реНрдЯрдо рджреНрд╡рд╛рд░рд╛ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдФрд░ рд╢реНрд░реЗрдгреА рдореВрд▓реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

MainActivity.java
 package com.example.markup.tutorial; import org.xml.sax.XMLReader; import android.os.Bundle; import android.app.Activity; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.Html; import android.text.Spannable; import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.widget.TextView; public class MainActivity extends Activity { TextView tvContent; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvContent = (TextView)findViewById(R.id.tvContent); tvContent.setLinksClickable(true); tvContent.setMovementMethod(new LinkMovementMethod()); setArticle("article_main"); } void setArticle(String strArticleResId) { int articleResId = getResources().getIdentifier(strArticleResId, "string", getPackageName()); String text = getString(articleResId); if (text == null) text = "Article not found"; Spanned spannedText = Html.fromHtml(text, htmlImageGetter, htmlTagHandler); Spannable reversedText = revertSpanned(spannedText); tvContent.setText(reversedText); } final Spannable revertSpanned(Spanned stext) { Object[] spans = stext.getSpans(0, stext.length(), Object.class); Spannable ret = Spannable.Factory.getInstance().newSpannable(stext.toString()); if (spans != null && spans.length > 0) { for(int i = spans.length - 1; i >= 0; --i) { ret.setSpan(spans[i], stext.getSpanStart(spans[i]), stext.getSpanEnd(spans[i]), stext.getSpanFlags(spans[i])); } } return ret; } Html.ImageGetter htmlImageGetter = new Html.ImageGetter() { public Drawable getDrawable(String source) { int resId = getResources().getIdentifier(source, "drawable", getPackageName()); Drawable ret = MainActivity.this.getResources().getDrawable(resId); ret.setBounds(0, 0, ret.getIntrinsicWidth(), ret.getIntrinsicHeight()); return ret; } }; Html.TagHandler htmlTagHandler = new Html.TagHandler() { public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { Object span = null; if (tag.startsWith("article_")) span = new ArticleSpan(MainActivity.this, tag); else if ("title".equalsIgnoreCase(tag)) span = new AppearanceSpan(0xffff2020, AppearanceSpan.NONE, 20, true, true, false, false); else if (tag.startsWith("color_")) span = new ParameterizedSpan(tag.substring(6)); if (span != null) processSpan(opening, output, span); } }; void processSpan(boolean opening, Editable output, Object span) { int len = output.length(); if (opening) { output.setSpan(span, len, len, Spannable.SPAN_MARK_MARK); } else { Object[] objs = output.getSpans(0, len, span.getClass()); int where = len; if (objs.length > 0) { for(int i = objs.length - 1; i >= 0; --i) { if (output.getSpanFlags(objs[i]) == Spannable.SPAN_MARK_MARK) { where = output.getSpanStart(objs[i]); output.removeSpan(objs[i]); break; } } } if (where != len) { output.setSpan(span, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } } 

AnotherActivity.java
 package com.example.markup.tutorial; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.net.Uri; import android.os.Bundle; public class AnotherActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Uri uri = getIntent().getData(); String caption = uri.getQueryParameter("caption"); String text = uri.getQueryParameter("text"); new AlertDialog.Builder(this) .setTitle(caption) .setMessage(text) .setPositiveButton("OK", dioclOK) .setCancelable(false) .create().show(); } DialogInterface.OnClickListener dioclOK = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); finish(); } }; } 

AppearanceSpan.java
 package com.example.markup.tutorial; import android.text.TextPaint; import android.text.style.CharacterStyle; public class AppearanceSpan extends CharacterStyle { public static final int NONE = -1; final int color, bgColor, textSize; final boolean boldText, italicText, strikeThruText, underlineText; public AppearanceSpan(int color, int bgColor, int textSize, boolean boldText, boolean italicText, boolean strikeThruText, boolean underlineText) { this.color = color; this.bgColor = bgColor; this.textSize = textSize; this.boldText = boldText; this.italicText = italicText; this.strikeThruText = strikeThruText; this.underlineText = underlineText; } @Override public void updateDrawState(TextPaint tp) { if (color != NONE) tp.setColor(color); if (bgColor != NONE) tp.bgColor = bgColor; tp.setFakeBoldText(boldText); tp.setStrikeThruText(strikeThruText); if (textSize != NONE) tp.setTextSize(textSize); tp.setUnderlineText(underlineText); tp.setTextSkewX(italicText ? -0.25f : 0); } } 

ArticleSpan.java
 package com.example.markup.tutorial; import android.text.style.ClickableSpan; import android.view.View; public class ArticleSpan extends ClickableSpan { final MainActivity activity; final String articleId; public ArticleSpan(MainActivity activity, String articleId) { super(); this.activity = activity; this.articleId = articleId; } @Override public void onClick(View arg0) { activity.setArticle(articleId); } } 

ParameterizedSpan.java
 package com.example.markup.tutorial; import android.graphics.Color; import android.text.TextPaint; import android.text.style.CharacterStyle; public class ParameterizedSpan extends CharacterStyle { int color = 0; public ParameterizedSpan(String param) { try { color = Color.parseColor("#" + param); } catch(Exception ex) { } } @Override public void updateDrawState(TextPaint tp) { tp.setColor(color); } } 


рд╕рдВрд╕рд╛рдзрди рдХреА рддреИрдпрд╛рд░реА


рд▓реЗрдЖрдЙрдЯ / activity_main.xml
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ScrollView android:id="@+id/sv" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/tvContent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Content" /> </ScrollView> </RelativeLayout> 

рдорд╛рди / рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ред xml
 <resources> <string name="app_name">MarkupTutor</string> <string name="hello_world">Hello world!</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">MainActivity</string> <string name="article_main" formatted="false"><![CDATA[ <title> </title><br/> <br/> <img src="res_pushkin_little"> <article_pushkin_stih>..  "   "</article_pushkin_stih><br/> <img src="res_activity_little"> <a href="activity-run://AnotherActivityHost?caption=Another%20Activity&text=Hello%20from%20markup!">  Activity</a><br/> <br/> <color_ff00ff00>   <color_ffff00ff>  </color_ffff00ff>.</color_ff00ff00><br/>   GIF-:<br/> <img src="res_alien_anim"> ]]></string> <string name="article_pushkin_stih" formatted="false"><![CDATA[ <br/><article_main> </article_main><br/><br/> <img src="res_pushkin" /><br/><br/>  ,    ,<br/>   <br/>  ,   ,<br/>   .<br/>     ,<br/>    -    -<br/>   ,<br/><br/>    .<br/> ,  ,<br/> ,  ,<br/> ,  ,  .<br/> -, , .<br/>  , , <br/>     ,<br/>   <br/>   ,<br/>    :<br/>     -<br/>   <br/>    .<br/>    ,<br/> , ,<br/> , <br/>  !..<br/> ,   .<br/>       ,<br/>     .<br/>     ?<br/>  -<br/> (,    )<br/>    -<br/>    ...<br/> , ,  ,<br/>    .<br/> ]]></string> </resources> 


рдорд╛рд░реНрдХрдЕрдк рд╡рд╛рд▓реА рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рд╕реНрд╡рд░реВрдкрд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕реАрдбреАрдПрдЯреАрдП рдмреНрд▓реЙрдХ рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рд╕рдВрдХрд▓рдХ рдХреЛ рдорд╛рд░реНрдХрдЕрдк рдФрд░ рд╡рд┐рд╢реЗрд╖ рдкрд╛рддреНрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рд╢рд┐рдХрд╛рдпрдд рди рд╣реЛред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд▓реЗрдЦ рд▓рд╛рдЗрди рдирд╛рдо рдореЗрдВ article_ рдХреЗ рд╕рд╛рде рдЙрдкрд╕рд░реНрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдПрдХ рдЕрдЬреАрдм рдЧрдбрд╝рдмрдбрд╝ рднреА рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИ, рдЬреЛ рдЗрд╕ рддрдереНрдп рдореЗрдВ рд╣реА рдкреНрд░рдХрдЯ рд╣реЛрддреА рд╣реИ рдХрд┐ рдпрджрд┐ рдкрд╛рда рдПрдХ рдЯреИрдЧ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЙрд╕реА рдЯреИрдЧ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдПрдХ рд▓рд┐рдВрдХ рд╣реИ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдпрд╛ рддреЛ рдПрдХ рд╕реНрдкреЗрд╕ рдпрд╛ <br/> ред

рдЫрд╡рд┐рдпрд╛рдВ рдмрд┐рдирд╛ рдПрдиреАрдореЗрд╢рди рдХреЗ jpg, png рдпрд╛ gif рдлреЙрд░реНрдореЗрдЯ рдореЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдПрдирд┐рдореЗрдЯреЗрдб рдЬрд┐рдл рдХреЛ рд╕реНрдерд┐рд░ рдЪрд┐рддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕реНрдерд╛рди рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рд╣реИ, рд╡рд┐рднрд┐рдиреНрди рдШрдирддреНрд╡реЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП, рдЖрдк рдЪрд┐рддреНрд░ рдХрд╛ рдЕрдкрдирд╛ рд╕рдВрд╕реНрдХрд░рдг рддреИрдпрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рднреА рдЪрд┐рддреНрд░ рдбреНрд░реЙрдПрдмрд▓-рдиреЙрдбрдкреА рдореЗрдВ рд╣реИрдВ



рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ


рдЖрдЗрдП рдХреЛрдб рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvContent = (TextView)findViewById(R.id.tvContent); tvContent.setLinksClickable(true); tvContent.setMovementMethod(new LinkMovementMethod()); setArticle("article_main"); } 


рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ TextView рдХреЛ рд╡рд┐рд╢реЗрд╖ рдЖрд░рдВрдн рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ:

tvContent.setLinksClickable (рд╕рдЪ); рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрддреНрд╡ рдореЗрдВ рд▓рд┐рдВрдХ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣реИрдВред

tvContent.setMovementMethod (рдирдпрд╛ LinkMovementMethod ()); рдХрд┐рд╕реА рдЖрдЗрдЯрдо рдХреЛ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдмрддрд╛рддрд╛ рд╣реИред рд╣рдордиреЗ рдЬреЛ LinkMovementMethod рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдФрд░ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдХреЗ рд▓рд╛рдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрджрд┐ рдЕрдзрд┐рдХ рдкреВрд░реНрдг рдирд┐рдпрдВрддреНрд░рдг рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рддреЛ рдЖрдк рдПрдХ рд╡рд╛рд░рд┐рд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреА рдУрд╡рд░рд░рд╛рдЗрдб рд╡рд┐рдзрд┐рдпрд╛рдВ рдЖрдкрдХреЛ рддрддреНрд╡ рдореЗрдВ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИрдВред

 void setArticle(String strArticleResId) { int articleResId = getResources().getIdentifier(strArticleResId, "string", getPackageName()); String text = getString(articleResId); if (text == null) text = "Article not found"; Spanned spannedText = Html.fromHtml(text, htmlImageGetter, htmlTagHandler); Spannable reversedText = revertSpanned(spannedText); tvContent.setText(reversedText); } 

рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рд╕реЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕реЗ HTML рд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕реНрдкрд╛рдиреНрдб рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рд╕реНрдкреИрдирдмрд▓ рдореЗрдВ рдПрдХ рдФрд░ рд░реВрдкрд╛рдВрддрд░рдг рдФрд░ рдЯреЗрдХреНрд╕реНрдЯрд╡реНрдпреВ рдХреЛ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рдм рдмрд▓реНрдХрд┐ рдмреЛрдЭрд┐рд▓ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдХрд╛рд░рдг рд╣реИрдВред

рдЯреЗрдХреНрд╕реНрдЯрд╡реНрдпреВ рдореЗрдВ , рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реНрдкреИрди рдХрд╛ рдПрдХ рдЕрдЬреАрдм рдХреНрд░рдо рд╕реВрдЪреА рдХреЗ рдЕрдВрдд рд╕реЗ рд╣реИред HTML рд╕реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╕реНрдкреИрди рдХреА рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреЗ рд╕рд╛рде, рдиреЗрд╕реНрдЯреЗрдб рд╕реНрдкреИрди рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдЙрди рд╕реНрдкреИрди рдХреЗ рдЧреБрдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдУрд╡рд░рд▓реИрдк рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд░рд┐рд╡рд░реНрд╕реНрдкреЗрдВрдб рдХрд┐рдП рдЧрдП рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдЪрдореБрдЪ рдЕрдВрдХрди рдХреЛ рдЕрдВрджрд░ рдмрд╛рд╣рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

 final Spannable revertSpanned(Spanned stext) { Object[] spans = stext.getSpans(0, stext.length(), Object.class); Spannable ret = Spannable.Factory.getInstance().newSpannable(stext.toString()); if (spans != null && spans.length > 0) { for(int i = spans.length - 1; i >= 0; --i) { ret.setSpan(spans[i], stext.getSpanStart(spans[i]), stext.getSpanEnd(spans[i]), stext.getSpanFlags(spans[i])); } } return ret; } 

рдПрдХ рдЫрд╡рд┐ рд▓рд┐рдВрдХ рд╣реИрдВрдбрд▓рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдиреНрдпреВрдирддрдо рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреЗрд╡рд▓ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рд╕реЗ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╣рдо рдПрдХ рд╕рд╣рд╛рдпрддрд╛ рдкреНрд░рдгрд╛рд▓реА рд╡рд┐рдХрд▓реНрдк рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ред рдЖрдкрдХреА рдЕрдиреБрдорддрд┐ рд╕реЗ, рдореИрдВ рдЙрд╕реЗ рдЙрджреНрдзреГрдд рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рдпрджрд┐ рдЖрдк рдЕрдзрд┐рдХ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд▓реЗрдЦ рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред

Html.TagHadler рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛:

 Html.TagHandler htmlTagHandler = new Html.TagHandler() { public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { Object span = null; if (tag.startsWith("article_")) span = new ArticleSpan(MainActivity.this, tag); else if ("title".equalsIgnoreCase(tag)) span = new AppearanceSpan(0xffff2020, AppearanceSpan.NONE, 20, true, true, false, false); else if (tag.startsWith("color_")) span = new ParameterizedSpan(tag.substring(6)); if (span != null) processSpan(opening, output, span); } }; 


рдпрд╣рд╛рдБ рд╣рдо рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рддреЗрдВ рд╣реЛ рд░рд╣реА рд╣реИред

HTML рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдХреЗ Html.fromHtml рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП , br , p , div , em , b , strong , cite , dfn , i , big , small , font , blockquote , tt , a , u , sup , sub , h1...h6 рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред h1...h6 рдФрд░ img ред рдпрджрд┐ рдЯреИрдЧ рдХреЛ рдорд╛рдиреНрдпрддрд╛ рдирд╣реАрдВ рджреА рдЧрдИ рд╣реИ, рддреЛ Html.TagHandler рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬрдм рддрдХ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣ рдХреЙрд▓ рдХреЛ рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ)ред

рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдЯреИрдЧ "рд╣рдорд╛рд░рд╛" рд╣реИ рдФрд░ рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рд╕реНрдкреИрди - рдорд╛рд░реНрдХрдЕрдк рддрддреНрд╡ рдмрдирд╛рдПрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдкрд╛рда рдкрд░ рдереЛрдк рджреЗрдВред рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдХреБрдЫ рд╕реНрдкреИрди рдмрдирд╛рдП, рдЬрд┐рдирдХреА рдЪрд░реНрдЪрд╛ рдмрд╛рдж рдореЗрдВ рдХреА рдЬрд╛рдПрдЧреАред рдЖрдорддреМрд░ рдкрд░, spans android.text.style.CharacterStyle рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реЗ рд╣реИрдВред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд▓рд╛рдЗрдиреЛрдВ рдпрд╛ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХреЛ рдереЛрдбрд╝реЗ рд╕реЗ рд░рдХреНрдд рдХреЗ рд╕рд╛рде рдкреНрд░рдмрдВрдзрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХреНрд╖рдорддрд╛ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк xmlReader рд╕реЗ рдЯреИрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдирд╣реАрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ, рдореБрдЭреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдкрдиреА рд╡рд┐рдзрд┐ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░рдирд╛ рдкрдбрд╝рд╛: рдореВрд▓реНрдп рдЯреИрдЧ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, ParameterizedSpan рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рдВрдЧ рдЯреИрдЧ рдореЗрдВ рд░рдВрдЧ рдорд╛рди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдкреНрд░реЗрд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдпрд╣ <color_ffff0000></color_ffff0000> рдЬреИрд╕рд╛ рдХреБрдЫ рдкрддрд╛ <color_ffff0000></color_ffff0000> ред рдпрд╣ рдПрдХ рдХрд╛рдлреА рд╕реАрдорд┐рдд рдФрд░ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рдХрд┐рд╕реА рд╕реЗ рдмреЗрд╣рддрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

  void processSpan(boolean opening, Editable output, Object span) { int len = output.length(); if (opening) { output.setSpan(span, len, len, Spannable.SPAN_MARK_MARK); } else { Object[] objs = output.getSpans(0, len, span.getClass()); int where = len; if (objs.length > 0) { for(int i = objs.length - 1; i >= 0; --i) { if (output.getSpanFlags(objs[i]) == Spannable.SPAN_MARK_MARK) { where = output.getSpanStart(objs[i]); output.removeSpan(objs[i]); break; } } } if (where != len) { output.setSpan(span, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } 

рдпрд╣ рдХреЛрдб рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ: рдпрджрд┐ рдЦреБрд▓рдиреЗ рд╡рд╛рд▓рд╛ рд╕реНрдкреИрди рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЕрдкрдиреЗ рд╡рд░реНрддрдорд╛рди рд░реВрдк рдореЗрдВ рд▓рд╛рдЗрди рдХреЗ рдЕрдВрдд рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╕реНрдкреИрди рдмрдВрдж рд╣реЛ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рдо рд▓рд╛рдЗрди рдореЗрдВ рдЗрд╕рдХреЗ рд╢реБрд░реБрдЖрддреА рдПрдирд╛рд▓реЙрдЧ рдХреЛ рдвреВрдВрдврддреЗ рд╣реИрдВ, рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╣рдЯрд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдирдпрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдФрд░ рд▓рдВрдмрд╛рдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рдеред

рд╣рдордиреЗ рдЧрддрд┐рд╡рд┐рдзрд┐ рд╡рд░реНрдЧ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХрд╛ рдореБрдЦреНрдп рдореЙрдбреНрдпреВрд▓ рд╣реИред рдЕрдм рд╕рд╣рд╛рдпрдХ рд╡рд░реНрдЧреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

 package com.example.markup.tutorial; import android.text.TextPaint; import android.text.style.CharacterStyle; public class AppearanceSpan extends CharacterStyle { public static final int NONE = -1; final int color, bgColor, textSize; final boolean boldText, italicText, strikeThruText, underlineText; public AppearanceSpan(int color, int bgColor, int textSize, boolean boldText, boolean italicText, boolean strikeThruText, boolean underlineText) { this.color = color; this.bgColor = bgColor; this.textSize = textSize; this.boldText = boldText; this.italicText = italicText; this.strikeThruText = strikeThruText; this.underlineText = underlineText; } @Override public void updateDrawState(TextPaint tp) { if (color != NONE) tp.setColor(color); if (bgColor != NONE) tp.bgColor = bgColor; tp.setFakeBoldText(boldText); tp.setStrikeThruText(strikeThruText); if (textSize != NONE) tp.setTextSize(textSize); tp.setUnderlineText(underlineText); tp.setTextSkewX(italicText ? -0.25f : 0); } } 

рдпрд╣ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЙрджреНрджреЗрд╢реНрдп рд╕реНрдкреИрди рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдЖрдк рдЕрдзрд┐рдХрд╛рдВрд╢ рдкрд╛рда рд╢реИрд▓реА рд╡рд┐рдХрд▓реНрдк рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ рдЯреИрдЧ рд╕реЗ рдкрд╛рда рд╢реИрд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

 package com.example.markup.tutorial; import android.text.style.ClickableSpan; import android.view.View; public class ArticleSpan extends ClickableSpan { final MainActivity activity; final String articleId; public ArticleSpan(MainActivity activity, String articleId) { super(); this.activity = activity; this.articleId = articleId; } @Override public void onClick(View arg0) { activity.setArticle(articleId); } } 

рдпрд╣ рд╡рд░реНрдЧ рдПрдХ рддрддреНрд╡ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдкрд░, рдЙрд╕ рд▓реЗрдЦ рдХреЛ рдПрдХ рд╕рдВрдХреНрд░рдордг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЙрд╕рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рдпрд╣рд╛рдВ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдмрддрд╛рдИ рдЧрдИ рд╡рд┐рдзрд┐ рдХрд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛: рдЯреИрдЧ рд╕реНрд╡рдпрдВ рдЕрдкрдирд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИ, рдФрд░ рдЗрд╕рдХреА рдХрдХреНрд╖рд╛ рдЙрдкрд╕рд░реНрдЧ рд▓реЗрдЦ_ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред Html.TagHandler рдХреЗ рд╡рд░реНрдгрди рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВ :

 if (tag.startsWith("article_")) span = new ArticleSpan(MainActivity.this, tag); 

рдЯреИрдЧ рд╣реИрдВрдбрд▓рд░, рдиреЗ рд▓реЗрдЦ_ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЯреИрдЧ рдХреЛ рджреЗрдЦрд╛ рд╣реИ, рдПрдХ ArticleSpan рдмрдирд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЯреИрдЧ рдирд╛рдо рджреЗрддрд╛ рд╣реИред рдПрдХ рддрддреНрд╡, рдЬрдм рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ MainActivity.setArticle рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж TextView рдореЗрдВ рдирдпрд╛ рдкрд╛рда рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИред

 package com.example.markup.tutorial; import android.graphics.Color; import android.text.TextPaint; import android.text.style.CharacterStyle; public class ParameterizedSpan extends CharacterStyle { int color = 0; public ParameterizedSpan(String param) { try { color = Color.parseColor("#" + param); } catch(Exception ex) { } } @Override public void updateDrawState(TextPaint tp) { tp.setColor(color); } } 

рдпрд╣рд╛рдВ рдПрдХ рддрддреНрд╡ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдФрд░ рдЙрд╕рдХреЗ рдирд╛рдо рд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЯреИрдЧ рдирд╛рдордХрд░рдг рдорд╛рдирдХ рдХрд╛ рджрд╛рд╡рд╛ рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВред

рдмреЗрд╢рдХ, рд╡рд░реНрдгрд┐рдд рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреА рднрд┐рдиреНрдирддрд╛ рд╣реИ, рд╣рд░ рдХреЛрдИ рдЪреБрди рд▓реЗрдЧрд╛ рдХрд┐ рдЙрд╕рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

рдЧрддрд┐рд╡рд┐рдзрд┐ рдЪреБрдиреМрддреА


рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдпреЛрдЬрдирд╛ рдФрд░ рд╣реЛрд╕реНрдЯ рдХреЗ рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп <a href...> рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ <a href...> рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

HTML рдореЗрдВ, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЗрдЦрддреЗ рд╣реИрдВ:
 <a href="activity-run://AnotherActivityHost?caption=Another%20Activity&text=Hello%20from%20markup!">  Activity</a> 

рдЬрдм рдЖрдк рд▓рд┐рдВрдХ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ Intent рдХреЗ рд▓рд┐рдП рджрд┐рдП рдЧрдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдФрд░Activity рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
 Uri uri = getIntent().getData(); String caption = uri.getQueryParameter("caption"); String text = uri.getQueryParameter("text"); 


рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рдордЧреНрд░рд┐рдпреЛрдВ рдиреЗ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдмрд╣реБрдд рддреЗрдЬ рдХрд░ рджрд┐рдпрд╛, рдФрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕реЗ рдЖрдо рддреМрд░ рдкрд░ рд╕рдВрднрд╡ рдмрдирд╛рдпрд╛:

www.sherif.mobi/2011/09/html-and-activity-links-in-textview.html
stackoverflow.com/questions/3874999/alignment-in-html-fromhtml
stackoverflow.com/questions/11865334/how-to-use-xmlreader-in-taghandler-handletag
stackoverflow.com/questions/4044509/android-how-to-use-the-html-taghandler
stackoverflow.com/questions/1792604/html-imagegetter

рдореБрдЭреЗ рдмрд╣реБрдд рдЦреБрд╢реА рд╣реИ рдХрд┐ StackOverflow.com рджреБрдирд┐рдпрд╛ рдореЗрдВ рдореМрдЬреВрдж рд╣реИред

рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд╕рд╛рде рдкреБрд░рд╛рд▓реЗрдЦ



рд╕реНрд░реЛрдд рдЧреНрд░рдВрдереЛрдВ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд╕рд╛рде рдкреБрд░рд╛рд▓реЗрдЦ рдпрд╣рд╛рдВ рд▓реЗ рдЬрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

Source: https://habr.com/ru/post/In166351/


All Articles