Android 单击“上一步”按钮时重复值-已修复
这是我的情况 在此屏幕中,我单击“评论”按钮 “注释”活动打开,我键入所需内容 该评论已成功添加到firebase中,并将我带回详细活动 到目前为止一切都很好!现在让我们添加另一条评论。现在你看我得到了重复的评论 我希望你也能看到。现在在DetailActivity中,我有一个名为Android 单击“上一步”按钮时重复值-已修复,android,firebase,android-recyclerview,Android,Firebase,Android Recyclerview,这是我的情况 在此屏幕中,我单击“评论”按钮 “注释”活动打开,我键入所需内容 该评论已成功添加到firebase中,并将我带回详细活动 到目前为止一切都很好!现在让我们添加另一条评论。现在你看我得到了重复的评论 我希望你也能看到。现在在DetailActivity中,我有一个名为queryFirebaseDb()的方法,该方法在onCreate()和onResume()方法中都被调用。如果我不使用onResume()方法,那么在CommentActivity中单击back按钮后,数据将
queryFirebaseDb()
的方法,该方法在onCreate()
和onResume()方法中都被调用。如果我不使用onResume()方法,那么在CommentActivity中单击back按钮后,数据将不会显示。你知道我现在要去哪里了吧?问题是如何避免从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");
}
}
瞧 一些我以为你在使用Android时会知道的东西:
基本上,在android中,您需要了解生命周期是如何工作的。因此,当您从onCreate
和onResume
调用queryFirebaseDb()
时,您的应用程序在活动开始时同时执行两个查询
生命周期是这样的OnCreate->onResume
。所以,当活动开始时,根据您的逻辑,查询在onCreate
上执行一次比在onResume
上执行一次更有意义
答案就在这里
我注意到您正在使用ArrayList 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);
}
if(dataSnapshot.exists()){
ArrayList tempComments=新建ArrayList();
对于(DataSnapshot DataSnapshot:DataSnapshot.getChildren()){
Comment Comment=dataSnapshots.getValue(Comment.class);
//mUserDatabase=FirebaseDatabase.getInstance().getReference().child(“用户”).child(用户ID);
添加(注释);
//Log.d(Log_标记,String.valueOf(commentArrayList.size());
}
commentArrayList=tempComments;//假设要将数据存储在类字段中
displayCommentsAdapter=新的displayCommentsAdapter(这是commentArrayList);
mRecyclerView.setAdapter(displayCommentsAdapter);
显示CommentsAdapter.setCommentsData(commentArrayList);
noCommentsTextView.setVisibility(View.GONE);
//commentsTextView.setVisibility(View.VISIBLE);
}
一些我以为你在使用Android时会知道的东西:
基本上,在android中,您需要了解生命周期是如何工作的。因此,当您从onCreate
和onResume
调用queryFirebaseDb()
时,您的应用程序在活动开始时同时执行两个查询
生命周期是这样的OnCreate->onResume
。所以,当活动开始时,根据您的逻辑,查询在onCreate
上执行一次比在onResume
上执行一次更有意义
答案就在这里
我注意到您正在使用ArrayList 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);
}
if(dataSnapshot.exists()){
ArrayList tempComments=新建ArrayList();
对于(DataSnapshot DataSnapshot:DataSnapshot.getChildren()){
Comment Comment=dataSnapshots.getValue(Comment.class);
//mUserDatabase=FirebaseDatabase.getInstance().getReference().child(“用户”).child(用户ID);
添加(注释);
//Log.d(Log_标记,String.valueOf(commentArrayList.size());
}
commentArrayList=tempComments;//假设要将数据存储在类字段中
displayCommentsAdapter=新的displayCommentsAdapter(这是commentArrayList);
mRecyclerView.setAdapter(displayCommentsAdapter);
显示CommentsAdapter.setCommentsData(commentArrayList);
noCommentsTextView.setVisibility(View.GONE);
//commentsTextView.setVisibility(View.VISIBLE);
}
您的数据库是否有相同的记录两次,还是仅在ui中显示?您的数据库是否有相同的记录两次,还是仅在ui中显示?