Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 单击“上一步”按钮时重复值-已修复_Android_Firebase_Android Recyclerview - Fatal编程技术网

Android 单击“上一步”按钮时重复值-已修复

Android 单击“上一步”按钮时重复值-已修复,android,firebase,android-recyclerview,Android,Firebase,Android Recyclerview,这是我的情况 在此屏幕中,我单击“评论”按钮 “注释”活动打开,我键入所需内容 该评论已成功添加到firebase中,并将我带回详细活动 到目前为止一切都很好!现在让我们添加另一条评论。现在你看我得到了重复的评论 我希望你也能看到。现在在DetailActivity中,我有一个名为queryFirebaseDb()的方法,该方法在onCreate()和onResume()方法中都被调用。如果我不使用onResume()方法,那么在CommentActivity中单击back按钮后,数据将

这是我的情况

在此屏幕中,我单击“评论”按钮

“注释”活动打开,我键入所需内容

该评论已成功添加到firebase中,并将我带回详细活动

到目前为止一切都很好!现在让我们添加另一条评论。现在你看我得到了重复的评论

我希望你也能看到。现在在DetailActivity中,我有一个名为
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中显示?