安卓 Picasso - 占位符和错误图片样式化

41

我正在使用Picasso库从网络下载图像。 我只想知道是否可以使用进度对话框或GIF图像作为占位符? 另外,有没有办法使占位符图像比实际下载的图像更小(并居中适合)?

我尝试查看示例,但没有运气。 有没有人在这里能让它正常工作?

6个回答

99
您可以在Picasso调用中使用*.placeholder(R.drawable.image_name)*来使用占位图像,例如:
Picasso.with(context)
       .load(imageUrl)
       .placeholder(R.drawable.image_name)

如果你想使用进度条而不是占位图像,你可以在.into函数中创建一个回调。请按照以下类似的方法操作:

在你的视图中:

//create the progressBar here and set it to GONE. This can be your adapters list item view for example
<RelativeLayout
    android:id="@+id/myContainer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">


    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"/>

    <ImageView
        android:id="@+id/myImageView"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:paddingLeft="60dp"
        android:scaleType="centerCrop"></ImageView>

</RelativeLayout>

在您的适配器/类中:

//create a new progress bar for each image to be loaded
ProgressBar progressBar = null;
if (view != null) {
   progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
   progressBar.setVisibility(View.VISIBLE);
}

//get your image view
ImageView myImage = (ImageView) view.findViewById(R.id.myImageView);

//load the image url with a callback to a callback method/class
Picasso.with(context)
            .load(imageUrl)
            .into(myImage,  new ImageLoadedCallback(progressBar) {
                    @Override
                    public void onSuccess() {
                        if (this.progressBar != null) {
                            this.progressBar.setVisibility(View.GONE);
                         }
                    }
              });

在您的适配器/类中,如上所述,我为回调创建了一个内部类:

private class ImageLoadedCallback implements Callback {
   ProgressBar progressBar;

    public  ImageLoadedCallback(ProgressBar progBar){
        progressBar = progBar;
    }

    @Override
    public void onSuccess() {

    }

    @Override
    public void onError() {

    }
}

希望这能让你理解!


2
这只是一个例子,你可以直接使用Callback而不是使用内部类来进行回调。 - Chris
在您的适配器中,您使用xml布局文件来定义图像布局。此xml包含一个进度条元素,该元素只是设置为隐藏/消失。然后,在您的适配器中,您将获取此ProgressBar元素并将其分配给变量,我最初将空值赋给它的原因是因为分配发生在“if”子句内部,但变量需要超出if-子句的范围。如果您没有使用null初始化变量,则根本不会初始化变量,当您尝试分配实际值时,应用程序将崩溃。一旦分配了变量,您只需将其设置为“可见”。 - Chris
4
非常好的回答。不知道为什么原帖作者还没有接受它。 - everydayapps
非常好。这绝对是答案,因为JakeWharton在此处提到的Picasso placeHolder animationdrawable不会尊重图像上的ScaleType。https://github.com/square/picasso/issues/427 - Odaym
我收到了“回调不存在”的错误信息。我尝试从Picasso导入,但是我的应用程序在打开后立即关闭了...有什么想法吗? - fh_bash
显示剩余4条评论

16

我已经实现了进度对话框,直到图像下载完成,这非常简单。在相对布局中取出你的ImageView并将进度加载器放置在同一ImageView上。 应用以下代码,并仅处理进度对话框的可见性。

                holder.loader.setVisibility(View.VISIBLE);
                holder.imageView.setVisibility(View.VISIBLE);
                final ProgressBar progressView = holder.loader;
                Picasso.with(context)
                .load(image_url)
                .transform(new RoundedTransformation(15, 0))
                .fit()
                .into(holder.imageView, new Callback() {
                    @Override
                    public void onSuccess() {
                        progressView.setVisibility(View.GONE);
                    }

                    @Override
                    public void onError() {
                        // TODO Auto-generated method stub

                    }
                });
            }

希望能对某人有所帮助!:)


12

展示进度条非常简单。

将此代码添加到活动中以带有进度条加载图像。

Picasso.with(this)
            .load(hoteImageStr)
            .error(R.drawable.loading)
            .into(img,  new com.squareup.picasso.Callback() {
                @Override
                public void onSuccess() {
                    if (progress != null) {
                        progress .setVisibility(View.GONE);
                    }
                }

                @Override
                public void onError() {

                }
            });

将此添加到您的布局文件中。

 <RelativeLayout
    android:id="@+id/hoteldetails_myContainer"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
   >


    <ProgressBar
        android:id="@+id/hoteldetails_progressBar"
        style="?android:attr/progressBarStyleSmall"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:visibility="gone"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp" />

    <ImageView
        android:id="@+id/hoteldetails_imageView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitXY"
        />

</RelativeLayout>

11

首先创建一个像这样的可绘制布局:
progress_animation.xml:

<?xml version="1.0" encoding="utf-8"?>

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/loading"
    android:pivotX="50%"
    android:pivotY="50%"/>


loading.png添加到drawable文件夹中
loading.png
使用方法:

Picasso.with(context).load(imageUri).placeholder(R.drawable.progress_animation).into(imgView);

8

Kotlin

val circularProgressDrawable = CircularProgressDrawable(context)
circularProgressDrawable.strokeWidth = 5f
circularProgressDrawable.centerRadius = 30f
circularProgressDrawable.start()
Picasso.get().load(imageUrl).placeholder(circularProgressDrawable).into(holder.imageView)

以上代码消除了XML代码,使其更加干净。

1
使用.apply { },代码会更加简洁 :-) - Stéphane Péchard

1
你需要在使用Picasso库的同时设置进度条,并手动使用监听器管理其可见性。
我正在使用UniversalImageLoader,而Picasso库应该非常相似。
private ImageLoadingListener photoSuccess = new ImageLoadingListener() {

    @Override
    public void onLoadingStarted(String imageUri, View view) {
    }

    @Override
    public void onLoadingFailed(String imageUri, View view,
            FailReason failReason) {
        if(progress != null)
            progress.setVisibility(View.GONE);
    }

    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
        if(progress != null)
            progress.setVisibility(View.GONE);
        if(mImage != null)
            mImage.setVisibility(View.VISIBLE);
    }

    @Override
    public void onLoadingCancelled(String imageUri, View view) {
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接