使用RecyclerView加载项目时出错 [英] Error to load item with RecyclerView
问题描述
我知道RecyclerView每次都会重新加载项目以节省内存并提高性能.但是,我发现图像有问题,那就是当我开始快速滚动recyclerView时,元素开始以错误的顺序充电.我将视频放在发生情况的描述中.我该如何解决此错误?
I know that RecyclerView loads the items again every time to save memory and increase performance. However, I found a problem with the images, that is that when I start to scroll quickly the recyclerView the elements start to recharge in the wrong order. I put the video in description of what happens. How can I resolve this error?
LINK: https://www.youtube.com/watch?v=iwHUYgWIm5g
RecyclerViewAdapter.class
RecyclerViewAdapter.class
package com.example.mattiaferigutti.chatjava;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.squareup.picasso.Picasso;
import java.io.IOException;
import java.util.List;
public class RecyclerMessegeAdapter extends RecyclerView.Adapter<RecyclerMessegeAdapter.MyViewHolder> {
private List<Message> messages;
private FirebaseAuth mAuth;
private StorageReference storageRef;
private Context mContext;
public RecyclerMessegeAdapter(List<Message> messages, Context context) {
this.messages = messages;
this.mContext = context;
mAuth = FirebaseAuth.getInstance();
storageRef = FirebaseStorage.getInstance().getReference();
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.message_single_layout,
null, false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, int i) {
String currentUserId = mAuth.getUid();
Message currentMessage = messages.get(i);
String fromUser = currentMessage.getMessageUser();
if (fromUser.equals(currentUserId) && currentMessage.getMessageType().equals("text")) {
myViewHolder.textView.setBackgroundResource(R.drawable.message_text_background);
myViewHolder.textView.setTextColor(Color.WHITE);
myViewHolder.imageView.setVisibility(View.GONE);
myViewHolder.textView.setText(currentMessage.getMessageText());
} else if (currentMessage.getMessageType().equals("text")) {
myViewHolder.textView.setBackgroundResource(R.drawable.message_text_background);
myViewHolder.textView.setBackgroundColor(Color.WHITE);
myViewHolder.textView.setTextColor(Color.BLACK);
myViewHolder.imageView.setVisibility(View.GONE);
myViewHolder.textView.setText(currentMessage.getMessageText());
} else if (currentMessage.getMessageType().equals("image")) {
myViewHolder.textView.setVisibility(View.GONE);
String url = currentMessage.getMessageText();
storageRef.child("message_image/" + url + ".jpg").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
Picasso.get()
.load(uri)
.into(myViewHolder.imageView);
myViewHolder.imageView.setVisibility(View.VISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
}
}
//TODO: mettere il testo a destra o a sinistra
@Override
public int getItemCount() {
return messages.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private ImageView imageView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.message);
imageView = itemView.findViewById(R.id.imageView);
}
}
}
MainActivity.class
MainActivity.class
package com.example.mattiaferigutti.chatjava;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final int GALLERY_PICK = 123;
//Firebase
private FirebaseAuth mAuth;
private DatabaseReference myRef;
//Storage Firebase
private StorageReference mImageStorage;
private Toolbar mToolbar;
private String mCurrentUserId;
private EditText mTextInput;
private Button mSendBtn;
private ImageButton mPlusBtn;
private RecyclerView mMessagesList;
private final List<Message> messages = new ArrayList<>();
private RecyclerMessegeAdapter mAdapter;
private String usersDentist = "aaXmkFhvrUWmuzC6GDZAV8a0i0u1";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
myRef = FirebaseDatabase.getInstance().getReference();
mImageStorage = FirebaseStorage.getInstance().getReference();
mToolbar = findViewById(R.id.main_page_toolbar);
mSendBtn = findViewById(R.id.sendButton);
mTextInput = findViewById(R.id.textEdit);
mMessagesList = findViewById(R.id.recyclerView);
mPlusBtn = findViewById(R.id.plusBtn);
setSupportActionBar(mToolbar);
getSupportActionBar().setTitle("Chat");
if (mAuth.getCurrentUser() != null)
mCurrentUserId = mAuth.getCurrentUser().getUid();
mAdapter = new RecyclerMessegeAdapter(messages, this);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mMessagesList.setLayoutManager(layoutManager);
mMessagesList.isAttachedToWindow();
mMessagesList.setAdapter(mAdapter);
if (mAuth.getCurrentUser() != null)
loadMessages();
mMessagesList.scrollToPosition(messages.size()-1);
mSendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String textSend = mTextInput.getText().toString();
long currentMillis = System.currentTimeMillis();
myRef.child("messages").child(mCurrentUserId).child(usersDentist).push().setValue(new Message(
textSend, currentMillis, mCurrentUserId, "text"
));
myRef.child("messages").child(usersDentist).child(mCurrentUserId).push().setValue(new Message(
textSend, currentMillis, mCurrentUserId, "text"
));
mTextInput.setText("");
}
});
mPlusBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent, "SELECT IMAGE"),
GALLERY_PICK);
}
});
}
private void loadMessages() {
myRef.child("messages").child(mCurrentUserId).child(usersDentist).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//messages.clear();
Message message = dataSnapshot.getValue(Message.class);
messages.add(message);
/*if (messages.size() > 0) {
final LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);
mMessagesList.setLayoutManager(manager);
mAdapter = new RecyclerMessegeAdapter(messages, MainActivity.this);
mMessagesList.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}*/
mAdapter.notifyDataSetChanged();
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
mAdapter.notifyDataSetChanged();
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
mAdapter.notifyDataSetChanged();
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
@Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser == null) {
sendToStart();
}
}
private void sendToStart() {
Intent startActivity = new Intent(MainActivity.this, StartActivity.class);
startActivity(startActivity);
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.account_settings:
break;
case R.id.all_users:
break;
case R.id.log_out:
FirebaseAuth.getInstance().signOut();
sendToStart();
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK && resultCode == RESULT_OK) {
Uri image = data.getData();
long currentMillis = System.currentTimeMillis();
final String pushId = String.valueOf(myRef.push());
myRef.child("messages").child(mCurrentUserId).child(usersDentist).push().setValue(new Message(
pushId, currentMillis, mCurrentUserId, "image"
));
myRef.child("messages").child(usersDentist).child(mCurrentUserId).push().setValue(new Message(
pushId, currentMillis, mCurrentUserId, "image"
));
StorageReference filePath = mImageStorage.child("message_image").child(pushId + ".jpg");
filePath.putFile(image).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "succeful", Toast.LENGTH_SHORT).show();
mAdapter.notifyDataSetChanged();
}
}
});
}
}
}
推荐答案
https://github.com/QuickBlox/ChatMessagesAdapter-android
ChatMessagesAdapter for Android
ChatMessagesAdapter for Android
QuickBlox易于使用的UI库,用于在android应用程序内部显示quickblox聊天消息.
QuickBlox simple to use UI library for showing quickblox chat messages inside android application.
Ready-to-go QBChatMessage view adapter with a set of view types.
UI customisation for all message types.
Flexibility in improving and extending functionality.
Easy to connect with Quickblox.
Optimised and performant.
Flexible mechanism for styling layout for chat messages.
Add custom widgets inside predefined layout.
这可能会帮助
这篇关于使用RecyclerView加载项目时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!