下载的位图图像显示太小

时间:2018-12-22 19:20:54

标签: android android-bitmap

我有一个带有自定义适配器的ListView。每行都有一个我下载到位图的Pokémon精灵,这些精灵始终为96 x96。我手动下载了一个虚拟图像并将其放在我的drawables文件夹中,它可以很好地呈现: How it should be

但是当我实际以编程方式下载图像时,它给出了以下结果: How it is

为什么突然这么小?当我计算下载的位图的高度和宽度时,显示为96 x 96,但显然不能渲染为96 x 96。

这是下载图像的任务的代码

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap bm = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            bm = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bm;
    }

}

我怎么称呼任务

try {
        Bitmap bm = new DownloadImageTask().execute(dataModel.getSpriteUrl()).get();
        viewHolder.sprite.setImageBitmap(bm);
    } catch (Exception e) {
        e.printStackTrace();
    }

口袋妖怪行XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/img_sprite"
            android:layout_width="96dp"
            android:layout_height="96dp"
            android:scaleType="fitCenter" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="left|center_vertical"
            android:orientation="vertical">

            <TextView
                android:id="@+id/text_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@android:color/black"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/text_cp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/text_gendershiny"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="end"
            android:orientation="vertical">

            <Button
                android:id="@+id/btn_delete"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:backgroundTint="@color/colorPrimary"
                android:text="DELETE"
                android:textColor="#ffffff"
                android:textSize="16sp"
                android:textStyle="bold" />
        </LinearLayout>

    </LinearLayout>

</android.support.v7.widget.CardView>

2 个答案:

答案 0 :(得分:1)

您可能想看看这个网站。我提供了一些有关如何将scaleType属性和ImageView一起使用的提示:

https://robots.thoughtbot.com/android-imageview-scaletype-a-visual-guide


请参见此答案底部的修改。


由于存在使用get()的{​​{1}}方法的问题

使用AsyncTask告诉您interface完成的时间:

AsyncTask

您的public interface BitmapLoaderListener { void onCompletedBitmapLoaded(Bitmap bm); } 可能如下所示:

AsyncTask

public class BitmapLoader extends AsyncTask<String, Integer, Bitmap> { private static final String TAG = BitmapLoader.class.getSimpleName(); private BitmapLoaderListener mListener; private String imageUrl = ""; public BitmapLoader(String imageUrl, BitmapLoaderListener listener){ this.imageUrl = imageUrl; this.mListener = listener; this.selectedSource = source; } @Override protected Bitmap doInBackground(String... params) { Bitmap bm = null; try{ // Your code here !!! } catch (Exception ex){ Log.e(TAG, ex.getMessage()); } return bm; } protected void onPostExecute(Bitmap bm) { mListener.onCompletedBitmapLoaded(bm); } } 的{​​{1}}呼叫AsyncTask

RecyclerView



您可以实施缓存类型的系统,在该系统中,将映像持久保存到设备存储中,仅在需要时才从Internet加载它们。我用很多我的应用程序做到这一点。这是可能的,但是需要处理线程和资源的经验……正如安吉丽娜指出的那样,您始终可以使用Glide或Picasso库。尽管在这种情况下我很少使用第三方库,但您可能要考虑一下-它们是设计良好且维护良好的库。



编辑:

为每个下载的图像使用缩放方法onBindViewHolder似乎有点沉重。

您可能希望对布局文件进行以下简单更改:

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position){
    MyData data = mData.get(position);

    // Add whatever code you need here

    BitmapLoaderListener listener = new BitmapLoaderListener() {
        @Override
        public void onCompletedBitmapLoaded(Bitmap bm) {
            if (bm == null) return;
            holder.myImageView.setImageBitmap(bm);
        }
    };

    BitmapLoader loader = new BitmapLoader(imageUrl, listener);
    loader.execute();
}

有很多方法可以通过对布局文件进行一些更改来获得所需的结果。我只是选择要下载的图像尺寸(96x96)中最简单的一种。

此示例获取图像并将其强制放入createScaledBitmap() 96dpx96dp中,以使图像居中并缩放以适合视图边界,从而保持原始宽高比。

与为每个图像使用<ImageView android:id="@+id/img_sprite" android:layout_width="96dp" android:layout_height="96dp" android:scaleType="fitCenter"/> 方法相比,这更易于维护和修改,而且重量更轻-不管它是否需要,哎呀!

答案 1 :(得分:-1)

使用AsyncTask下载图像并不常见。通常,这是通过名为Glide的库完成的。它在后台线程中下载图像并对其进行缓存。您还可以在那里设置图像的ScaleType。