Android 使用Firebase查询实现Firebase native express广告

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

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("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
    }
}