【问题标题】:IndoorAtlas SDK 2.0: Using Picasso with custom ImageViewIndoorAtlas SDK 2.0:使用 Picasso 和自定义 ImageView
【发布时间】:2015-11-14 12:20:55
【问题描述】:

所以....,我想使用 Picasso 图像加载器库和现有的自定义图像视图类来加载、调整大小和旋转我的图像。问题是我没有成功,就好像我使用这段代码一样:“Picasso.with(this).load(url).into(custom ImageView)”,它给了我一个错误并建议“将参数转换为目标”。将参数“自定义图像视图”转换为目标后,当我测试应用程序时,它会在 Logcat 中显示 “自定义图像视图无法转换为目标”。 在这个问题之后,我使用了另一段包含 "onBitmapLoaded" 方法的代码,该方法对应于 Picasso 库的 Target 接口,并且我能够成功地加载、调整大小和旋转图像,但是作为我正在开发室内定位系统,蓝点显示在视线之外。它显示在视线之外/不正确的原因是因为自定义图像视图没有与毕加索一起使用来加载和显示图像。这是包含“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 本身来加载、调整大小和旋转图像,并在这个特定示例中正确显示蓝点?强>

非常感谢您能帮我解决这个问题。

【问题讨论】:

    标签: java imageview android-custom-view picasso indoor-positioning-system


    【解决方案1】:

    IndoorAtlas 示例中的 BlueDotView(此处:https://github.com/IndoorAtlas/android-sdk-examples/blob/master/Basic/src/main/java/com/indooratlas/android/sdk/examples/imageview/BlueDotView.java)扩展了 Dave Morissey(此处:https://github.com/davemorrissey/subsampling-scale-image-view)的 SubsamplingScaleImageViewSubsamplingScaleImageView 不扩展 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。该链接还解释了将SubsamplingScaleImageView 与毕加索混合的正确方法。快速破解是将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)

    【讨论】:

    • 我按照你说的做了很多修改,但是蓝点还是像往常一样看不见。问题出在 fetchfloorplan 方法中,我不确定我是否应该仍然拥有 mFloorPlan = result.getResult(); 还是应该是 showfloorplanimage(result.getResult));乙>。因此,我在我的应用程序中同时使用了它们。可以在此处看到此代码中的新更改:“en.textsave.org/zLNb”。如果你能指出这段代码有什么问题,那就太好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 2019-06-27
    相关资源
    最近更新 更多