使用Firebase查询实施Firebase原生快递广告

a)我想显示从firebase查询生成的动态列表内的admob原生快速广告

b)我使用PostListFragment.java来显示post,post适配器是RVAdapter.java

三)我加载和以编程方式显示广告,并与静态列表工作正常

d)这是动态列表:

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")); 

错误是: – 当我使用静态列表,它工作正常,没有崩溃,我得到NativeExpressAd每8个位置,但是当我用一个动态列表(来自Firebase查询)替换这个静态列表,因为投射问题崩溃,即使屏幕上显示post,列表大小也是零

这是我的适配器代码:

 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 { private static final int POST = 0; private static final int AD = 1; Context context; List mPosts; DatabaseReference mDatabase; public RVAdapter(Context context, List 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.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 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 getPosts(Query query){ final List 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()) { 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()); } } 

这里是堆栈跟踪:

11-21 14:51:47.182 21965-21965 / com.google.firebase.quickstart.database W / dalvikvm:threadid = 1:线程以未捕获的exception退出(group = 0x417f89a8)11-21 14:51:47.182 21965-21965 /com.google.firebase.quickstart.database W / dalvikvm:threadid = 1:发生未捕获的exception11-21 14:51:47.182 21965-21965 / com.google.firebase.quickstart.database W / System.err:java。 lang.ClassCastException:com.google.firebase.quickstart.database.models.Post无法转换为com.google.android.gms.ads.NativeExpressAdView 11-21 14:51:47.186 21965-21965 / com.google.firebase。 quickstart.database W / System.err:com.google.firebase.quickstart.database.RVAdapter.configureAd(RVAdapter.java:83)11-21 14:51:47.186 21965-21965 / com.google.firebase.quickstart。数据库W / System.err:com.google.firebase.quickstart.database.RVAdapter.onBindViewHolder(RVAdapter.java:77)11-21 14:51:47.187 21965-21965 / com.google.firebase.quickstart.database W /System.err:在android.support.v7.widget.RecyclerView $ Adapter.onBindViewHold 呃(RecyclerView.java:5825)11-21 14:51:47.187 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.support.v7.widget.RecyclerView $ Adapter.bindViewHolder RecyclerView.java:5858)11-21 14:51:47.187 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView。 java:5094)11-21 14:51:47.187 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java: 4970)11-21 14:51:47.187 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.support.v7.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:2029) 11-21 14:51:47.188 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)11-21 14 :51:47.188 21965-21965 / com.google.firebase.quickstart.database W / System.er r:在android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)11-21 14:51:47.188 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android .support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1193)11-21 14:51:47.188 21965-21965 / com.google.firebase.quickstart.database W / System.err:at android.support.v7 .widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1043)11-21 14:51:47.189 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.support.v7.widget.RecyclerView $ ViewFlinger.run(RecyclerView.java:4413)11-21 14:51:47.189 21965-21965 / com.google.firebase.quickstart.database W / System.err:at android.view.Choreographer $ CallbackRecord.run(Choreographer .java:776)11-21 14:51:47.189 21965-21965 / com.google.firebase.quickstart.database W / System.err:at android.view.Choreographer.doCallbacks(Choreographer.java:579)11-21 14:51:47.189 21965-21965 / com.google.firebase.quickstart.database W / Syste m.err:在android.view.Choreographer.doFrame(Choreographer.java:547)11-21 14:51:47.189 21965-21965 / com.google.firebase.quickstart.database W / System.err:在android.view .Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:762)11-21 14:51:47.189 21965-21965 / com.google.firebase.quickstart.database W / System.err:at android.os.Handler.handleCallback(Handler .java:800)11-21 14:51:47.190 21965-21965 / com.google.firebase.quickstart.database W / System.err:at android.os.Handler.dispatchMessage(Handler.java:100)11-21 14:51:47.190 21965-21965 / com.google.firebase.quickstart.database W / System.err:at android.os.Looper.loop(Looper.java:194)11-21 14:51:47.190 21965-21965 /com.google.firebase.quickstart.database W / System.err:at android.app.ActivityThread.main(ActivityThread.java:5391)11-21 14:51:47.191 21965-21965 / com.google.firebase.quickstart .database W / System.err:at java.lang.reflect.Method.invokeNative(Native Method)11-21 14:51:47.191 21965-21965 / com.google.firebase.quickstart.data base W / System.err:at java.lang.reflect.Method.invoke(Method.java:525)11-21 14:51:47.191 21965-21965 / com.google.firebase.quickstart.database W / System.err :at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:833)11-21 14:51:47.191 21965-21965 / com.google.firebase.quickstart.database W / System.err:at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)11-21 14:51:47.192 21965-21965 / com.google.firebase.quickstart.database W / System.err:at dalvik.system。 NativeStart.main(Native Method)11-21 14:51:47.192 21965-21965 / com.google.firebase.quickstart.database W / dalvikvm:threadid = 1:调用UncaughtExceptionHandler 11-21 14:51:47.196 21965-21965 / com.google.firebase.quickstart.database E / AndroidRuntime:致命exception:main java.lang.ClassCastException:com.google.firebase.quickstart.database.models.Post无法转换为com.google.android.gms.ads。 NativeExpressAdView,位于com.google.firebase.quickstart.database.RVAdapter.configureAd(RVAdapter.java:83) oogle.firebase.quickstart.database.RVAdapter.onBindViewHolder(RVAdapter.java:77)at android.support.v7.widget.RecyclerView $ Adapter.onBindViewHolder(RecyclerView.java:5825)at android.support.v7.widget.RecyclerView $在android.support.v7.widget.RecyclerView的Adapter.bindViewHolder(RecyclerView.java:5858)$ Recycler.getViewForPosition(RecyclerView.java:5094)at android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(RecyclerView.java: 4970)at android.support.v7.widget.LinearLayoutManager $ LayoutState.next(LinearLayoutManager.java:2029)at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)at android.support.v7.widget .LinearLayoutManager.fill(LinearLayoutManager.java:1377)at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1193)at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1043)at android.support.v7.widget.RecyclerView $ ViewFlinger.run(RecyclerView.java:4413)at andr oid.view.Choreographer $ CallbackRecord.run(Choreographer.java:776)at android.view.Choreographer.doCallbacks(Choreographer.java:579)at android.view.Choreographer.doFrame(Choreographer.java:547)at android.view编辑$ FrameDisplayEventReceiver.run(Choreographer.java:762)在android.os.Handler.handleCallback(Handler.java:800)在android.os.Handler.dispatchMessage(Handler.java:100)在android.os.Looper。循环(Looper.java:194)在android.app.ActivityThread.main(ActivityThread.java:5391)在java.lang.reflect.Method.invokeNative(本地方法)在java.lang.reflect.Method.invoke(方法。 java:525)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:833)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)at dalvik.system.NativeStart .main(Native Method)

我走了另一条路,并在“onDataChange”(解决方案在Kotlin)中添加广告:

 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) : RecyclerView.Adapter() { 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 } }