这是我的情况。
在此屏幕中,我点击评论按钮。
评论活动打开,我输入我想要的内容。
评论在firebase中成功添加,它将我带回细节活动。
到目前为止一切都很棒!现在让我们添加另一条评论。现在你看到我得到了重复的评论。
我希望你也能看到。现在在 DetailActivity 中,我有一个名为queryFirebaseDb()
的方法,该方法在onCreate()
和onResume()
方法中都被调用。如果我不使用onResume()方法,则在单击CommentActivity中的后退按钮后,将不会显示数据。你看我现在去哪里了吗?问题是如何从CommentActivity返回后避免重复数据。这是我的代码。
public class DetailActivity extends AppCompatActivity {
ArrayList<Comment> commentArrayList;
ImageView mImageView;
TextView mTitle;
TextView mDate;
TextView mDescription;
TextView mAuthor;
ToggleButton mFavBtn;
private TextView noCommentsTextView;
private TextView commentsTextView;
private ImageButton imageButton;
private FloatingActionButton mShareBtn;
private String newsTitle;
private String newsImage;
private String newsDate;
private String newsDescription;
private static String NEWS_SHARE_HASHTAG = "#EasyNewsApp";
private String date1;
private String date2;
private String newsUrl;
private String newsAuthor;
private Cursor favoriteCursor;
private DatabaseReference mDatabase;
private static Bundle bundle = new Bundle();
private Uri uri;
private RecyclerView mRecyclerView;
private DisplayCommentsAdapter displayCommentsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent i = getIntent();
mAuthor = (TextView) findViewById(R.id.detail_author);
mImageView = (ImageView) findViewById(R.id.detail_image_view);
mTitle = (TextView) findViewById(R.id.detail_title);
mDate = (TextView) findViewById(R.id.detail_publish_date);
mDescription = (TextView) findViewById(R.id.detail_description);
noCommentsTextView = (TextView)findViewById(R.id.noCommentsTextView);
commentsTextView = (TextView)findViewById(R.id.commentsTextView);
mShareBtn = (FloatingActionButton) findViewById(R.id.share_floating_btn);
mFavBtn = (ToggleButton) findViewById(R.id.fav_news_btn);
imageButton = (ImageButton)findViewById(R.id.detail_comment_image_btn);
mRecyclerView = (RecyclerView)findViewById(R.id.recycler_comments);
LinearLayoutManager manager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
commentArrayList = new ArrayList<>();
mDatabase = FirebaseDatabase.getInstance().getReference();
mFavBtn.setTextOn(null);
mFavBtn.setText(null);
mFavBtn.setTextOff(null);
newsAuthor = i.getStringExtra("author");
newsImage = i.getStringExtra("image");
newsTitle = i.getStringExtra("newsTitle");
newsDate = i.getStringExtra("date");
newsDescription = i.getStringExtra("description");
newsUrl = i.getStringExtra("url");
date1 = newsDate.substring(0, 10);
date2 = newsDate.substring(11, 19);
Picasso.with(this).load(newsImage)
.placeholder(R.drawable.ic_broken_image)
.into(mImageView);
mTitle.setText(newsTitle);
mAuthor.setText("Author: " + newsAuthor);
mDescription.setText(newsDescription);
mDate.setText(date2 + ", " + date1);
mShareBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent shareIntent = createShareNewsIntent();
startActivity(shareIntent);
}
});
imageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent commentIntent = new Intent(DetailActivity.this, CommentActivity.class);
commentIntent.putExtra("newsTitle",newsTitle);
startActivity(commentIntent);
}
});
/**
* Handling the add/remove news part. We check if the specific news article
* exists in favourite.db.
*/
favoriteCursor = getContentResolver().query(FavouriteContract.FavouriteEntry.CONTENT_URI,
null,
FavouriteContract.FavouriteEntry.COLUMN_NEWS_TITLE + "=?",
new String[]{newsTitle},
null);
/**
* If yes then set the toggle button to true
*/
if (favoriteCursor.getCount() > 0) {
try {
mFavBtn.setChecked(true);
} finally {
favoriteCursor.close();
}
}
/**
* Else click the toggle button to add the news article as favourite
*/
mFavBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, final boolean isChecked) {
/**
* If checked the add the news article as favourite.
*/
if (isChecked) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
ContentValues contentValues = new ContentValues();
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_TITLE, newsTitle);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_AUTHOR, newsAuthor);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_DESCRIPTION, newsDescription);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_URL, newsUrl);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_URL_TO_IMAGE, newsImage);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_PUBLISHED_AT, newsDate);
//The actual insertion in the db.
uri = getContentResolver().insert(FavouriteContract.FavouriteEntry.CONTENT_URI, contentValues);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(DetailActivity.this, "Article with title: " + newsTitle + " was added", Toast.LENGTH_SHORT).show();
}
}.execute();
} else {
/**
* If you uncheck the toggle button then delete the news article from the favourite db.
*/
Uri newsTitleOfFavNews = FavouriteContract.FavouriteEntry.buildNewsUriWithTitle(newsTitle);
//String title = uri.getPathSegments().get(1);// Get the task ID from the URI path
getContentResolver().delete(
newsTitleOfFavNews,
null,
null);
Toast.makeText(DetailActivity.this, "News article deleted from favourites ", Toast.LENGTH_SHORT).show();
}
}
});
queryFirebaseDb();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.detail_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if(item.getItemId() == R.id.detail_browser_btn){
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(newsUrl));
startActivity(browserIntent);
} if(item.getItemId() == android.R.id.home){
NavUtils.navigateUpFromSameTask(this);
return true;
}
return true;
}
private Intent createShareNewsIntent() {
Intent shareIntent = ShareCompat.IntentBuilder.from(this)
.setType("text/plain")
.setText(NEWS_SHARE_HASHTAG + "\n\n\n" + newsTitle
+ "\n\n\n" + newsDescription
+ "\n\n\n" + newsDate)
.getIntent();
return shareIntent;
}
@Override
protected void onStart() {
super.onStart();
//queryFirebaseDb();
}
@Override
protected void onRestart() {
super.onRestart();
queryFirebaseDb();
//displayCommentsAdapter.notifyDataSetChanged();
}
public void queryFirebaseDb(){
/**
* Querying the database to check if the specific article has comments.
*/
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = mDatabase.child("comments").orderByChild("newsTitle").equalTo(newsTitle);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot dataSnapshots : dataSnapshot.getChildren()){
Comment comment = dataSnapshots.getValue(Comment.class);
//mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
commentArrayList.add(comment);
displayCommentsAdapter = new DisplayCommentsAdapter(this,commentArrayList);
mRecyclerView.setAdapter(displayCommentsAdapter);
displayCommentsAdapter.setCommentsData(commentArrayList);
//Log.d(LOG_TAG, String.valueOf(commentArrayList.size()));
}
noCommentsTextView.setVisibility(View.GONE);
//commentsTextView.setVisibility(View.VISIBLE);
}else{
//Toast.makeText(DisplayComments.this,"There are no comments posted",Toast.LENGTH_LONG).show();
noCommentsTextView.setVisibility(View.VISIBLE);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
/*
@Override
protected void onPause() {
super.onPause();
bundle.putBoolean("ToggleButtonState", mFavBtn.isChecked());
}
@Override
public void onResume() {
super.onResume();
mFavBtn.setChecked(bundle.getBoolean("ToggleButtonState",false));
}
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mFavBtn.setChecked(savedInstanceState.getBoolean("ToggleButtonState",false));
savedInstanceState.putParcelableArrayList("newsList",commentArrayList);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("ToggleButtonState",mFavBtn.isChecked());
outState.getParcelableArrayList("newsList");
}
}
和
public class CommentActivity extends AppCompatActivity {
private static final String REQUIRED = "Required";
private static final String TAG = CommentActivity.class.getSimpleName();
Toolbar toolbar;
DatabaseReference mDatabase;
EditText titleEt;
EditText bodyEt;
Button commentBtn;
String newsTitle;
Intent i;
String name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comment);
toolbar = (Toolbar) findViewById(R.id.comment_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Add comment");
mDatabase = FirebaseDatabase.getInstance().getReference();
titleEt = (EditText) findViewById(R.id.comment_title);
bodyEt = (EditText) findViewById(R.id.comment_body);
commentBtn = (Button) findViewById(R.id.comment_btn);
i = getIntent();
newsTitle = i.getStringExtra("newsTitle");
commentBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
submitPost();
}
});
}
private void submitPost() {
final String title = titleEt.getText().toString();
final String body = bodyEt.getText().toString();
// Title is required
if (TextUtils.isEmpty(title)) {
titleEt.setError(REQUIRED);
return;
}
// Body is required
if (TextUtils.isEmpty(body)) {
bodyEt.setError(REQUIRED);
return;
}
// Disable button so there are no multi-posts
setEditingEnabled(false);
Toast.makeText(this, "Posting...", Toast.LENGTH_SHORT).show();
// [START single_value_read]
final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
mDatabase.child("Users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user value
User user = dataSnapshot.getValue(User.class);
// [START_EXCLUDE]
if (user == null) {
// User is null, error out
Log.e(TAG, "User " + userId + " is unexpectedly null");
Toast.makeText(CommentActivity.this,
"Error: could not fetch user.",
Toast.LENGTH_SHORT).show();
} else {
// Write new post
name = dataSnapshot.child("name").getValue().toString();
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
String strDate = sdf.format(c.getTime());
writeNewPost(userId,strDate,name,newsTitle, title, body);
}
// Finish this Activity, back to the stream
setEditingEnabled(true);
finish();
// [END_EXCLUDE]
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
// [START_EXCLUDE]
setEditingEnabled(true);
// [END_EXCLUDE]
}
});
// [END single_value_read]
}
private void writeNewPost(String userId,String date,String
commentAuthor, String newsTitle, String commentTitle, String
commentBody){
String key = mDatabase.child("comments").push().getKey();
Comment comment = new Comment(userId, date,
commentAuthor,newsTitle,commentTitle,commentBody);
Map<String, Object> commentValues = comment.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/comments/" + key, commentValues);
mDatabase.updateChildren(childUpdates);
}
private void setEditingEnabled(boolean enabled) {
titleEt.setEnabled(enabled);
bodyEt.setEnabled(enabled);
if (enabled) {
commentBtn.setVisibility(View.VISIBLE);
} else {
commentBtn.setVisibility(View.GONE);
}
}
}
更新
我用过这个
@Override
protected void onRestart() {
super.onRestart();
finish();
startActivity(getIntent());
}
瞧!
答案 0 :(得分:2)
我认为你在做Android时会知道的一些东西:
基本上,在android中,你需要了解生命周期是如何工作的。因此,当您从queryFirebaseDb()
和onCreate
致电onResume
时,您的应用最初会在活动开始时同时进行两次查询。
生命周期就像这样OnCreate -> onResume
。因此,有意义的是,当活动开始时,查询会根据您的逻辑在onCreate
上执行一次而不是在onResume
上执行。
答案就在这里
我注意到您使用的是ArrayList<Comment> commentArrayList;
ArrayList
结构,它允许您拥有重复数据。而且,如果你研究Firebase
的行为以及你的查询是如何构建的,就像这样,
Query query = mDatabase.child("comments").orderByChild("newsTitle").equalTo(newsTitle);
此查询意味着您收集所有评论,之前的评论和新评论(不仅仅是新评论),我认为您只是希望(1)最近添加评论或(2)用新的评论替换旧的评论。
这样做的第一种方式听起来很复杂,尽管这并非不可能。但是,第二种做法很容易。
因此,要解决这个问题, 简单地说,用这个数据替换你拥有的arrayList。
if(dataSnapshot.exists()){
ArrayList<Comment> tempComments = new ArrayList();
for(DataSnapshot dataSnapshots : dataSnapshot.getChildren()){
Comment comment = dataSnapshots.getValue(Comment.class);
//mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
tempComments.add(comment);
//Log.d(LOG_TAG, String.valueOf(commentArrayList.size()));
}
commentArrayList = tempComments; //assuming you want to store the data in the class fields
displayCommentsAdapter = new DisplayCommentsAdapter(this,commentArrayList);
mRecyclerView.setAdapter(displayCommentsAdapter);
displayCommentsAdapter.setCommentsData(commentArrayList);
noCommentsTextView.setVisibility(View.GONE);
//commentsTextView.setVisibility(View.VISIBLE);
}