Android 使用Firebase查询实现Firebase native express广告
a) 我想在firebase查询生成的动态列表中显示admob native express广告 b) 我使用PostListFragment.java来显示posts,posts适配器是RVAdapter.java c) 我以编程方式加载和显示广告,它可以与静态列表配合使用 d) 这是动态列表:Android 使用Firebase查询实现Firebase native express广告,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,a) 我想在firebase查询生成的动态列表中显示admob native express广告 b) 我使用PostListFragment.java来显示posts,posts适配器是RVAdapter.java c) 我以编程方式加载和显示广告,它可以与静态列表配合使用 d) 这是动态列表: mPosts = getPosts(postsQuery); f) 这是静态列表: mPosts = new ArrayList<>(); mPosts.add(new Post
mPosts = getPosts(postsQuery);
f) 这是静态列表:
mPosts = new ArrayList<>();
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
mpost=newarraylist();
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
添加(新帖子(“key”、“uid”、“author”、“title”、“body”);
错误是:
-当我使用静态列表时,它工作正常,没有崩溃,我每8个位置就获得一个NativeExpressAd,但是当我用动态列表(来自firebase查询)替换这个静态列表时,它会因为强制转换问题崩溃,即使屏幕上显示了帖子,列表大小也是零
以下是我的适配器代码:
package com.google.firebase.quickstart.database;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.ads.NativeExpressAdView;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.Transaction;
import com.google.firebase.quickstart.database.fragment.PostListFragment;
import com.google.firebase.quickstart.database.models.Post;
import com.google.firebase.quickstart.database.viewholder.NativeExpressAdViewHolder;
import com.google.firebase.quickstart.database.viewholder.PostViewHolder;
import java.util.List;
public class RVAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int POST = 0;
private static final int AD = 1;
Context context;
List<Object> mPosts;
DatabaseReference mDatabase;
public RVAdapter(Context context, List<Object> mPosts , DatabaseReference mDatabase) {
this.context = context;
this.mPosts = mPosts;
this.mDatabase = mDatabase;
}
@Override
public int getItemCount() {
return mPosts.size();
}
@Override
public int getItemViewType(int position) {
return (position % PostListFragment.ITEMS_PER_AD == 0) ? AD : POST;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType) {
case POST:
View menuItemLayoutView = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.item_post, viewGroup, false);
return new PostViewHolder(menuItemLayoutView);
case AD:
// fall through
default:
View nativeExpressLayoutView = LayoutInflater.from(
viewGroup.getContext()).inflate(R.layout.item_ad,
viewGroup, false);
return new NativeExpressAdViewHolder(nativeExpressLayoutView);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case POST:
configurePost(holder , position);
break;
case AD:
// fall through
default:
configureAd(holder , position);
}
}
public void configureAd(RecyclerView.ViewHolder holder , int position){
NativeExpressAdViewHolder nativeExpressHolder = (NativeExpressAdViewHolder) holder;
NativeExpressAdView adView = (NativeExpressAdView) mPosts.get(position);
ViewGroup adCardView = (ViewGroup) nativeExpressHolder.itemView;
if (adCardView.getChildCount() > 0) {
adCardView.removeAllViews();
}
// Add the Native Express ad to the native express ad view.
adCardView.addView(adView);
}
public void configurePost (RecyclerView.ViewHolder holder , int position){
final PostViewHolder viewHolder = (PostViewHolder) holder;
final Post model = (Post) mPosts.get(position);
final String postKey = model.key;
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Launch PostDetailActivity
Intent intent = new Intent(context, PostDetailActivity.class);
intent.putExtra(PostDetailActivity.EXTRA_POST_KEY, postKey);
context.startActivity(intent);
}
});
// Determine if the current user has liked this post and set UI accordingly
if (model.stars.containsKey(getUid())) {
viewHolder.starView.setImageResource(R.drawable.ic_toggle_star_24);
} else {
viewHolder.starView.setImageResource(R.drawable.ic_toggle_star_outline_24);
}
// Bind Post to ViewHolder, setting OnClickListener for the star button
viewHolder.bindToPost(model, new View.OnClickListener() {
@Override
public void onClick(View starView) {
// Need to write to both places the post is stored
DatabaseReference globalPostRef = mDatabase.child("posts").child(postKey);
DatabaseReference userPostRef = mDatabase.child("user-posts").child(model.uid).child(postKey);
// Run two transactions
onStarClicked(globalPostRef);
onStarClicked(userPostRef);
}
});
}
private void onStarClicked(DatabaseReference postRef) {
postRef.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Post p = mutableData.getValue(Post.class);
if (p == null) {
return Transaction.success(mutableData);
}
if (p.stars.containsKey(getUid())) {
// Unstar the post and remove self from stars
p.starCount = p.starCount - 1;
p.stars.remove(getUid());
} else {
// Star the post and add self to stars
p.starCount = p.starCount + 1;
p.stars.put(getUid(), true);
}
// Set value and report transaction success
mutableData.setValue(p);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
// Transaction completed
}
});
}
public String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
package com.google.firebase.quickstart.database;
导入android.content.Context;
导入android.content.Intent;
导入android.support.v7.widget.RecyclerView;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入com.google.android.gms.ads.NativeExpressAdView;
导入com.google.firebase.auth.FirebaseAuth;
导入com.google.firebase.database.DataSnapshot;
导入com.google.firebase.database.DatabaseError;
导入com.google.firebase.database.DatabaseReference;
导入com.google.firebase.database.MutableData;
导入com.google.firebase.database.Transaction;
导入com.google.firebase.quickstart.database.fragment.PostListFragment;
导入com.google.firebase.quickstart.database.models.Post;
导入com.google.firebase.quickstart.database.viewholder.NativeExpressAdViewHolder;
导入com.google.firebase.quickstart.database.viewholder.PostViewHolder;
导入java.util.List;
公共类RVAdapter扩展了RecyclerView.Adapter{
私有静态最终int POST=0;
专用静态最终int AD=1;
语境;
列出mpost;
数据库参考数据库;
公共RVAdapter(上下文上下文、列表MPost、数据库引用mDatabase){
this.context=上下文;
this.mPosts=mPosts;
this.mDatabase=mDatabase;
}
@凌驾
public int getItemCount(){
返回mpost.size();
}
@凌驾
public int getItemViewType(int位置){
返回(位置%PostListFragment.ITEMS\u PER\u AD==0)?AD:POST;
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup ViewGroup,int viewType){
开关(视图类型){
个案职位:
View menuItemLayoutView=LayoutFlater.from(viewGroup.getContext())。充气(
R.layout.item_post,视图组,false);
返回新的PostViewHolder(menuItemLayoutView);
案例广告:
//失败
违约:
视图nativeExpressLayoutView=LayoutFlater.from(
viewGroup.getContext())。充气(R.layout.item_ad,
视图组,false);
返回新的NativeExpressAdViewHolder(nativeExpressLayoutView);
}
}
@凌驾
BindViewHolder上的公共无效(RecyclerView.ViewHolder,int位置){
int viewType=getItemViewType(位置);
开关(视图类型){
个案职位:
配置柱(支架、位置);
打破
案例广告:
//失败
违约:
配置AD(支架、位置);
}
}
公共无效配置AD(RecyclerView.ViewHolder,内部位置){
NativeExpressAdViewHolder nativeExpressHolder=(NativeExpressAdViewHolder)holder;
NativeExpressAdView adView=(NativeExpressAdView)mPosts.get(位置);
ViewGroup adCardView=(ViewGroup)nativeExpressHolder.itemView;
如果(adCardView.getChildCount()>0){
adCardView.RemoveAllView();
}
//将本机Express广告添加到本机Express广告视图。
adcardwiew.addView(adView);
}
public void configurePost(RecyclerView.ViewHolder,int位置){
最终PostViewHolder viewHolder=(PostViewHolder)holder;
最终Post模型=(Post)mPosts.get(position);
最终字符串postKey=model.key;
viewHolder.itemView.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
//启动PostDetailActivity
意向意向=新意向(上下文,PostDetailActivity.class);
intent.putExtra(PostDetailActivity.EXTRA\u POST\u KEY,postKey);
背景。开始触觉(意图);
}
});
//确定当前用户是否喜欢此帖子,并相应地设置UI
if(model.stars.containsKey(getUid())){
viewHolder.rightView.setImageResource(R.drawable.ic_toggle_star_24);
}否则{
viewHolder.饥饿视图.setImageResource(R.drawable.ic\u开关\u星形\u轮廓\u 24);
}
//将Post绑定到ViewHolder,为星形按钮设置OnClickListener
viewHolder.bindToPost(model,newview.OnClickListener(){
@凌驾
公共void onClick(视图视图){
//需要写到帖子存储的两个位置
数据库参考globalPostRef=
package com.google.firebase.quickstart.database.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.NativeExpressAdView;
import com.google.firebase.auth.FirebaseAuth;
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.Query;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.quickstart.database.R;
import com.google.firebase.quickstart.database.RVAdapter;
import com.google.firebase.quickstart.database.models.Post;
import java.util.ArrayList;
import java.util.List;
public abstract class PostListFragment extends Fragment {
private DatabaseReference mDatabase;
private RVAdapter mAdapter;
private RecyclerView mRecycler;
private LinearLayoutManager mManager;
public static final int ITEMS_PER_AD = 8;
private static final int NATIVE_EXPRESS_AD_HEIGHT = 150;
private static final int NATIVE_EXPRESS_AD_WIDTH = 320;
private static final String AD_UNIT_ID = "ca-app-pub-7651927944958903/3704936407";
private List<Object> mPosts;
public PostListFragment() {}
@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_all_posts, container, false);
mDatabase = FirebaseDatabase.getInstance().getReference();
mRecycler = (RecyclerView) rootView.findViewById(R.id.messages_list);
mRecycler.setHasFixedSize(true);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Set up Layout Manager, reverse layout
mManager = new LinearLayoutManager(getActivity());
mManager.setReverseLayout(true);
mManager.setStackFromEnd(true);
mRecycler.setLayoutManager(mManager);
Query postsQuery = getQuery(mDatabase);
mPosts = getPosts(postsQuery);
// mPosts = new ArrayList<>();
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
// mPosts.add(new Post("key" , "uid" , "author" , "title" , "body"));
addNativeExpressAds();
setUpAndLoadNativeExpressAds();
mAdapter = new RVAdapter(getActivity() ,mPosts , mDatabase);
//this toast always gets 0 posts or 1 ad
Toast.makeText(getActivity(), mPosts.size()+"", Toast.LENGTH_SHORT).show();
mRecycler.setAdapter(mAdapter);
}
public String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
public abstract Query getQuery(DatabaseReference databaseReference);
public List<Object> getPosts(Query query){
final List<Object> items = new ArrayList<>();
query.getRef().addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
Post post = postSnapshot.getValue(Post.class);
items.add(post);
}
}
@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Toast.makeText(getActivity(), "Failed to load posts!", Toast.LENGTH_SHORT).show();
}
});
return items;
}
private void addNativeExpressAds() {
// Loop through the items array and place a new Native Express ad in every ith position in
// the items List.
for (int i = 0; i <= mPosts.size(); i += ITEMS_PER_AD) {
final NativeExpressAdView adView = new NativeExpressAdView(getActivity());
mPosts.add(i, adView);
}
}
private void setUpAndLoadNativeExpressAds() {
// Use a Runnable to ensure that the RecyclerView has been laid out before setting the
// ad size for the Native Express ad. This allows us to set the Native Express ad's
// width to match the full width of the RecyclerView.
mRecycler.post(new Runnable() {
@Override
public void run() {
// final float density = getActivity().getResources().getDisplayMetrics().density;
// Set the ad size and ad unit ID for each Native Express ad in the items list.
for (int i = 0; i <= mPosts.size(); i += ITEMS_PER_AD) {
final NativeExpressAdView adView = (NativeExpressAdView) mPosts.get(i);
AdSize adSize = new AdSize(NATIVE_EXPRESS_AD_WIDTH, NATIVE_EXPRESS_AD_HEIGHT);
adView.setAdSize(adSize);
adView.setAdUnitId(AD_UNIT_ID);
}
// Load the first Native Express ad in the items list.
loadNativeExpressAd(ITEMS_PER_AD);
}
});
}
private void loadNativeExpressAd(final int index) {
if (index >= mPosts.size()) {
return;
}
Object item = mPosts.get(index);
if (!(item instanceof NativeExpressAdView)) {
throw new ClassCastException("Expected item at index " + index + " to be a Native"
+ " Express ad.");
}
final NativeExpressAdView adView = (NativeExpressAdView) item;
// Set an AdListener on the NativeExpressAdView to wait for the previous Native Express ad
// to finish loading before loading the next ad in the items list.
adView.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
// The previous Native Express ad loaded successfully, call this method again to
// load the next ad in the items list.
loadNativeExpressAd(index + ITEMS_PER_AD);
}
@Override
public void onAdFailedToLoad(int errorCode) {
// The previous Native Express ad failed to load. Call this method again to load
// the next ad in the items list.
Log.e("MainActivity", "The previous Native Express ad failed to load. Attempting to"
+ " load the next Native Express ad in the items list.");
loadNativeExpressAd(index + ITEMS_PER_AD);
}
});
// Load the Native Express ad.
adView.loadAd(new AdRequest.Builder().build());
}
}
Ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError?) {
Log.v(TAG, "empty")
}
override fun onDataChange(p0: DataSnapshot) {
val items = p0.childrenCount.toInt()
var i = 0
for (ds in p0.children) {
if (position % ITEMS_PER_AD == 0) {
val adView = NativeExpressAdView(activity)
val scale = activity.resources.displayMetrics.density
val adSize = AdSize((activity.resources.displayMetrics.widthPixels / scale).toInt(), NATIVE_EXPRESS_AD_HEIGHT)
adView.adSize = adSize
adView.adUnitId = "my unit id..."
adView.loadAd(AdRequest.Builder().build())
list.add(position, adView)
position += 1
}
val model = ds.getValue(someModel::class.java)
list.add(position, model!!)
i += 1
position += 1
if (i == items) {
val adapter = RecyclerViewAdapter(activity, list)
mRecycler.adapter = adapter
}
}
}
})
class RecyclerViewAdapter(private val mContext: Context, private val mRecyclerViewItems: List<Any>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
inner class MenuItemViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
val menuItemName: TextView
init {
menuItemName = view.findViewById(R.id.menu_item_name) as TextView
}
}
inner class NativeExpressAdViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view)
override fun getItemCount(): Int {
return mRecyclerViewItems.size
}
override fun getItemViewType(position: Int): Int {
return if (position % ITEMS_PER_AD == 0)
NATIVE_EXPRESS_AD_VIEW_TYPE
else
MENU_ITEM_VIEW_TYPE
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
MENU_ITEM_VIEW_TYPE -> {
val menuItemLayoutView = LayoutInflater.from(viewGroup.context).inflate(
R.layout.menu_item_container, viewGroup, false)
return MenuItemViewHolder(menuItemLayoutView)
}
else -> {
val nativeExpressLayoutView = LayoutInflater.from(
viewGroup.context).inflate(R.layout.native_express_ad_container,
viewGroup, false)
return NativeExpressAdViewHolder(nativeExpressLayoutView)
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val viewType = getItemViewType(position)
when (viewType) {
MENU_ITEM_VIEW_TYPE -> {
val menuItemHolder = holder as MenuItemViewHolder
val menuItem = mRecyclerViewItems[position] as modelWOD
menuItemHolder.menuItemName.text = menuItem.name
}
else -> {
val nativeExpressHolder = holder as NativeExpressAdViewHolder
val adView = mRecyclerViewItems[position] as NativeExpressAdView
val adCardView = nativeExpressHolder.itemView as ViewGroup
if (adCardView.childCount > 0) adCardView.removeAllViews()
if (adView.parent != null) (adView.parent as ViewGroup).removeView(adView)
adCardView.addView(adView)
}
}
}
companion object {
private val MENU_ITEM_VIEW_TYPE = 0
private val NATIVE_EXPRESS_AD_VIEW_TYPE = 1
private val ITEMS_PER_AD = 8
}
}