我正在构建一个聊天应用程序,我试图将图像附加到EditText,通过使用Picasso从URL获取图像,附加和ImageGetter将图像附加到EditText。但是,我在下面实现的内容不起作用,因为在使用应用程序时附加消息不显示任何内容(但消息确实显示在数据库中)。
我已经在不使用Picasso的情况下进行了测试,因为只需在应用程序中使用带有图像资源的ImageGetter就可以正常工作,只是不需要来自URL。
配置ImageGetter和/或append方法的正确方法是什么,以便此功能可以与Picasso一起使用?或者有更简单的方法吗?
追加方法:
public void appendToMessageHistory(final String username,
final String message) {
if (username != null && message != null) {
Picasso.with(getBaseContext())
.load("http://localhost:3000/uploads/campaign/image/2/2.jpg")
.into(new Target() {
@Override
public void onPrepareLoad(Drawable arg0) {
}
@Override
public void onBitmapLoaded(Bitmap bitmap,
LoadedFrom arg1) {
Drawable drawImage = new BitmapDrawable(
getBaseContext().getResources(), bitmap);
drawImage.setBounds(0, 0,
drawImage.getIntrinsicHeight(),
drawImage.getIntrinsicWidth());
messageHistoryText.append(Html.fromHtml("<b>"
+ username + ":" + "</b>" + "<br>"));
messageHistoryText.append(Html.fromHtml(message
+ "<hr>" + "<br>")
+ System.getProperty("line.separator") + "");
messageHistoryText.append(Html
.fromHtml("<img src = '" + drawImage
+ "'/>",
imageGetter,
null));
}
@Override
public void onBitmapFailed(Drawable arg0) {
}
});
}
}
ImageGetter:
ImageGetter imageGetter = new ImageGetter() {
Drawable imageUsed=null;
@Override
public Drawable getDrawable(String source) {
Picasso.with(getBaseContext())
.load("http://localhost:3000/uploads/campaign/image/2/2.jpg")
.into(new Target() {
@Override
public void onPrepareLoad(Drawable arg0) {
}
@Override
public void onBitmapLoaded(Bitmap bitmap,
LoadedFrom arg1) {
Drawable drawImage = new BitmapDrawable(
getBaseContext().getResources(), bitmap);
drawImage.setBounds(0, 0,
drawImage.getIntrinsicHeight(),
drawImage.getIntrinsicWidth());
imageUsed=drawImage;
}
@Override
public void onBitmapFailed(Drawable arg0) {
}
});
return imageUsed;
}
};
答案 0 :(得分:21)
我无法使用Picasso的目标......
我的解决方法是:
像这样:
public class PicassoImageGetter implements Html.ImageGetter {
final Resources resources;
final Picasso pablo;
final TextView textView;
public PicassoImageGetter(final TextView textView, final Resources resources, final Picasso pablo) {
this.textView = textView;
this.resources = resources;
this.pablo = pablo;
}
@Override public Drawable getDrawable(final String source) {
final BitmapDrawablePlaceHolder result = new BitmapDrawablePlaceHolder();
new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(final Void... meh) {
try {
return pablo.load(source).get();
} catch (Exception e) {
return null;
}
}
@Override
protected void onPostExecute(final Bitmap bitmap) {
try {
final BitmapDrawable drawable = new BitmapDrawable(resources, bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
result.setDrawable(drawable);
result.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
textView.setText(textView.getText()); // invalidate() doesn't work correctly...
} catch (Exception e) {
/* nom nom nom*/
}
}
}.execute((Void) null);
return result;
}
static class BitmapDrawablePlaceHolder extends BitmapDrawable {
protected Drawable drawable;
@Override
public void draw(final Canvas canvas) {
if (drawable != null) {
drawable.draw(canvas);
}
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
}
}
希望这很有用。
答案 1 :(得分:5)
我建立在托马斯的回答上。我使用现有的Picasso方法在不同的线程上下载任何图像,并占用了占位符Drawables。
public class PicassoImageGetter implements Html.ImageGetter {
private TextView textView = null;
public PicassoImageGetter() {}
public PicassoImageGetter(TextView target) {
textView = target;
}
@Override
public Drawable getDrawable(String source) {
BitmapDrawablePlaceHolder drawable = new BitmapDrawablePlaceHolder();
Context context = FeedSurferApp.getContext();
FeedSurferApp
.getPicasso()
.load(source)
.error(ResourcesCompat.getDrawable(context.getResources(), R.drawable.connection_error, context.getTheme()))
.into(drawable);
return drawable;
}
private class BitmapDrawablePlaceHolder extends BitmapDrawable implements Target {
protected Drawable drawable;
@Override
public void draw(final Canvas canvas) {
if (drawable != null) {
drawable.draw(canvas);
}
}
public void setDrawable(Drawable drawable) {
this.drawable = drawable;
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
if (textView != null) {
textView.setText(textView.getText());
}
}
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setDrawable(new BitmapDrawable(FeedSurferApp.getContext().getResources(), bitmap));
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
setDrawable(errorDrawable);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {}
}
}
答案 2 :(得分:1)
我找到了一种将ImageGetter与Picasso Target一起使用的方法:
public Drawable getDrawable(String source) {
final BitmapDrawablePlaceHolder result = new BitmapDrawablePlaceHolder();
Picasso.with(getContext()).load(source).into(new Target() {
@Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
final BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
result.setDrawable(drawable);
result.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
content.setText(content.getText());
// cache is now warmed up
}
@Override public void onBitmapFailed(Drawable errorDrawable) { }
@Override public void onPrepareLoad(Drawable placeHolderDrawable) { }
});
return result;
}
这使用缓存,不再是需要AsyncTask的同步调用。
答案 3 :(得分:0)
使用毕加索的另一种简单方法是创建自定义TextView,并使其实现毕加索的Target接口。 然后,您可以做这样简单的事情。
Picasso.get().load("Some_img_url").placeholder(R.drawable.ic_launcher_foreground).into(tv)
下面是课程
class TextViewWithImageLoader @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr), Target {
enum class Direction { START, END, TOP, BOTTOM }
private var mWidthInPixels: Int = 0
private var mHeightInPixels: Int = 0
private var mDirection: Direction = Direction.START //default value
// This method initialize the required parameters for the TextView to load the image
fun setupImageLoader(widthInPixels: Int, heightInPixels: Int, direction: Direction) {
mWidthInPixels = widthInPixels
mHeightInPixels = heightInPixels
mDirection = direction
}
// sets the size of the drawable
private fun setDrawableBounds(drawable: Drawable) {
drawable.setBounds(0, 0, mWidthInPixels, mHeightInPixels)
}
// Sets the initial placeholder drawable
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
//checking if height and width are valid
if (placeHolderDrawable != null && mWidthInPixels > 0 && mHeightInPixels > 0) {
setDrawableBounds(placeHolderDrawable)
setDrawable(placeHolderDrawable)
}
}
// set the drawable based on the Direction enum
private fun setDrawable(placeHolderDrawable: Drawable?) {
when (mDirection) {
Direction.START -> setCompoundDrawables(placeHolderDrawable, null, null, null);
Direction.END -> setCompoundDrawables(null, null, placeHolderDrawable, null);
Direction.TOP -> setCompoundDrawables(null, placeHolderDrawable, null, null);
Direction.BOTTOM -> setCompoundDrawables(null, null, null, placeHolderDrawable);
}
}
//In this method we receive the image from the url
override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
//checking if height and width are valid
if (mWidthInPixels > 0 && mHeightInPixels > 0) {
val drawable = BitmapDrawable(resources, bitmap)
setDrawableBounds(drawable)
setDrawable(drawable)
}
}
override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
//Do nothing as we are already setting a default value in onPrepareLoad method
// you can add your logic here if required
}
}
您可以直接使用此类,或者,如果您当前拥有自己的自定义视图,则可以扩展此类。
您可以通过这种媒介article来了解更多详情
OR
您可以在github上看到示例项目