Android 回收视图';s适配器显示相同的图片,而不是不同的图片
我有一个适配器,它应该从Firebase存储中获取每个用户的配置文件图片,并将其设置在ImageView中,但发生的是,每次更新时,它都会更改所有图像视图的相同配置文件图片。(因此,它在所有图像视图上显示最后获取的图片)。这是获取和设置图片的代码部分:Android 回收视图';s适配器显示相同的图片,而不是不同的图片,android,firebase,Android,Firebase,我有一个适配器,它应该从Firebase存储中获取每个用户的配置文件图片,并将其设置在ImageView中,但发生的是,每次更新时,它都会更改所有图像视图的相同配置文件图片。(因此,它在所有图像视图上显示最后获取的图片)。这是获取和设置图片的代码部分: @Override public void onBindViewHolder(MyViewHolder holder, int position) { myHolder = holder; StorageReference
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
myHolder = holder;
StorageReference ref = storageRef.child("profilePictures").child(mDataset.get(position));
final long ONE_MEGABYTE = 1024 * 1024;
ref.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Log.d("Tag", "Success");
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
Log.d("Tag", "Failure");
}
});
myHolder.singleItemImage.setImageBitmap(bitmap);
}
@覆盖
公共无效onBindViewHolder(MyViewHolder,int位置){
我的持有者=持有者;
StorageReference ref=storageRef.child(“profilePictures”).child(mDataset.get(position));
最终长1兆字节=1024*1024;
ref.getBytes(一兆字节).addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时的公共void(字节[]字节){
日志d(“标记”、“成功”);
位图=位图工厂.decodeByteArray(字节,0,字节.长度);
}
}).addOnFailureListener(新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常){
//处理任何错误
日志d(“标签”、“故障”);
}
});
myHolder.singleItemImage.setImageBitmap(位图);
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="@drawable/ic_launcher_background" />
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/icon" />
</android.support.constraint.ConstraintLayout>
mUpdatesReference=FirebaseDatabase.getInstance().getReference(“时间更新”);
mAdapter=新的MyAdapter(myDataset);
ValueEventListener=新的ValueEventListener(){
@覆盖
公共void onDataChange(DataSnapshot DataSnapshot){
布尔值isChanged=false;
对于(DataSnapshot数据:DataSnapshot.getChildren()){
如果(时间<180)){
如果(!myDataset.contains(datas.getKey().toString())){
添加(datas.getKey().toString());
isChanged=true;
}
}否则{
myDataset.remove(datas.getKey().toString());
isChanged=true;
}
如果(已更改){
mAdapter.notifyDataSetChanged();
}
}
mUpdatesReference.addValueEventListener(侦听器);
mRecyclerView.setAdapter(mAdapter);
因为您获得位图并将其设置为方法外,而不释放该位图,所以它为所有用户设置。
只需将您的方法更改为:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
myHolder = holder;
StorageReference ref = storageRef.child("profilePictures").child(mDataset.get(position));
final long ONE_MEGABYTE = 1024 * 1024;
ref.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Log.d("Tag", "Success");
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if(bitmap!=null)
myHolder.singleItemImage.setImageBitmap(bitmap);
else myHolder.singleItemImage.setImageResource(R.drawable.YourPlaceholder);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
Log.d("Tag", "Failure");
myHolder.singleItemImage.setImageResource(R.drawable.YourPlaceholder);
}
});
}
@覆盖
公共无效onBindViewHolder(MyViewHolder,int位置){
我的持有者=持有者;
StorageReference ref=storageRef.child(“profilePictures”).child(mDataset.get(position));
最终长1兆字节=1024*1024;
ref.getBytes(一兆字节).addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时的公共void(字节[]字节){
日志d(“标记”、“成功”);
位图=位图工厂.decodeByteArray(字节,0,字节.长度);
if(位图!=null)
myHolder.singleItemImage.setImageBitmap(位图);
else myHolder.singleItemImage.setImageResource(R.drawable.YourPlaceholder);
}
}).addOnFailureListener(新的OnFailureListener(){
@凌驾
public void onFailure(@NonNull异常){
//处理任何错误
日志d(“标签”、“故障”);
myHolder.singleItemImage.setImageResource(R.drawable.YourPlaceholder);
}
});
}
首先使用位图参考更新模型
void downloadImage(int rowindex){
StorageReference ref = storageRef.child("profilePictures").child(mDataset.get(rowindex).getId());
final long ONE_MEGABYTE = 1024 * 1024;
ref.getBytes(ONE_MEGABYTE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Log.d("Tag", "Success");
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
mDataset.get(rowindex).setDownloadedBitmap(bitmap);
notifyDataSetChanged ();
}
ProfilePictureItem.java
public class ProfilePictureItem{
private String key;
private Bitmap downloadedBitmap;
public setKey(String key){
this.key=key;
}
public getKey(){
return key;
}
public setDownloadedBitmap(Bitmap downloadedBitmap){
this.downloadedBitmap=downloadedBitmap;
}
public getDownloadedBitmap(){
return downloadedBitmap;
}
}
你的意思是在onSuccess中移动设置吗?我尝试过,但实际情况是它不断地将图像从一个更改到另一个(因为适配器是从另一个活动调用的)。因此,现在每个图像视图仍然为所有图像显示相同的图像,但会不断更改。如果用户图像不可用,则必须设置占位符,否则请将其设置为imageview。如果不执行此操作,请将位图设置为imageview,并将其设置为所有其他imageview。只需为imageview设置占位符。如果是w,则xml中会有占位符你是什么意思?在xml中不起作用。因为你得到位图,它保留在内存中,每次你得到一个位图,它就会为所有的imageview设置。好的,但是我键入的是什么而不是“你的占位符”?我是否需要使用findViewById获取一些可绘制的内容?如何获取位图占位符?因为图像下载是异步工作的,当图像下载成功时,当前视图持有者索引更改为新索引,您必须将索引映射到位图并更新适配器。哪些是setImageBitmap和getImageBitmap函数?它们无法解析I我也是Java初学者,如何从模型中调用ProfilePictureItem?是否需要键入类似
ProfilePictureItem item=new ProfilePictureItem()
?
public void onBindViewHolder(MyViewHolder holder, int position) {
myHolder = holder;
Bitmap currentBitmap=mDataset.get(rowindex).getDownloadedBitmap();
if(currentBitmap!=null){
myHolder.singleItemImage.setImageBitmap(currentBitmap);
}else{
downloadImage(position);
myHolder.singleItemImage.setImageResource(R.drawable.default);
}
}
public class ProfilePictureItem{
private String key;
private Bitmap downloadedBitmap;
public setKey(String key){
this.key=key;
}
public getKey(){
return key;
}
public setDownloadedBitmap(Bitmap downloadedBitmap){
this.downloadedBitmap=downloadedBitmap;
}
public getDownloadedBitmap(){
return downloadedBitmap;
}
}