Как обновлять общее количество дочерних узлов от дочернего узла firebase каждый раз на onDataChange из AddSingleValueEventListner? - PullRequest
2 голосов
/ 09 июля 2019

На следующем рисунке показана структура моей базы данных Firebase:

enter image description here

Все данные получены успешно.Вот мой класс модели.

public class Post
{
    public String lastname;
    public String postid;
    public long timestamp;
    public HashMap<String,Boolean> count;

    public Post()
    {
    }

    public Post(String lastname, long timestamp, String postid,HashMap count)
    {
        this.lastname=lastname;
        this.timestamp=timestamp;
        this.postid=postid;
        this.count=count;
    }

public HashMap<String, Boolean> getCounts() {
        return count;
    }

    public void setCounts(HashMap<String, Boolean> count) {
        this.count = count;
    }

В основной деятельности я использовал для получения данных

 mAdapter = new PostAdapter(MainActivity.this);

    getAllPost(null);
    postList.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            if (!recyclerView.canScrollVertically(1))
            {

                loaded=loaded+10;
                if (totalPost== mAdapter.getItemCount())
                {
                    Toast.makeText(MainActivity.this, "no more post", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    getAllPost(mAdapter.getLastItemId());
                }

            }
        }
    });
postList.setAdapter(mAdapter);
private void getAllPost(final String nodeId)
    {
        final Query query;
        final int left= (int) (totalPost-mAdapter.getItemCount());
        Toast.makeText(this, String .valueOf(left), Toast.LENGTH_SHORT).show();


        if (nodeId == null)
        {
            query = PostRef
                    .orderByChild("timestamp")
                    .limitToLast(mPostsPerPage);
        }

        else
        {

            if (left<10)
            {
                query = PostRef
                        .orderByChild("timestamp")
                        .limitToFirst(left);
            }
            else
            {
                Long time=Long.parseLong(nodeId);
                query = PostRef
                        .orderByChild("timestamp").endAt(time)
                        .limitToLast(10);
            }

        }


        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                List<Post> userModels = new ArrayList<>();


                for (DataSnapshot userSnapshot : dataSnapshot.getChildren())
                {
                    userModels.add(userSnapshot.getValue(Post.class));

                }
                if (!(nodeId ==null))
                {
                    if (left>10)
                    {
                        userModels.remove(9);
                    }

                }


                Collections.reverse(userModels);
                mAdapter.addAll(userModels);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                throw databaseError.toException();
            }
        });
    }

И в адаптере:

      public class PostAdapter extends RecyclerView.Adapter<PostHolder>
    {
        List<Post> mPost;
        Context mContext;
        public PostAdapter(Context c) {
            this.mPost  = new ArrayList<>();
            mContext=c;
        }
        @NonNull
        @Override
        public PostHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            return new PostHolder(LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.all_post_layout, viewGroup, false));
        }
        @Override
            public void onBindViewHolder(@NonNull final PostHolder postHolder, final int i) {
    final String PostKey=mPost.get(i).getPostid();
            FirebaseAuth mAuth=FirebaseAuth.getInstance();
            final String currentUserID=mAuth.getCurrentUser().getUid();


    final DatabaseReference post=FirebaseDatabase.getInstance().getReference().child("Posts");
         showCounts(postHolder,i);
        setCountsButton(postHolder,i,currentUserID);
        tapOnCounts(postHolder,i,currentUserID,post,PostKey);
        }
private void tapOncounts(final PostHolder postHolder, final int i, final String currentUserID, final DatabaseReference post, final String postKey)
    {
        postHolder.countsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                if (mPost.get(i).getCounts() !=null)
                {
                    if(mPost.get(i).getCounts().containsKey(currentUserID))
                    {
                        post.child(postKey).child("counts").child(currentUserID).removeValue();
                        postHolder.countsButton.setImageResource(R.drawable.discounts);
                    }
                    else
                    {
                        postHolder.countsButton.setImageResource(R.drawable.counts);
                        post.child(postKey).child("counts").child(currentUserID).setValue(true);
                    }
                }
                else
                {
                    postHolder.countsButton.setImageResource(R.drawable.counts);
                    post.child(postKey).child("counts").child(currentUserID).setValue(true);
                }
            }
        });
    }
    private void setcountsButton(final PostHolder postHolder, int i, String currentUserID)
    {
        if (mPost.get(i).getCounts() !=null)
        {
            if(mPost.get(i).getCounts().containsKey(currentUserID))
            {
                postHolder.countsButton.setImageResource(R.drawable.counts);
            }
            else
            {
                postHolder.countsButton.setImageResource(R.drawable.discounts);
            }
        }
    }
    private void showCounts(PostHolder postHolder, int i)
    {
        if((mPost.get(i).getCounts() !=null))
        {
            postHolder.noOfcounts.setText(String.valueOf(mPost.get(i).getCounts().size()));
        }
        else
        {
            postHolder.noOfcounts.setText("0");
        }
    }
@Override
    public int getItemCount() {
        return mPost.size();
    }
    public void addAll(List<Post> newPost) {
        int initialSize = mPost.size();
        mPost.addAll(newPost);
        notifyItemRangeInserted(initialSize, newPost.size());
    }

    public String getLastItemId() {
        return String.valueOf(mPost.get(mPost.size() - 1).getTimestamp());
    }

}

Все успешно, но всегдаобщее количествоизменения дочернего элемента (добавлен новый дочерний элемент ИЛИ удален старый дочерний элемент) в recylerview узла подсчета не обновляется.Он будет обновляться только при попытке перейти к другому действию и перезапустить MainActivity.

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Чтобы получать обновления в реальном времени, вы должны использовать Query's addValueEventListener (слушатель ValueEventListener) метод:

Добавьте прослушиватель для изменений данных в этом месте.

При использовании addListenerForSingleValueEvent (слушатель ValueEventListener) :

Добавьте слушателя для одного изменения данных в этом месте.

Edit:

Чтобы получить размер вашего списка, измените следующую строку кода:

holder.count.setText(String.valueOf(mPost.get(i).getCount().size));

до

holder.count.setText(String.valueOf(getItemCount());
0 голосов
/ 09 июля 2019

Всякий раз, когда изменяется общее количество детей, ваш список модальных Post также меняется, например, userModels в вашем случае.Следовательно, всякий раз, когда ваш список моделей меняется, ваш адаптер должен быть уведомлен.Следовательно, я предполагаю добавить notifyDataSetChanged к адаптеру.

Попробуйте это:

query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    List<Post> userModels = new ArrayList<>();
    for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
        userModels.add(userSnapshot.getValue(Post.class));
    }
    mAdapter.notifyDataSetChanged(); //<<changes made HERE

}

@Override
public void onCancelled(DatabaseError databaseError) {
}
})

Я надеюсь, что для этого userModels является переменной экземпляра для вашего MainActivity и для него установлено значение mAdapter во время инициализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...