skip to Main Content

I have the following Firebase Realtime Database, which has parts inside the root:

1: blog_posts
2: Ads

  • root

  • blog_posts

    • post_id_1
      • title: "Blog Post 1"
      • content: "Content of Blog Post 1"
      • contentType: "text"
      • contentUrl: "https://example.com/post1"
    • post_id_2
      • title: "Blog Post 2"
      • content: "Content of Blog Post 2"
      • contentType: "text"
      • contentUrl: "https://example.com/post2"
  • post_id_3

    • title: "Blog Post 3 "
    • content: "Content of Blog Post 3"
    • contentType: "text"
    • contentUrl: "https://example.com/post3"
    • post_id_4
      • title: "Blog Post 4"
      • content: "Content of Blog Post 4"
      • contentType: "text"
      • contentUrl: "https://example.com/post4"

  • Ads

    • ad_id_1
      • title: "Ad 1"
      • content: "Content of Ad 1"
      • contentType: "image"
      • contentUrl: "https://example.com/ad1"
    • ad_id_2
      • title: "Ad 2"
      • content: "Content of Ad 2"
      • contentType: "image"
      • contentUrl: "https://example.com/ad2"

What I want to achieve is to display Ads after every 2 blog posts.

But when I run my codes this is what comes as results( Ads appear after all posts).

Here is my code:

    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import omega.jschii.healourlandafrica.R;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    import com.google.firebase.database.DataSnapshot;
    import com.google.firebase.database.DatabaseError;
    import com.google.firebase.database.DatabaseReference;
    import com.google.firebase.database.FirebaseDatabase;
    import com.google.firebase.database.ValueEventListener;
    import java.util.ArrayList;
    import java.util.List;
    import androidx.annotation.NonNull;

            public class MainActivityViewPost extends AppCompatActivity {
                private RecyclerView recyclerView;
                private Adapter adapter;
                private List<Object> items;

                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main_view_post);

                    recyclerView = findViewById(R.id.recyclerView);
                    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
                    recyclerView.setLayoutManager(layoutManager);

                    items = new ArrayList<>();

                    DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
                    databaseReference.child("blog_posts").addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                                BlogPost blogPost = snapshot.getValue(BlogPost.class);
                                items.add(blogPost);
                            }
                            adapter.notifyDataSetChanged();
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {
                            // Handle database error
                        }
                    });

                    databaseReference.child("Ads").addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                                Ads ad = snapshot.getValue(Ads.class);
                                items.add(ad);
                            }
                            adapter.notifyDataSetChanged();
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError databaseError) {
                            // Handle database error
                        }
                    });
                    adapter = new Adapter(this, items);
                    recyclerView.setAdapter(adapter);
                }
            }

}

Adapter class

   import android.content.Context;
   import android.view.LayoutInflater;
   import android.view.View;
   import android.view.ViewGroup;
   import android.widget.TextView;
   import androidx.annotation.NonNull;
   import androidx.recyclerview.widget.RecyclerView;
   import java.util.List;
public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_BLOG_POST = 0;
private static final int VIEW_TYPE_AD = 1;

private List<Object> items;
private Context context;

// Constructor
public Adapter(Context context, List<Object> items) {
    this.context = context;
    this.items = items;
}

@Override
public int getItemViewType(int position) {
    Object item = items.get(position);
    return item instanceof BlogPost ? VIEW_TYPE_BLOG_POST : VIEW_TYPE_AD;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    if (viewType == VIEW_TYPE_BLOG_POST) {
        View itemView = inflater.inflate(R.layout.item_blog_post, parent, false);
        return new BlogPostViewHolder(itemView);
    } else {
        View itemView = inflater.inflate(R.layout.item_ad, parent, false);
        return new AdViewHolder(itemView);
    }
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof BlogPostViewHolder) {
        BlogPostViewHolder blogPostViewHolder = (BlogPostViewHolder) holder;
        BlogPost blogPost = (BlogPost) items.get(position);
        blogPostViewHolder.bind(blogPost);
    } else if (holder instanceof AdViewHolder) {
        AdViewHolder adViewHolder = (AdViewHolder) holder;
        Ads ad = (Ads) items.get(position);
        adViewHolder.bind(ad);
    }
}

@Override
public int getItemCount() {
    return items.size();
}

// ViewHolder classes for blog posts and ads
private class BlogPostViewHolder extends RecyclerView.ViewHolder {
    private TextView titleTextView;


    BlogPostViewHolder(@NonNull View itemView) {
        super(itemView);
        titleTextView = itemView.findViewById(R.id.titleTextView);
    }

    void bind(BlogPost blogPost) {
        titleTextView.setText(blogPost.getTitle());
    }
}

private class AdViewHolder extends RecyclerView.ViewHolder {
    private TextView titleTextView;


    AdViewHolder(@NonNull View itemView) {
        super(itemView);
        titleTextView = itemView.findViewById(R.id.titleTextView);

    }

    void bind(Ads ad) {
        titleTextView.setText(ad.getTitle());

    }
}

}

here is the output

enter image description here

How can I make Ad 1 appear after post2, Ad2 appear after post4 , and Ad3 appear after post6

2

Answers


  1. You can get that type of result by displaying ads after specific posts in a RecyclerView, you can modify the RecyclerView adapter to include logic for displaying ads at those positions.

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import com.squareup.picasso.Picasso;
    import java.util.ArrayList;
    
    public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        private static final int VIEW_TYPE_BLOG_POST = 0;        
        private static final int VIEW_TYPE_AD = 1;
    
        private Context context;
        private ArrayList<Post> posts;
    
        public PostAdapter(Context context, ArrayList<Post> posts) {
            this.context = context;
            this.posts = posts;
        }
    
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            if (viewType ==  VIEW_TYPE_BLOG_POST) {
                View view = inflater.inflate(R.layout.item_post, parent, false);
                return new PostViewHolder(view);
            } else {
                View view = inflater.inflate(R.layout.item_ad, parent, false);
                return new AdViewHolder(view);
            }
        }
    
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof PostViewHolder) {
                bindPostViewHolder((PostViewHolder) holder, position);
            } else if (holder instanceof AdViewHolder) {
                // Bind ad view holder
            }
        }
    
        private void bindPostViewHolder(PostViewHolder holder, int position) {
            Post post = posts.get(position);
            holder.txtTitle.setText(post.getTitle());
            Picasso.get().load(post.getImageUrl()).into(holder.imgPost);
        }
    
        @Override
        public int getItemCount() {
            return posts.size() + getAdCount(posts.size());
        }
    
        @Override
        public int getItemViewType(int position) {
            if (isAdPosition(position)) {
                return VIEW_TYPE_AD;
            } else {
                return  VIEW_TYPE_BLOG_POST;
            }
        }
    
        private boolean isAdPosition(int position) {
            return position == 2 || position == 5 || position == 8; // Ads after post 2, 5, and 8
        }
    
        private int getAdCount(int postCount) {
            return postCount / 3; // Assuming an ad after every 3 posts
        }
    
        private static class PostViewHolder extends RecyclerView.ViewHolder {
            TextView txtTitle;
            ImageView imgPost;
    
            PostViewHolder(View itemView) {
                super(itemView);
                txtTitle = itemView.findViewById(R.id.txt_title);
                imgPost = itemView.findViewById(R.id.img_post);
            }
        }
    
        private static class AdViewHolder extends RecyclerView.ViewHolder {
            // Add ad view components here
            AdViewHolder(View itemView) {
                super(itemView);
                // Initialize ad view components
            }
        }
    }
    

    Firebase json structure :

    {
    "root": {
        "blog_posts": {
        "post_id_1": {
            "title": "Blog Post 1",
            "content": "Content of Blog Post 1",
            "contentType": "text",
            "contentUrl": "https://example.com/post1",
            "type": "blog"
        },
        "post_id_2": {
            "title": "Blog Post 2",
            "content": "Content of Blog Post 2",
            "contentType": "text",
            "contentUrl": "https://example.com/post2",
            "type": "blog"
        },
        "post_id_3": {
            "title": "Blog Post 3",
            "content": "Content of Blog Post 3",
            "contentType": "text",
            "contentUrl": "https://example.com/post3",
            "type": "blog"
        },
        "post_id_4": {
            "title": "Blog Post 4",
            "content": "Content of Blog Post 4",
            "contentType": "text",
            "contentUrl": "https://example.com/post4",
            "type": "blog"
        }
        },
        "Ads": {
        "ad_id_1": {
            "title": "Ad 1",
            "content": "Content of Ad 1",
            "contentType": "image",
            "contentUrl": "https://example.com/ad1",
            "type": "ad"
        },
        "ad_id_2": {
            "title": "Ad 2",
            "content": "Content of Ad 2",
            "contentType": "image",
            "contentUrl": "https://example.com/ad2",
            "type": "ad"
        }
        }
    }
    }
    
    Login or Signup to reply.
  2. You’re getting this result:

    enter image description here

    Because you’re performing two separate Firebase Realtime Database requests, one after the other. If you need to have displayed 2 posts and an ad, 2 posts, and an ad, and so on, then you have to perform the request for getting the ads only when you already have the blog posts available. This means that when the operation for getting the ads is successful, then you’ll have two lists full of data, one list with blog posts and one list with ads. Now you can create a new list that combines the two lists in the way mentioned above.

    You can achieve this by nesting the second request inside the callback of the first request, or you can use get() instead of addListenerForSingleValueEvent() and right after that use Tasks.whenAllSuccess(), as you can see below:

    DatabaseReference db = FirebaseDatabase.getInstance().getReference();
    DatabaseReference blogPostsRequest = db.child("blog_posts");
    DatabaseReference adsRequest = db.child("Ads");
    
    Task<DataSnapshot> blogPostsTask = blogPostsRequest.get();
    Task<DataSnapshot> adsTask = adsRequest.get();
    
    Task<List<Object>> combinedTask = Tasks.whenAllSuccess(blogPostsTask, adsTask).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
        @Override
        public void onSuccess(List<Object> list) {
            //Do what you need to do with your list
        }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search