0

I am facing a problem to hide RecyclerView. From Last 2 night's I am looking for the solution but I have failed to find it.

I am using firebase recycleradapter to show value in recyclerview. When ever someone click the viewholderitem i save his Uid under the datasnapshot key.

So to show the value if datasnapshot don't have the uid key show the value in recyclerview. If the datasnapshot have the uid key don't show his data . everything works fine . But i want to hide the recyclerview and show a textview when every datasnapshot have the uid key and there is nothing to show in the recyclerview. My problem is in the last line . I can't hide the recyclerview and how the textview.

FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<ViewsAdapter>()
                .setQuery(ViewsRef,ViewsAdapter.class)
                .build();


        adapter = new FirebaseRecyclerAdapter<ViewsAdapter, ViewsAdapterHolder>(options) {

            @Override
            protected void onBindViewHolder(@NonNull final ViewsAdapterHolder holder, int position, @NonNull ViewsAdapter model) {
                String userIds = getRef(position).getKey();
                assert userIds != null;
                ViewsRef.child(userIds).addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {


                        if (dataSnapshot.hasChild(Uid)){
                            Long date = dataSnapshot.child(Uid).getValue(Long.class);

                            assert date != null;
                            int dat = date.intValue();

                            if (dat!=Date){
                                recyclerView.removeAllViews();
                                dataSnapshot.child(Uid).getRef().setValue(null);
                                adapter.startListening();


                            }

                            ViewGroup.LayoutParams layoutParams =holder.itemView.getLayoutParams();
                            layoutParams.width= ViewGroup.LayoutParams.MATCH_PARENT;
                            layoutParams.height= 0;
                            holder.itemView.setLayoutParams(layoutParams);







                        }else {

                            //get the data from child and show in recyclerview

                            holder.button.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {

                        }



                    }

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

                    }
                });

            }

            @NonNull
            @Override
            public ViewsAdapterHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.viewsview,viewGroup,false);
                return new ViewsAdapterHolder(view);
            }



        };

        recyclerView.setAdapter(adapter);

3 Answers3

1

i have used adapter.registerAdapterDataObserver(); method but it doesn't works .

I don't know how you used registerAdapterDataObserver() but here is the correct approch of using it. So to know the number of items that are returned by the query, you need to use getItemCount() method that exist in your adapter class. Because the data from Firebase realtime database is loaded asynchronously, you cannot simply call getItemCount() directly in your adapter class, as it will always be zero. So in order to get the total number of items, you need to register an observer like in the following lines of code:

adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
    public void onItemRangeInserted(int positionStart, int itemCount) {
        int totalNumberOfItems = adapter.getItemCount();
        Log.d(TAG, String.valueOf(totalNumberOfItems));
        if(totalNumberOfItems == 0) {
            recyclerView.setVisibility(View.GONE);
            emptyInfoTextView.setVisibility(View.VISIBLE);
        }
    }
});
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • where should i use it ? in onstart method? @alex –  Aug 21 '19 at 08:54
  • You should use this, right after this line `recyclerView.setAdapter(adapter);`. Does it work? – Alex Mamo Aug 21 '19 at 08:55
  • That's good :) it means that there is no data and the `RecyclerView` was hidden, right? Add some text to TextView, see if it is displayed. Is it? – Alex Mamo Aug 21 '19 at 09:01
  • it's looking same when i did't use registerAdapterDataObserver . Textview is fine . it is working with the method " if (dataSnapshot.getChildrenCount()==0){}" in onstart . –  Aug 21 '19 at 09:03
  • I'm not sure I understand you. When you have **NO** data in the `RecycklerView`, is it hidden? If you have data, is it shown? – Alex Mamo Aug 21 '19 at 09:07
  • let me clear : when there is no child in datasnapshot . recyclerView.setVisibility(View.GONE); and textview.setVisivility(Visibile); works fine . But now i have child in my datasnapshot but it doesn't following the condition that's why it is showing blank but i didn't hide it in this method. look at my code. –  Aug 21 '19 at 09:11
  • So if you say that "when there is no child in datasnapshot . recyclerView.setVisibility(View.GONE); and textview.setVisivility(Visibile); works fine" ---> So it means that your problem is solved, since you are asking how to hide the `RecyclerView` when you have no item, right? – Alex Mamo Aug 21 '19 at 09:16
  • No man . hide it when there is no item following the condition. `if (dataSnapshot.hasChild(Uid)){}` look at this . when every child under datasnapshot has the uid and nothing is left to show in holder then hide the recyclerview and show the textview. –  Aug 21 '19 at 09:17
  • No, this is **NOT** how you hide the `RecyclerView`. You cannot solve the issue according to that condition. You should use an observer like in my answer. Have you even try it? I cannot see in your code that you have... – Alex Mamo Aug 21 '19 at 09:19
  • I have use it last night and when it not works i removed it . but when i used onChanged() in registerAdapterDataObserver it gives the right toast but it only giving the toast when i left the activity. –  Aug 21 '19 at 09:24
  • You use it last night but for sure in a **wrong** way. The way you are trying to solve this, won't solve the problem. Try it again as in my answer, as I already have a similar answer for **[Coud Firestore](https://stackoverflow.com/questions/57441563/firestore-paging-adapter-how-to-know-if-query-returns-0-results/57448654#57448654)** and it works 100%. I have personally tested it. Please confirm me that it also works for you. – Alex Mamo Aug 21 '19 at 09:28
  • i know it works . i also check this . look i have attached the method it work in else method . –  Aug 21 '19 at 09:30
  • when i remove the uid from the child node . it shows the child and toast hace item . but it not working when i insert the uid in the datasnapshot. –  Aug 21 '19 at 09:33
  • But you are adding a new `ValueEventListener` on every bind `ViewHolder`. That's not the way you normally do. – Alex Mamo Aug 21 '19 at 09:33
  • You are trying to solve this issue in way in which you are speding to many resources. And I repet, this is not the way you do it. I understand you tried once and you did not succeed but try it again with code in my answer. You will be amazed that it will work ;) – Alex Mamo Aug 21 '19 at 09:35
  • is there any way to solve this? basically i am inserting uid in the viewholder item click . so if anyone already click the viewholder item it will hide that item . when someone clicked the every holder and there is no holder to be clicked hide the recyclerview and show the imageview. –  Aug 21 '19 at 09:37
  • No, there is not! In the way you do **NO**! This is not the solution. Give it a try to my answer and tell me if it works. – Alex Mamo Aug 21 '19 at 09:38
  • "i have tried it not working " doesn't help me see what's the real problem is. If you want to get help, you also need to help me by providing more details. So please add the code that you tried to see what's wrong. Not the actual one, the one with the observer, since that is the **only** way you can solve this. – Alex Mamo Aug 21 '19 at 09:49
  • did you check my question ? i have edit it and added the method . –  Aug 21 '19 at 09:51
  • And, what's happening when you are adding that code? – Alex Mamo Aug 21 '19 at 09:56
  • it only works when `if (dataSnapshot.hasChild(Uid)){}` Uid doesn't exits or when item is visible . –  Aug 21 '19 at 09:58
  • You should remove all the logic inside the adapter class in order to make it work. Have you tried this way? – Alex Mamo Aug 21 '19 at 10:09
  • I need to make it done with those logic man . Otherwise what i will do with it. –  Aug 21 '19 at 10:12
  • I think you don't understand how asynchronous programming works. I'm afraid you cannot do that the way you do. So I still recommend to be open in terms of practices and use my answer as it will work for sure. Check my answer and comment again and try to fix it. Leave a comment when you did it. – Alex Mamo Aug 21 '19 at 10:17
  • Look at my question again . when i don't have uid in datasnapshot it shows the items in recyclerview . When i insert uid in the datasnapshot and open the app it shows the image item but one datasnapshot don't have the uid. –  Aug 21 '19 at 11:04
  • I'm not going forward with that solution since that is **not** the way you should handle it. You should use an observer. – Alex Mamo Aug 21 '19 at 11:09
  • if i use observer it will not help us because it will not follow the condition in onBindViewHolder . –  Aug 21 '19 at 11:11
  • There is no condition that you should add in your `onBindViewHolder`. **None!** – Alex Mamo Aug 21 '19 at 11:14
  • so tell me how can i do this ? Like when someone click the viewholder item it will save his uid in the datasnapshot . by this i will hide the datasnapshot value for the Uid holder user. –  Aug 21 '19 at 11:16
  • There is no way you can save an `uid` in a `DataSnapshot` object. Beside that, it sounds like your question started off about *"Hide recyclerview when there is no item"*, but is actually just about *how to hide a `DataSnapshot`*. At this point, you should probably think about asking a new question that illustrates what's not working the way you expect. – Alex Mamo Aug 21 '19 at 11:21
  • last time check my question again if you understand it please help else i will find another way, –  Aug 21 '19 at 11:40
  • your answer is not working for me . it only work without condition but you have to think about my problem . –  Aug 21 '19 at 12:08
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/198272/discussion-on-answer-by-alex-mamo-hide-recyclerview-when-there-is-no-item-to-sho). – Samuel Liew Aug 22 '19 at 00:19
  • @AlexMamo https://stackoverflow.com/questions/57607099/google-in-app-purchase-giving-reward-more-than-1-time solve this please –  Aug 22 '19 at 10:48
  • I''ll take a look and if I'll know the answer, I'll write it to you. – Alex Mamo Aug 22 '19 at 10:52
  • @AlexMamo https://stackoverflow.com/questions/57636713/get-the-highest-10-values-from-database-and-show-in-recyclerview would you please look at the problem . :) –  Aug 24 '19 at 09:51
  • Yes I will and if I'll know the answer, I'll write it to you. – Alex Mamo Aug 24 '19 at 09:53
  • @AlexMamo Ok help me as fast as you can:) –  Aug 24 '19 at 10:52
0

So you want to hide when there is no child?

if (dataSnapshot.hasChild(Uid)){
    //your stuff...
}else {
    //set data in viewholder . it works fine
    //Here you hide it.
    emptyInfoTextView.setVisibility(View.VISIBLE);
    recyclerView.setVisibility(View.GONE);
        holder.button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    });
}
Ticherhaz FreePalestine
  • 2,738
  • 4
  • 20
  • 46
0

In some cases changing only visibility, the attribute might still end up as allocated blank space (because of parent view's padding, margins, inner elements, etc). Then changing the height of the parent view helps:

holder.itemView.setVisibility(View.GONE); 
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));

Then be sure that in the condition that it should be visible, also set:

holder.itemView.setVisibility(View.VISIBLE);
holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

You need to do that because the viewHolder is recycled as you scroll, if you change properties like this and never return them to their natural state, other elements will be already hidden in the event they reuse the same view.