次のHTMLがあるとします。
_<p>This is text and this is an image <img src="http://www.example.com/image.jpg" />.</p>
_
画像をレンダリングすることは可能ですか?このスニペットmContentText.setText(Html.fromHtml(text));
を使用すると、黒い枠のシアンのボックスが表示され、TextViewがimgタグとは何かを理解していると信じ込ませます。
Html.fromHtml(text)
のドキュメント を見ると、次のように表示されます:
HTML内の_
<img>
_タグは一般的な置換イメージとして表示され、プログラムはそれを通過して実際のイメージに置き換えることができます。
この置換を自分で行いたくない場合は、 他のHtml.fromHtml()
メソッド を使用できます。これは _Html.TagHandler
_ と- _Html.ImageGetter
_ 引数および解析するテキストとして。
あなたの場合、null
を_Html.TagHandler
_として解析できますが、デフォルトの実装がないため、独自の_Html.ImageGetter
_を実装する必要があります。
ただし、問題になるのは、_Html.ImageGetter
_を同期的に実行する必要があることです。Webから画像をダウンロードする場合は、おそらく非同期で実行する必要があります。アプリケーションのリソースとして表示したい画像を追加できる場合、ImageGetter
の実装はずっと簡単になります。あなたは次のようなもので逃げることができます:
_private class ImageGetter implements Html.ImageGetter {
public Drawable getDrawable(String source) {
int id;
if (source.equals("stack.jpg")) {
id = R.drawable.stack;
}
else if (source.equals("overflow.jpg")) {
id = R.drawable.overflow;
}
else {
return null;
}
Drawable d = getResources().getDrawable(id);
d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
return d;
}
};
_
ただし、ソース文字列をリソースIDにマッピングするためのよりスマートなものを見つけたいと思うでしょう。
私はアプリに実装しました pskink 。thanxから何度も参照しました
package com.example.htmltagimg;
import Java.io.FileNotFoundException;
import Java.io.IOException;
import Java.io.InputStream;
import Java.net.MalformedURLException;
import Java.net.URL;
import Android.app.Activity;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.graphics.drawable.BitmapDrawable;
import Android.graphics.drawable.Drawable;
import Android.graphics.drawable.LevelListDrawable;
import Android.os.AsyncTask;
import Android.os.Bundle;
import Android.text.Html;
import Android.text.Html.ImageGetter;
import Android.text.Spanned;
import Android.util.Log;
import Android.widget.TextView;
public class MainActivity extends Activity implements ImageGetter {
private final static String TAG = "TestImageGetter";
private TextView mTv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String source = "this is a test of <b>ImageGetter</b> it contains " +
"two images: <br/>" +
"<img src=\"http://developer.Android.com/assets/images/dac_logo.png\"><br/>and<br/>" +
"<img src=\"http://www.hdwallpapersimages.com/wp-content/uploads/2014/01/Winter-Tiger-Wild-Cat-Images.jpg\">";
String imgs="<p><img alt=\"\" src=\"http://images.visitcanberra.com.au/images/canberra_hero_image.jpg\" style=\"height:50px; width:100px\" />Test Article, Test Article, Test Article, Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,v</p>";
String src="<p><img alt=\"\" src=\"http://stylonica.com/wp-content/uploads/2014/02/Beauty-of-nature-random-4884759-1280-800.jpg\" />Test Attractions Test Attractions Test Attractions Test Attractions</p>";
String img="<p><img alt=\"\" src=\"/site_media/photos/gallery/75b3fb14-3be6-4d14-88fd-1b9d979e716f.jpg\" style=\"height:508px; width:640px\" />Test Article, Test Article, Test Article, Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,Test Article,v</p>";
Spanned spanned = Html.fromHtml(imgs, this, null);
mTv = (TextView) findViewById(R.id.text);
mTv.setText(spanned);
}
@Override
public Drawable getDrawable(String source) {
LevelListDrawable d = new LevelListDrawable();
Drawable empty = getResources().getDrawable(R.drawable.ic_launcher);
d.addLevel(0, 0, empty);
d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());
new LoadImage().execute(source, d);
return d;
}
class LoadImage extends AsyncTask<Object, Void, Bitmap> {
private LevelListDrawable mDrawable;
@Override
protected Bitmap doInBackground(Object... params) {
String source = (String) params[0];
mDrawable = (LevelListDrawable) params[1];
Log.d(TAG, "doInBackground " + source);
try {
InputStream is = new URL(source).openStream();
return BitmapFactory.decodeStream(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
Log.d(TAG, "onPostExecute drawable " + mDrawable);
Log.d(TAG, "onPostExecute bitmap " + bitmap);
if (bitmap != null) {
BitmapDrawable d = new BitmapDrawable(bitmap);
mDrawable.addLevel(1, 1, d);
mDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
mDrawable.setLevel(1);
// i don't know yet a better way to refresh TextView
// mTv.invalidate() doesn't work as expected
CharSequence t = mTv.getText();
mTv.setText(t);
}
}
}
}
以下の@rpgmakerコメントに従って、私はこの答えを追加しました
はい(ResolveInfoクラスを使用して行うことができます
ファイルが既にインストールされているアプリでサポートされているかどうかを確認してください
以下のコードを使用:
private boolean isSupportedFile(File file) throws PackageManager.NameNotFoundException {
PackageManager pm = mContext.getPackageManager();
Java.io.File mFile = new Java.io.File(file.getFileName());
Uri data = Uri.fromFile(mFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(data, file.getMimeType());
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolveInfos != null && resolveInfos.size() > 0) {
Drawable icon = mContext.getPackageManager().getApplicationIcon(resolveInfos.get(0).activityInfo.packageName);
Glide.with(mContext).load("").placeholder(icon).into(binding.fileAvatar);
return true;
} else {
Glide.with(mContext).load("").placeholder(R.drawable.avatar_defaultworkspace).into(binding.fileAvatar);
return false;
}
}
これは私が使用するものであり、リソース名をハードコアにする必要はなく、アプリリソースで最初に描画可能なリソースを探し、次に何も見つからない場合は在庫Androidリソースで-許可するデフォルトのアイコンなどを使用します。
private class ImageGetter implements Html.ImageGetter {
public Drawable getDrawable(String source) {
int id;
id = getResources().getIdentifier(source, "drawable", getPackageName());
if (id == 0) {
// the drawable resource wasn't found in our package, maybe it is a stock Android drawable?
id = getResources().getIdentifier(source, "drawable", "Android");
}
if (id == 0) {
// prevent a crash if the resource still can't be found
return null;
}
else {
Drawable d = getResources().getDrawable(id);
d.setBounds(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());
return d;
}
}
}
どちらとして使用できますか(例):
String myHtml = "This will display an image to the right <img src='ic_menu_more' />";
myTextview.setText(Html.fromHtml(myHtml, new ImageGetter(), null);
私は同じ問題に直面し、かなりきれいな解決策を見つけました:Html.fromHtml()の後、すべてのタグを反復処理し、画像を取得して表示するAsyncTaskを実行できます。
ここで、使用できるコードを見つけることができます(ただし、カスタマイズが必要です): https://Gist.github.com/1190397
私はDave Webbの回答を使用しましたが、少し簡略化しました。ユースケースで実行時にリソースIDが同じである限り、Html.ImageGetter
を実装する独自のクラスを記述し、ソース文字列をいじる必要はありません。
リソースIDをソース文字列として使用していました。
final String img = String.format("<img src=\"%s\"/>", R.drawable.your_image);
final String html = String.format("Image: %s", img);
直接使用します:
Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(final String source) {
Drawable d = null;
try {
d = getResources().getDrawable(Integer.parseInt(source));
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
} catch (Resources.NotFoundException e) {
Log.e("log_tag", "Image not found. Check the ID.", e);
} catch (NumberFormatException e) {
Log.e("log_tag", "Source string not a valid resource ID.", e);
}
return d;
}
}, null);
また、独自のパーサーを作成して、すべての画像のURLを取得し、新しい画像ビューを動的に作成してURLを渡すこともできます。
また、自分で置換を行いたい場合、探す必要があるキャラクターは[]です。
しかし、Eclipseを使用している場合、[replace]ステートメントにその文字を入力すると、Cp1252と競合することを通知します。これはEclipseのバグです。修正するには、
ウィンドウ->設定->一般->ワークスペース->テキストファイルのエンコード、
[UTF-8]
を選択します
リソースが宣言型である必要があり、複数の言語でSpannableを使用するのが面倒であると誰かが考える場合、カスタムビューを作成しました
import Android.content.Context;
import Android.content.res.Resources;
import Android.content.res.TypedArray;
import Android.graphics.drawable.Drawable;
import Android.text.Html;
import Android.text.Html.ImageGetter;
import Android.text.Spanned;
import Android.util.AttributeSet;
import Android.widget.TextView;
/**
* XXX does not support Android:drawable, only current app packaged icons
*
* Use it with strings like <string name="text"><![CDATA[Some text <img src="some_image"></img> with image in between]]></string>
* assuming there is @drawable/some_image in project files
*
* Must be accompanied by styleable
* <declare-styleable name="HtmlTextView">
* <attr name="Android:text" />
* </declare-styleable>
*/
public class HtmlTextView extends TextView {
public HtmlTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HtmlTextView);
String html = context.getResources().getString(typedArray.getResourceId(R.styleable.HtmlTextView_Android_text, 0));
typedArray.recycle();
Spanned spannedFromHtml = Html.fromHtml(html, new DrawableImageGetter(), null);
setText(spannedFromHtml);
}
private class DrawableImageGetter implements ImageGetter {
@Override
public Drawable getDrawable(String source) {
Resources res = getResources();
int drawableId = res.getIdentifier(source, "drawable", getContext().getPackageName());
Drawable drawable = res.getDrawable(drawableId, getContext().getTheme());
int size = (int) getTextSize();
int width = size;
int height = size;
// int width = drawable.getIntrinsicWidth();
// int height = drawable.getIntrinsicHeight();
drawable.setBounds(0, 0, width, height);
return drawable;
}
}
}
https://Gist.github.com/logcat/64234419a935f1effc67 で更新を追跡します