問題描述
IndoorAtlas SDK 2.0:使用 Picasso 和自定義 ImageView (IndoorAtlas SDK 2.0: Using Picasso with custom ImageView)
所以....,我想使用 Picasso 圖像加載器庫和現有的自定義圖像視圖類來加載、調整大小和旋轉我的圖像。問題是我沒有成功,就好像我使用以下代碼:“Picasso.with(this).load(url).into(custom ImageView)”,它給了我一個錯誤並建議“將參數投射到目標”。將參數“自定義圖像視圖”轉換為目標後,當我測試應用程序時,它會在 Logcat 中顯示 “自定義圖像視圖無法轉換為目標”。在這個問題之後,我使用了另一段代碼,其中包含對應於畢加索庫的 "onBitmapLoaded" 方法' s 目標界面,我可以成功加載、調整大小和旋轉圖像,但是當我正在開發室內定位系統時,藍點顯示在視線之外。它顯示在視線之外/不正確的原因是因為自定義圖像視圖沒有與畢加索一起使用來加載和顯示圖像。這是包含“onBitmapLoaded”方法的代碼位,我沒有得到我想要的結果,它也不正確,因為過了一會兒應用程序崩潰並出現此錯誤 "java.lang.RuntimeException: Canvas:嘗試使用回收的位圖 android.graphics.Bitmap@1d21751f" 並引用自定義 ImageView 類中的代碼行 "super.onDraw(canvas)" :
private IAFloorPlan mFloorPlan;
private BlueDotView mImageView;
private Target mLoadTarget;
private void showFloorPlanImage(String filePath) {
final String url = mFloorPlan.getUrl();
if (mLoadTarget == null) {
mLoadTarget = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Log.d(TAG, "onBitmap loaded with dimensions: " + bitmap.getWidth() + "x"
+ bitmap.getHeight());
mImageView.setImage(ImageSource.bitmap(bitmap));
mImageView.setRadius(mFloorPlan.getMetersToPixels() * dotRadius);
//mImageView.setRotation(90);
//setupGroundOverlay(floorPlan, bitmap);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
// N/A
}
@Override
public void onBitmapFailed(Drawable placeHolderDraweble) {
Toast.makeText(AutomaticFloorPlanLoader.this, "Failed to load bitmap",
Toast.LENGTH_SHORT).show();
}
};
}
RequestCreator request = Picasso.with(this).load(url).rotate(90).resize(500,500);
final int bitmapWidth = mFloorPlan.getBitmapWidth();
final int bitmapHeight = mFloorPlan.getBitmapHeight();
if (bitmapHeight > MAX_DIMENSION) {
request.resize(0, MAX_DIMENSION);
} else if (bitmapWidth > MAX_DIMENSION) {
request.resize(MAX_DIMENSION, 0);
}
request.into(mLoadTarget);
/*DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
int screenHeight = displaymetrics.heightPixels;
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(screenWidth,screenHeight);
mImageView.setLayoutParams(parms);*/
//Picasso.with(this).load(Uri.parse(mFloorPlan.getUrl())).into((Target) mImageView);
Log.w(TAG, "showFloorPlanImage: " + filePath);
/* mImageView.setRadius(mFloorPlan.getMetersToPixels() * dotRadius);
mImageView.setImage(ImageSource.uri(filePath));
mImageView.setRotation(90);*/
}
這是我的應用程序中上述代碼的結果:“http://i.imgur.com/kcSa2x1。 png"
And here is the custom ImageView class:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
public class BlueDotView extends SubsamplingScaleImageView {
//private static final float RATIO = 4f / 3f;
private float radius = 1.0f;
private PointF dotCenter = null;
public void setRadius(float radius) {
this.radius = radius;
}
public void setDotCenter(PointF dotCenter) {
this.dotCenter = dotCenter;
}
public BlueDotView(Context context) {
this(context, null);
}
public BlueDotView(Context context, AttributeSet attr) {
super(context, attr);
initialise();
}
private void initialise() {
setWillNotDraw(false);
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_CENTER);
}
/*public BlueDotView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isReady()) {
return;
}
if (dotCenter != null) {
PointF vPoint = sourceToViewCoord(dotCenter);
//float scaledRadius = getScale() * radius;
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
canvas.drawCircle(vPoint.x, vPoint.y, 10, paint);
}
}
}
我嘗試了 setLinearLayout、displayMetrics 和 onMeasure 方法,但都無法調整圖像大小。
所以,總的來說,我的問題是:我如何使用 Picasso 和自定義 ImageView 類/imageView 本身來加載、調整大小和旋轉圖像,並在這個特定的情況下正確顯示藍點例如?
如果您能幫我解決這個問題,請提前多謝。
參考解法
方法 1:
The BlueDotView
(here: https://github.com/IndoorAtlas/android‑sdk‑examples/blob/master/Basic/src/main/java/com/indooratlas/android/sdk/examples/imageview/BlueDotView.java) in IndoorAtlas's example extends SubsamplingScaleImageView
by Dave Morissey (here: https://github.com/davemorrissey/subsampling‑scale‑image‑view). SubsamplingScaleImageView
does not extend android.widget.ImageView
and hence you cannot use it directly as load target: Picasso.with(this).load(url).into(mImageView)
but you need to use Target
just as you did.
What comes to java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f
this is because SubsamplingScaleImageView
does not work out‑of‑the‑box with most image loading libraries. Read more here: https://github.com/davemorrissey/subsampling‑scale‑image‑view/wiki/X.‑Using‑with‑Picasso. That link also explains the proper way of mixing SubsamplingScaleImageView
with Picasso. The quick hack is to pass a copy of the Bitmap
to image view:
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mImageView.setImage(ImageSource.bitmap(bitmap.copy(bitmap.getConfig(), true));
}
This may be ok for small bitmaps that don't change often but is waste of resources for large bitmaps and can cause OOM exceptions.
It looks like your are resizing your bitmap to 500x500 pixels. If your original floor plan bitmap was not square (?) you are changing aspect ratio and positioning blue dot correctly will fail. To set e.g. width of your bitmap to 500px and still maintain aspect ratio, use: resize(500, 0)
.
(by Neel0507、Jukka Raanamo)