Android ImageGetter 图像重叠文本
Posted
技术标签:
【中文标题】Android ImageGetter 图像重叠文本【英文标题】:Android ImageGetter images overlapping text 【发布时间】:2011-12-13 19:03:19 【问题描述】:我正在尝试使用
将 html 块加载到 TextView 中,包括图像URLImageParser p = new URLImageParser(articleBody, this);
Spanned htmlSpan = Html.fromHtml(parsedString, p, null);
顺便说一下,parsedString 是 HTML。无论如何,它会加载,但是图像没有为它们创建任何空间供它们坐下,因此它们最终与它们上方的文本重叠。这是我的 URLImageParser 文件:
public class URLImageParser implements Html.ImageGetter
Context c;
View container;
/***
* Construct the URLImageParser which will execute AsyncTask and refresh the container
* @param t
* @param c
*/
public URLImageParser(View t, Context c)
this.c = c;
this.container = t;
public Drawable getDrawable(String source)
URLDrawable urlDrawable = new URLDrawable();
// get the actual source
ImageGetterAsyncTask asyncTask =
new ImageGetterAsyncTask( urlDrawable);
asyncTask.execute(source);
// return reference to URLDrawable where I will change with actual image from
// the src tag
return urlDrawable;
public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable>
URLDrawable urlDrawable;
public ImageGetterAsyncTask(URLDrawable d)
this.urlDrawable = d;
@Override
protected Drawable doInBackground(String... params)
String source = params[0];
return fetchDrawable(source);
@Override
protected void onPostExecute(Drawable result)
// set the correct bound according to the result from HTTP call
Log.d("height",""+result.getIntrinsicHeight());
Log.d("width",""+result.getIntrinsicWidth());
urlDrawable.setBounds(0, 0, 0+result.getIntrinsicWidth(), 0+result.getIntrinsicHeight());
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
/***
* Get the Drawable from URL
* @param urlString
* @return
*/
public Drawable fetchDrawable(String urlString)
try
URL aURL = new URL(urlString);
final URLConnection conn = aURL.openConnection();
conn.connect();
final BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
final Bitmap bm = BitmapFactory.decodeStream(bis);
Drawable drawable = new BitmapDrawable(bm);
drawable.setBounds(0,0,bm.getWidth(),bm.getHeight());
return drawable;
catch (Exception e)
return null;
有什么想法吗?非常感谢。
【问题讨论】:
您正在尝试延迟加载图像?如果是这样,我认为这只是那里的问题。为什么不尝试同时加载图像和文本? “延迟加载”到底是什么意思? 延迟加载意味着在下载图像时显示它们。另一种方法是等待图像下载,然后才显示视图。 我正在尝试做类似的事情,你能告诉我这里的 URLDrawable 是什么吗? @AbhayKumar 我认为包含 URLDrawable 的原始代码是在 ***.com/a/7442725/262462 定义的 【参考方案1】:是否有特殊原因需要将其加载到文本视图中?你能改用WebView 吗?
如果您不能使用 Webviews,那么最好的解决方案是不要将图像放在您的文本视图中。将图像放在 ImageView 中。 TextView 没有任何布局引擎功能,您需要找出将图像和文本相互关联的位置。它们不是 ViewGroup(如 LinearLayout 或 RelativeLayout),因此没有内部布局指定功能。如果您真的不想使用 webview(以及它拥有的所有不错的布局引擎),您将不得不自己弄清楚如何安排单独的 TextView 和 ImageView。
【讨论】:
WebViews 创建不合格的体验。我正在尝试编写一个好的本机应用程序。我已经展示了我的图像,我只需要它们正确布局即可。 这是有道理的。我将过滤掉图像并单独进行。 @Nick 我认为您应该在下面选择答案。因为它正在解决textview中的问题。无需使用网络视图。 Webviews 不是为了这个目的。而且,如果在列表视图中使用 Web 视图,它们可能会出现问题。【参考方案2】:您可以将您的硬币容器 c(视图)更改为 textView,然后让您的 onPostExecute 看起来像这样:
@Override
protected void onPostExecute(Drawable result)
// set the correct bound according to the result from HTTP call
Log.d("height",""+result.getIntrinsicHeight());
Log.d("width",""+result.getIntrinsicWidth());
urlDrawable.setBounds(0, 0, 0+result.getIntrinsicWidth(), 0+result.getIntrinsicHeight());
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
// For ICS
URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight()
+ result.getIntrinsicHeight()));
// Pre ICS
URLImageParser.this.textView.setEllipsize(null);
这将首先绘制图像,然后立即将 TextView 的高度设置为 drawable 的高度 + TextViews 的高度
【讨论】:
这很完美!有图像重叠的相同问题。使用此解决方案,图像可以完美显示!container.setText(container.getText())
也可以工作(前提是容器是 TextView)。但是,我想知道强制 TextView 重做其布局的最佳方法是..
天哪!我花了大约 6 个小时来解决这个问题,直到找到您的解决方案。我现在可以睡觉了wwww。
setHeight 不起作用 :( Eclipse 告诉使用 setMinimumHeight,但这无济于事
@Kondra007 您需要按照 Martin 的指示将 cointainer c(视图)更改为 textView,然后 eclipse 不会要求您使用 setMinimumHeight【参考方案3】:
也许我们不需要将容器从 View 更改为 TextView。
@Override
protected void onPostExecute(Drawable result)
// set the correct bound according to the result from HTTP call
urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0
+ result.getIntrinsicHeight());
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.setMinimumHeight((URLImageParser.this.container.getHeight()+ result.getIntrinsicHeight()));
URLImageParser.this.container.requestLayout();
URLImageParser.this.container.invalidate();
【讨论】:
【参考方案4】:我没有足够的声望给 Martin S 投票,但他的回答真的很有帮助。如果 TextView 在加载前显示了默认图像,我们可以像这样更改 setHeight() 方法:
URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight()
+ result.getIntrinsicHeight()-mDefaultDrawable.getInstrinsicHeight()));
【讨论】:
【参考方案5】:我发现这些解决方案的一个有趣行为: 如果图像的加载速度过快并且 textview 尚未渲染(例如,我使用带有缓存的 Okhttp,所以第二次调用非常快),则 textview 大小为 0。
为了解决这个问题,我将 ImageGetter 从 AsyncTask 转换回来,而是启动了一个 AsyncTask,它为我的 TextView 创建 Spanned 并在之后设置文本。
使用此解决方案,无需在每次加载图像时调整 TextView 的大小。
new AsyncTask<TextView, Void, Spanned>()
TextView tv;
@Override
protected Spanned doInBackground(TextView... params)
tv = params[0];
return Html.fromHtml(feedEntry.getContent(),
new HttpImageGetter(getActivity(), HttpLoaderImpl.getInstance(getActivity())),
new Html.TagHandler()
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader)
//do nothing...
);
@Override
protected void onPostExecute(final Spanned result)
new Handler(Looper.getMainLooper()).post(new Runnable()
@Override
public void run()
tv.setText(result);
);
.execute(textView);
【讨论】:
以上是关于Android ImageGetter 图像重叠文本的主要内容,如果未能解决你的问题,请参考以下文章
Android HTML ImageGetter 作为 AsyncTask