从UX的角度来看,最好先向用户显示缩略图,直到真实图像完成加载,然后向他显示,但Picasso仅使用资源文件作为占位符:
Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.into(imageView);
那么,我如何使用缩略图URL作为占位符?如果我应该两次使用毕加索,那该怎么办?
An issue已经在Picasso的github页面上打开了这个请求,但似乎根据JakeWharton它不会被添加到Picasso。那么我们怎么能用手头上的东西来做呢?
答案 0 :(得分:30)
感谢raveN here&关于github上original request的评论,最后我得到了一个有效的解决方案:
Picasso.with(context)
.load(thumb) // thumbnail url goes here
.into(imageView, new Callback() {
@Override
public void onSuccess() {
Picasso.with(context)
.load(url) // image url goes here
.placeholder(imageView.getDrawable())
.into(imageView);
}
@Override
public void onError() {
}
});
这里的技巧是在第一次调用&之后从imageView(缩略图)中获取drawable。将其作为占位符传递给第二个调用
- 更新 -
我做了blog post描述整个场景
答案 1 :(得分:3)
你可以写一个简单的助手,两次调用毕加索(如你所说)。
我没有测试过它,但它应该像
一样Picasso.with(context)
.load(thumbnailUrl)
.error(errorPlaceholderId)
.into(imageView, new Callback() {
@Override
public void onSuccess() {
// TODO Call Picasso once again here
}
@Override
public void onError() {
}
);
有几种不同的方法让你的毕加索被召唤两次。我能想到的一种方法(再次,未经测试)是
public static void loadImageWithCallback(String url, Callback callback) {
Picasso.with(context)
.load(url)
.error(errorPlaceholderId)
.into(imageView, callback);
}
public static void loadImage(String url) {
Picasso.with(context)
.load(url)
.error(errorPlaceholderId)
.into(imageView);
}
loadImageWithCallback("http://example.com/mythumbnail.jpg", new Callback() {
@Override
public void onSuccess() {
loadImage("http://example.com/myRealImage.jpg");
}
@Override
public void onError() {
}
}
编辑:我所知道的是Picasso提供了这种回调机制。我在我的应用程序中使用它来隐藏在加载图像之前显示的ProgressBar。我将隐藏它成功或错误回调 - 因此您可以选择在图像加载完成时收到通知。然后你可以再次调用它。我希望上述方法有效。
答案 2 :(得分:1)
我最初使用的是AbdelHady的解决方案,但发现只有在缩略图完成加载后才会加载较大的图像,所以我想出了这个。
假设您的项目中有实用程序类;
<html>
<head>
<title>Full player example</title>
<!-- Uncomment the following meta tag if you have issues rendering this page on an intranet or local site. -->
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"/> -->
<script type="text/javascript">
function init() { // Master function, encapsulates all functions
var video = document.getElementById("Video1");
if (video.canPlayType) { // tests that we have HTML5 video support
document.getElementById("buttonbar").style.display = "block";
video.src == "";
function vidplay(evt) {
if (video.src == "") { // inital source load
getVideo();
}
button = evt.target; // get the button id to swap the text based on the state
if (video.paused) { // play the file, and display pause symbol
video.play();
button.textContent = "||";
} else { // pause the file, and display play symbol
video.pause();
button.textContent = ">";
}
}
// load video file from input field
function getVideo() {
var fileURL = "/lib/exe/fetch.php?media=experiment_log_books:sig0700.mp4"; // get input field
if (fileURL != "") {
video.src = fileURL;
video.load(); // if HTML source element is used
document.getElementById("play").click(); // start play
} else {
errMessage("Enter a valid video URL"); // fail silently
}
}
// skip forward, backward, or restart
function setTime(tValue) {
try {
if (tValue == 0) {
video.currentTime = tValue;
}
else {
video.currentTime += tValue;
}
} catch (err) {
// errMessage(err) // show exception
errMessage("Video content might not be loaded");
}
}
// display an error message
function errMessage(msg) {
// displays an error message for 5 seconds then clears it
document.getElementById("errorMsg").textContent = msg;
setTimeout("document.getElementById('errorMsg').textContent=''", 5000);
}
// Play
document.getElementById("play").addEventListener("click", vidplay, false);
// Restart
document.getElementById("restart").addEventListener("click", function () {
setTime(0);
}, false);
// Skip backward 10 seconds
document.getElementById("rew").addEventListener("click", function () {
setTime(-10);
}, false);
// Skip forward 10 seconds
document.getElementById("fwd").addEventListener("click", function () {
setTime(10);
}, false);
// set src == latest video file URL
document.getElementById("loadVideo").addEventListener("click", getVideo, false);
// fail with message
video.addEventListener("error", function (err) {
errMessage(err);
}, true);
// playback speed buttons
document.getElementById("slower").addEventListener("click", function () {
video.playbackRate -= .25;
}, false);
document.getElementById("faster").addEventListener("click", function () {
video.playbackRate += .25;
}, false);
document.getElementById("normal").addEventListener("click", function () {
video.playbackRate = 1;
}, false);
document.getElementById("play").click();
} // end of runtime
}// end of master
</script>
</head>
<body onload="init();" >
<video id="Video1" controls autoplay loop height="320" width="640" title="Sig 0700">
HTML5 Video is required for this example
</video>
<div id="buttonbar" style="display: none;")>
<button id="restart" title="Restart button">[]</button>
<button id="slower" title="Slower playback button">-</button>
<button id="rew" title="Rewind button" ><<</button>
<button id="play" title="Play button">></button>
<button id="fwd" title="Forward button" >>></button>
<button id="faster" title="Faster playback button">+</button>
<button id="normal" title="Reset playback rate button">=</button>
</div>
<div id= "inputField" style="display:none;" >
<label>Type or paste a video URL: <br/>
<input type="text" id="videoFile" style="width: 300px;" title="video file input field" value="http://ie.microsoft.com/testdrive/ieblog/2011/nov/pp4_blog_demo.mp4" />
<button id="loadVideo" title="Load video button" >Load</button>
</label>
</div>
<div title="Error message area" id="errorMsg" style="color:Red;"></div>
</body>
</html>
<强>用法:强>
public final class U {
public static void picassoCombo(final RequestCreator thumbnail,
final RequestCreator large,
final ImageView imageView) {
Target target = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
imageView.setImageBitmap(bitmap);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
imageView.setImageDrawable(errorDrawable);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
thumbnail.into(imageView);
}
};
imageView.setTag(target); // To prevent target from being garbage collected
large.into(target);
}
}
在上面的示例中,首先设置占位符,然后设置缩略图URL,无论缩略图请求是完成,成功还是失败,都会在完成后设置大图像请求。如果大图像请求失败,则设置错误drawable。
唯一的问题是,如果您使用setIndicatorsEnabled(true)
调试指标,则不会显示大型请求。据我所知,这似乎是根据this issue convo