MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
public static final String ANONYMOUS = "anonymous";
public static final int RC_SIGN_IN = 1;
private static final int RC_PHOTO_PICKER = 2;
private String mUsername;
// Firebase instance variables
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mMessagesDatabaseReference;
private ChildEventListener mChildEventListener;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private FirebaseStorage mFirebaseStorage;
private StorageReference mChatPhotosStorageReference;
private FirebaseRemoteConfig mFirebaseRemoteConfig;
private ProgressBar progressBar;
private RecyclerView recyclerView;
private FloatingActionButton floatingActionButton;
PhotosAdapter contactsAdapter;
List<Photos> contactList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(ProgressBar)findViewById(R.id.progressbar);
mUsername = ANONYMOUS;
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
floatingActionButton=(FloatingActionButton)findViewById(R.id.floatingactionbutton);
contactList = new ArrayList();
progressBar.setVisibility(View.GONE);
// Initialize Firebase components
mFirebaseDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseStorage = FirebaseStorage.getInstance();
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
mMessagesDatabaseReference = mFirebaseDatabase.getReference().child("messages");
mChatPhotosStorageReference = mFirebaseStorage.getReference().child("chat_photos");
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
onSignedInInitialize(user.getDisplayName());
} else {
// User is signed out
onSignedOutCleanup();
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setProviders(
AuthUI.EMAIL_PROVIDER,
AuthUI.GOOGLE_PROVIDER)
.build(),
RC_SIGN_IN);
}
}
};
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER);
}
});
mMessagesDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Photos imageUploadInfo = postSnapshot.getValue(Photos.class);
if(!contactList.contains(imageUploadInfo)){
contactList.add(imageUploadInfo);
Log.i(TAG, "onDataChange: "+contactList);
}
}
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
progressBar.setVisibility(View.GONE);
recyclerView.setAdapter(contactsAdapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(),5));
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
// Sign-in succeeded, set up the UI
Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// Sign in was canceled by the user, finish the activity
Toast.makeText(this, "Sign in canceled", Toast.LENGTH_SHORT).show();
finish();
}
}else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
// Get a reference to store file at chat_photos/<FILENAME>
StorageReference photoRef = mChatPhotosStorageReference.child(selectedImageUri.getLastPathSegment());
// Upload file to Firebase Storage
photoRef.putFile(selectedImageUri)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// When the image has successfully uploaded, we get its download URL
// progressBar.setVisibility(View.VISIBLE);
Uri downloadUrl = taskSnapshot.getDownloadUrl();
// Set the download URL to the message box, so that the user can send it to the database
Photos friendlyMessage = new Photos(downloadUrl.toString());
mMessagesDatabaseReference.push().setValue(friendlyMessage);
}
});
}
}
@Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
@Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null) {
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
}
}
private void onSignedInInitialize(String username) {
mUsername = username;
}
private void onSignedOutCleanup() {
mUsername = ANONYMOUS;
}
}
假设我将图像上传到firebase存储,它会在app的recyclerview的imageview中检索到。当我上传第二张图片时,第一张图片会在我的应用中显示两次,第二张图片会显示一次。当我上传第三张图像时,第一张图像显示三次,第二张图像显示两次,第三张图像一次显示。我知道问题出在mMessagesDatabaseReference.addValueEventListener
,但我无法弄明白。请帮帮我..
答案 0 :(得分:1)
我想在每次新上传时都会调用onDataChange
所有数据。因此,您必须在添加项目之前清除contactList
,例如:
public void onDataChange(DataSnapshot snapshot) {
contactList.clear()
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Photos imageUploadInfo = postSnapshot.getValue(Photos.class);
if(!contactList.contains(imageUploadInfo)){
contactList.add(imageUploadInfo);
Log.i(TAG, "onDataChange: "+contactList);
}
}
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
progressBar.setVisibility(View.GONE);
recyclerView.setAdapter(contactsAdapter);
}
答案 1 :(得分:0)
使用ChildEventListener
代替value event listener
。
值事件侦听器在单个更改时再次获取所有数据,因此对于添加图像2,还将在值事件中接收图像1。
在ChildEventListener
中,您可以将方法onChildAdded()
添加到回收站。
像这样使用子事件监听器,不需要for循环,在添加子进程时会调用它,避免需要进行循环
在添加项目后也不要忘记在recyclerAdapter上调用notify以显示视图上的更改
在onCreate方法中移动它们并在那里初始化:
contactList = new ArrayList();
contactsAdapter=new PhotosAdapter(contactList,getApplicationContext());
recyclerView.setAdapter(contactsAdapter);
从firebase获取子代码的代码
private void attachDatabaseReadListener() {
if (mChildEventListener == null) {
mChildEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Photos imageUploadInfo = dataSnapshot.getValue(Photos.class);
if (!contactList.contains(imageUploadInfo)) {
contactList.add(imageUploadInfo);
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
}
mMessagesDatabaseReference.addChildEventListener(mChildEventListener);
}
}