IndoorAtlas SDK 2.0:将 Picasso 与自定义 ImageView 结合使用
IndoorAtlas SDK 2.0: Using Picasso with custom ImageView
所以....,我想使用 Picasso 图像加载器库和现有的自定义图像视图 class 来加载、调整大小和旋转我的图像。问题是我没有成功,就像我使用这段代码一样:"Picasso.with(this).load(url).into(custom ImageView)",它给了我一个错误并建议 "cast parameter to target"。将参数 "custom imageview" 投射到目标后,当我测试应用程序时,它给我错误提示 Logcat 中的 "custom imageview cannot be cast to target"。
在这个问题之后,我使用了一段不同的代码,其中包含对应于 Picasso 库的 Target 接口的 "onBitmapLoaded" 方法,我能够成功地加载、调整大小和旋转图像,但当我正在开发室内定位系统时,蓝点显示在视线之外。它显示在 sight/incorrectly 之外的原因是因为自定义 imageview 没有与 picasso 一起使用来加载和显示图像。这是包含 "onBitmapLoaded" 方法的代码位,我没有得到我想要的结果而且它也不正确,因为过了一会儿应用程序崩溃并出现此错误 "java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f" 它指的是自定义 ImageView class:
中的代码行 "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 class/the imageView 本身来加载、调整大小和旋转图像,并正确显示蓝点这个具体的例子?
非常感谢你能帮我解决这个问题。
BlueDotView
(此处: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
不扩展 android.widget.ImageView
,因此您不能直接将其用作加载目标:Picasso.with(this).load(url).into(mImageView)
但您需要像以前那样使用 Target
。
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f
这是因为 SubsamplingScaleImageView
不能与大多数图像加载库一起使用。在此处阅读更多内容:https://github.com/davemorrissey/subsampling-scale-image-view/wiki/X.-Using-with-Picasso。 link 也解释了将 SubsamplingScaleImageView
与 Picasso 混合的正确方法。快速破解是将 Bitmap
的副本传递给图像视图:
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mImageView.setImage(ImageSource.bitmap(bitmap.copy(bitmap.getConfig(), true));
}
这对于不经常更改的小位图可能没问题,但对于大位图会浪费资源并可能导致 OOM 异常。
您似乎正在将位图大小调整为 500x500 像素。如果您的原始平面图位图不是正方形(?),您正在更改纵横比并且正确定位蓝点将失败。设置例如位图的宽度为 500px 并保持宽高比,使用:resize(500, 0)
.
所以....,我想使用 Picasso 图像加载器库和现有的自定义图像视图 class 来加载、调整大小和旋转我的图像。问题是我没有成功,就像我使用这段代码一样:"Picasso.with(this).load(url).into(custom ImageView)",它给了我一个错误并建议 "cast parameter to target"。将参数 "custom imageview" 投射到目标后,当我测试应用程序时,它给我错误提示 Logcat 中的 "custom imageview cannot be cast to target"。 在这个问题之后,我使用了一段不同的代码,其中包含对应于 Picasso 库的 Target 接口的 "onBitmapLoaded" 方法,我能够成功地加载、调整大小和旋转图像,但当我正在开发室内定位系统时,蓝点显示在视线之外。它显示在 sight/incorrectly 之外的原因是因为自定义 imageview 没有与 picasso 一起使用来加载和显示图像。这是包含 "onBitmapLoaded" 方法的代码位,我没有得到我想要的结果而且它也不正确,因为过了一会儿应用程序崩溃并出现此错误 "java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f" 它指的是自定义 ImageView class:
中的代码行 "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 class/the imageView 本身来加载、调整大小和旋转图像,并正确显示蓝点这个具体的例子?
非常感谢你能帮我解决这个问题。
BlueDotView
(此处: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
不扩展 android.widget.ImageView
,因此您不能直接将其用作加载目标:Picasso.with(this).load(url).into(mImageView)
但您需要像以前那样使用 Target
。
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1d21751f
这是因为 SubsamplingScaleImageView
不能与大多数图像加载库一起使用。在此处阅读更多内容:https://github.com/davemorrissey/subsampling-scale-image-view/wiki/X.-Using-with-Picasso。 link 也解释了将 SubsamplingScaleImageView
与 Picasso 混合的正确方法。快速破解是将 Bitmap
的副本传递给图像视图:
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
mImageView.setImage(ImageSource.bitmap(bitmap.copy(bitmap.getConfig(), true));
}
这对于不经常更改的小位图可能没问题,但对于大位图会浪费资源并可能导致 OOM 异常。
您似乎正在将位图大小调整为 500x500 像素。如果您的原始平面图位图不是正方形(?),您正在更改纵横比并且正确定位蓝点将失败。设置例如位图的宽度为 500px 并保持宽高比,使用:resize(500, 0)
.