下载的位图图像显示太小
Downloaded bitmap images display too small
我有一个带有自定义适配器的 ListView。每行都有一个 Pokémon 精灵,我将其下载到位图,精灵始终为 96 x 96。我手动下载了一个虚拟图像并将其放入我的 drawables 文件夹中,它呈现得很好:
How it should be
但是当我实际以编程方式下载图像时,它给了我这个结果:
How it is
怎么突然变小了?当我 sysout 下载的位图的高度和宽度时,它显示为 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>
使用AsyncTask 下载图片并不常见。通常这是通过名为 Glide
的库完成的。它在后台线程中下载图像并缓存它。您还可以在那里设置图像的 ScaleType。
您可能想看看这个网站。我提供了一些有关如何将 scaleType
属性与 ImageView
:
一起使用的有用提示
https://robots.thoughtbot.com/android-imageview-scaletype-a-visual-guide
请参阅此答案底部的编辑内容。
现在讨论使用 AsyncTask
的 get()
方法的问题
使用 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);
}
}
从 onBindViewHolder
中调用 RecyclerView
中的 AsyncTask
:
@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();
}
您可以实现一个缓存类型系统,将图像保存到设备存储中,并仅在需要时从 Internet 加载它们。我用我的很多应用程序来做到这一点。这是可能的,但它需要处理线程和资源的经验......正如 Angelina 指出的那样,您始终可以使用 Glide 或 Picasso 库。尽管在这种情况下我很少使用第三方库,但您可能需要考虑一下——它们是设计良好且维护良好的库。
编辑:
对每个下载的图像使用缩放方法createScaledBitmap()
似乎有点重。
您可能希望对布局文件进行以下简单更改:
<ImageView
android:id="@+id/img_sprite"
android:layout_width="96dp"
android:layout_height="96dp"
android:scaleType="fitCenter"/>
有很多方法可以通过对布局文件进行一些更改来实现您想要的结果。关于您正在下载的图像大小 (96x96),我只选择最简单的。
此示例获取图像并将其强制为 ImageView
96dpx96dp,以便图像居中并缩放以适应视图边界,保持原始纵横比。
与对每个图像使用 createScaledBitmap()
方法相比,这更容易维护和修改,而且重量轻得多——不管它是否需要,哎哟!
我有一个带有自定义适配器的 ListView。每行都有一个 Pokémon 精灵,我将其下载到位图,精灵始终为 96 x 96。我手动下载了一个虚拟图像并将其放入我的 drawables 文件夹中,它呈现得很好: How it should be
但是当我实际以编程方式下载图像时,它给了我这个结果: How it is
怎么突然变小了?当我 sysout 下载的位图的高度和宽度时,它显示为 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>
使用AsyncTask 下载图片并不常见。通常这是通过名为 Glide
的库完成的。它在后台线程中下载图像并缓存它。您还可以在那里设置图像的 ScaleType。
您可能想看看这个网站。我提供了一些有关如何将 scaleType
属性与 ImageView
:
https://robots.thoughtbot.com/android-imageview-scaletype-a-visual-guide
请参阅此答案底部的编辑内容。
现在讨论使用 AsyncTask
get()
方法的问题
使用 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);
}
}
从 onBindViewHolder
中调用 RecyclerView
中的 AsyncTask
:
@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();
}
您可以实现一个缓存类型系统,将图像保存到设备存储中,并仅在需要时从 Internet 加载它们。我用我的很多应用程序来做到这一点。这是可能的,但它需要处理线程和资源的经验......正如 Angelina 指出的那样,您始终可以使用 Glide 或 Picasso 库。尽管在这种情况下我很少使用第三方库,但您可能需要考虑一下——它们是设计良好且维护良好的库。
编辑:
对每个下载的图像使用缩放方法createScaledBitmap()
似乎有点重。
您可能希望对布局文件进行以下简单更改:
<ImageView
android:id="@+id/img_sprite"
android:layout_width="96dp"
android:layout_height="96dp"
android:scaleType="fitCenter"/>
有很多方法可以通过对布局文件进行一些更改来实现您想要的结果。关于您正在下载的图像大小 (96x96),我只选择最简单的。
此示例获取图像并将其强制为 ImageView
96dpx96dp,以便图像居中并缩放以适应视图边界,保持原始纵横比。
与对每个图像使用 createScaledBitmap()
方法相比,这更容易维护和修改,而且重量轻得多——不管它是否需要,哎哟!