Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

怎么判断adapter中的imageView重用 #1302

Closed
ouyangzn opened this issue Feb 25, 2016 · 18 comments
Closed

怎么判断adapter中的imageView重用 #1302

ouyangzn opened this issue Feb 25, 2016 · 18 comments

Comments

@ouyangzn
Copy link

我想知道Picasso是怎么检测到imageView被重用的,源代码里面没看到,现在我遇到一个问题,就是关于重用的

@JakeWharton
Copy link
Member

Picasso keeps a map of ImageView -> URL and when the same ImageView is seen twice, the loading of the original URL is canceled and and new one is started.

@interestingdev
Copy link

a simple way is set the url as a tag into one View(ImageView). You just need to check if the new url is same or not with the tagged one. See View.setTag(Object obj) and View.getTag()

@ouyangzn
Copy link
Author

thanks for answer,我的需求是加载好友头像,因为涉及到好友头像变更等,所以没有完全使用Picasso来下载并加载头像,而是先通过okhttp下载头像到SDCard,然后再用Picasso加载,我在下载之前设置了tag,下载完成后比较tag是否相同.在listView快速滑动时,头像下载很快,但是Picasso从SDCard加载头像用时200多ms,导致了头像错乱问题(就是已经进入到if (reqUrl.equals(tagUrl)) 条件里面,然后adapter被刷出界面重用了,这个好友使用默认头像,但是200多ms后被修改成上一个人的头像了)
`/**
* 加载头像---------存在快速滑动时,如果下载速度很快,会导致复用性问题使头像错乱
* @param context APP上下文
* @param target 要显示图片的ImageView
* @param userId 用户id
* @param headUrl 头像地址
*/
public synchronized static void loadHead(final Context context, final ImageView target, final long userId, final String headUrl) {
target.setTag(R.id.tag_key_head_url, null);
if (StringUtil.isEmpty(headUrl)) {
target.setImageResource(R.drawable.default_photo);
return;
}
String headPath = getContactHeadPath(context, userId);
final File file = new File(headPath);
float dimension = context.getResources().getDimension(R.dimen.head_photo_small);
final int headSize = ScreenUtils.dp2px(context, dimension);
if (file.exists()) {
Picasso.with(context).load(file).error(R.drawable.default_photo).placeholder(R.drawable.default_photo)
.resize(headSize, headSize).centerInside()
.config(Bitmap.Config.RGB_565).into(target);
} else {// 头像在本地不存在,去服务器下载
target.setImageResource(R.drawable.default_photo);
if (!NetUtils.isNetworkConnected(context)) {
return;
}
// 下载头像
MainApplication app = (MainApplication)context.getApplicationContext();
ServerInfo serverInfo = app.getServerInfo();
if (serverInfo == null) {
return;
}
StringBuilder url = new StringBuilder("http://");
url.append(serverInfo.fileAccessIp).append(":").append(serverInfo.fileAccessPort).append("/").append(headUrl);
target.setTag(R.id.tag_key_head_url, url.toString());
HttpContactManager.downloadHeadAsync(url.toString(), headPath, new DefaultCallback() {
@OverRide
public void onSuccess(Object object) {
String reqUrl = (String) object;
String tagUrl = (String) target.getTag(R.id.tag_key_head_url);
Log.d(TAG, "------loadHead.target = " + target + " ,userId = " + userId + " ,reqUrl = " + reqUrl + " ,tagUrl = " + tagUrl);
if (reqUrl.equals(tagUrl)) {
final long beginTime = System.currentTimeMillis();
RequestCreator config = Picasso.with(context).load(file).error(R.drawable.default_photo).placeholder(R.drawable.default_photo)
.resize(headSize, headSize).centerInside().config(Bitmap.Config.RGB_565);
config.into(target, new Callback() {
@OverRide
public void onSuccess() {
Log.d(TAG, "------图片加载用时:" + (System.currentTimeMillis() - beginTime));
}

                        @Override
                        public void onError() {

                        }
                    });
                }
            }
        });
    }
}`

@ouyangzn
Copy link
Author

@NashLegend
Copy link

记得貌似好像大约Google给的教程里有类似的解决方式~
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
不知道Picasso原理是不是一样~

@miao1007
Copy link

miao1007 commented Mar 3, 2016

我觉得你在这里问不太好,你应该发到 stackoverflow

you should ask for stackoverflow instead of issue

@ThomasLau
Copy link

围观 JakeWharton ^_^

@l123456789jy
Copy link

JakeWharton ^_^

@donglua
Copy link

donglua commented Mar 4, 2016

JakeWharton 哈哈 ^_^

@yilylong
Copy link

yilylong commented Mar 4, 2016

JakeWharton ^_^

1 similar comment
@25343215
Copy link

25343215 commented Mar 4, 2016

JakeWharton ^_^

@ChoicesWang
Copy link

you are my idol . JakeWharton ^_^

@runweok
Copy link

runweok commented Mar 4, 2016

大神太棒了!@JakeWharton 你懂的
回到这个问题,adapter判断imageview重用和picasso没关系。
listview控件能判断每一行是否可见。listview让新可见的行重用不可见的行。前提是新可见的行和不可见的行是同类型的,那么view对象就可以重用,包括里面的imageview。通常在adapter的getview的方法中会告诉picasso重新绑定这个imageview和一个url的关系。recycleview原理一样。
所以楼主要保证的是每次都给imageview赋新值。由于异步加载有延迟,你可能需要先设置一个默认图,否则会有图像重复一段时间。

@tonybase
Copy link

tonybase commented Mar 4, 2016

JakeWharton 哈哈 ^_^

@ghost
Copy link

ghost commented Mar 4, 2016

语言不是障碍了 , 围观 JakeWharton 大神
Language is not a barrier, look JakeWharton big god

@ronanhardiman
Copy link

I think you are right
@runweok

@ouyangzn
Copy link
Author

thanks everyone

@mikaelzero
Copy link

six six six

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests