0

I have Admob Banner adds in my Recycler listview, but the ad is overlaying the list item. I have been through the stack looking for a way to fix this, the closest I have come is Embedding ads within Recyclerview

I have tried several of the answers provide in this article without any success. The banner add always overlays the list item. As you can see from the image below there are five games and Game 4 should be showing below the Banner Ad.

enter image description here

Can someone please help me fix this issue. I have placed the code for my Adapter below.

 private List<Game> gameList;
    private Activity gamesActivity;
    private LayoutInflater inflater;

    private static final int CONTENT_TYPE = 1;
    private static final int AD_TYPE = 0;
    private static final int AD_DELTA = 3;

    public void notifyDatasetChanged(List<Game> newGamelist) {
        gameList.clear();
        gameList.addAll(newGamelist);
        super.notifyDataSetChanged();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView gameLeagueId;
        private TextView gameBowlerId;
        private TextView gameSeriesId;
        private TextView gameName;
        private TextView score;
        private TextView strikes;
        private TextView spares;
        private TextView splits;
        private TextView splitConversions;
        private TextView openFrames;
        private TextView timestamp;
        public TextView buttonViewOptions;

        public MyViewHolder(View view) {
            super(view);
            if (!(itemView instanceof AdView)) {
                gameLeagueId = view.findViewById( R.id.tvLeagueId );
                gameBowlerId = view.findViewById( R.id.tvBowlerId );
                gameSeriesId = view.findViewById( R.id.tvSeriesId );
                gameName = view.findViewById(R.id.tvGameName);
                score = view.findViewById( R.id.tvScore );
                strikes = view.findViewById( R.id.tvStrikes );
                spares = view.findViewById( R.id.tvSpares );
                splits = view.findViewById( R.id.tvSplits );
                splitConversions = view.findViewById( R.id.tvSplitConversions );
                openFrames = view.findViewById( R.id.tvOpenFrames );
                timestamp = view.findViewById( R.id.timestamp );
                buttonViewOptions = view.findViewById(R.id.buttonViewOptions);
            }
        }
    }


    GamesAdapter(Context context, List<Game> gameList) {
        this.context = context;
        this.gameList = gameList;
        gamesActivity = (Activity) context;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public GamesAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        AdView adview;
        GamesAdapter.MyViewHolder holder;

        if (viewType == AD_TYPE) {
            adview = new AdView(gamesActivity);
            adview.setAdSize( AdSize.BANNER);

            // this is the good adview
            adview.setAdUnitId(gamesActivity.getString(R.string.admob_ad_id));

            float density = gamesActivity.getResources().getDisplayMetrics().density;
            int height = Math.round(AdSize.BANNER.getHeight() * density);
            AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, height);
            adview.setLayoutParams(params);

            // dont use below if testing on a device
            // follow https://developers.google.com/admob/android/quick-start?hl=en to setup testing device
            AdRequest request = new AdRequest.Builder().build();
            if (request != null && adview != null) {
                adview.loadAd(request);
            }
            holder = new MyViewHolder(adview);

        }else{
            View view = inflater.inflate(R.layout.listview_games, parent, false);
            holder = new MyViewHolder(view);
        }
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        if (getItemViewType(position)==CONTENT_TYPE) {
            Game game = gameList.get( position );
            int id = game.getId();
            String leagueId = game.getLeagueId();
            String bowlerId = game.getBowlerId();
            String seriesId = game.getSeriesId();
            String gameNumber = String.valueOf(position+1);
            holder.gameLeagueId.setText( game.getLeagueId() );
            holder.gameBowlerId.setText( game.getBowlerId() );
            holder.gameSeriesId.setText( game.getSeriesId() );
            holder.gameName.setText(String.format("Game %s",gameNumber));
            holder.score.setText( game.getScore() );
            if (game.getStrikes() == "1") {
                holder.strikes.setText( String.format( "%s Strike ", game.getStrikes()));
            } else holder.strikes.setText( String.format( "%s Strikes", game.getStrikes()));
            if (game.getSpares() == "1") {
                holder.spares.setText( String.format( "%s Spare ", game.getSpares()));
            } else holder.spares.setText( String.format( "%s Spares", game.getSpares()));
            if (game.getSplits() == "1") {
                holder.splits.setText( String.format( "%s Split ", game.getSplits()));
            } else holder.splits.setText( String.format( "%s Splits", game.getSplits()));
            if (game.getSplitConversions() == "1") {
                holder.splitConversions.setText( String.format( "%s Split Conversion", game.getSplitConversions()));
            } else holder.splitConversions.setText( String.format( "%s Split Conversions", game.getSplitConversions()));
            if (game.getOpenFrames() == "1") {
                holder.openFrames.setText( String.format( "%s Open Frame", game.getOpenFrames()));
            } else holder.openFrames.setText( String.format( "%s Open Frames", game.getOpenFrames()));
            // Formatting and displaying timestamp
            holder.timestamp.setText( formatDate( game.getTimestamp() ) );
            holder.buttonViewOptions.setOnClickListener( new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    //creating a popup menu
                    PopupMenu popup = new PopupMenu( context, holder.buttonViewOptions );
                    //inflating menu from xml resource
                    popup.inflate( R.menu.series_options_menu );
                    //adding click listener
                    popup.setOnMenuItemClickListener( new PopupMenu.OnMenuItemClickListener() {
                        @Override
                        public boolean onMenuItemClick(MenuItem item) {
                            switch (item.getItemId()) {
                                case R.id.profile:
                                    ((GamesActivity) context).openDialog( true, gameList.get( position ), leagueId, bowlerId, seriesId, position );
                                    break;
                                case R.id.delete:
                                    ((GamesActivity) context).deleteGame( position );
                                    break;
                            }
                            return false;
                        }
                    } );
                    //displaying the popup
                    popup.show();
                }
            } );
        }
    }

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

    //Formatting TimeStamp to 'EEE MMM dd yyyy (HH:mm:ss)'
    //Input  : 2018-05-23 9:59:01
    //Output : Wed May 23 2018 (9:59:01)
    private String formatDate(String dateStr) {
        try {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = fmt.parse(dateStr);
            SimpleDateFormat fmtOut = new SimpleDateFormat("EEE MMM dd yyyy (HH:mm:ss)");
            return fmtOut.format(date);
        } catch (ParseException ignored) {

        }

        return "";
    }

    @Override
    public int getItemViewType(int position) {
        if (position > 0 && position % AD_DELTA == 0) {
            return AD_TYPE;
        }
        return CONTENT_TYPE;
    }
Robert Vogl
  • 250
  • 5
  • 19

1 Answers1

0

When passing a List of objects to a recycler view it expect a single model (a single object type). In your case you are passing a Game object.

Say you have a list with 5 objects (as your example shows).. When building your holder you are replacing the fourth object with an AD_VIEW instead of building a holder for the fourth object.

Solution 1: Add an AdView to your layout with visibility=GONE Set visibility to VISIBLE when you your position variable meets the requirements.

Solution 2: Create a wrapper object that looks somthing like this:

public class Wrapper{
   public Game game;
   public boolean isAd;
}

and pass an object in the position you desire. So in the case of the example you should pass 5 Wrapper objects with a game object assigned and a 6th Wrapper object in the position you desire that has isAd=true and game=null.

n0ra5
  • 71
  • 2
  • I am relatively new to android programming, so I have been looking for an example of how to implement Solution 1, but I have not been able to find anything. Do you know of any? – Robert Vogl Aug 06 '19 at 16:18
  • The more I am reading on this, the more I am thinking that my problem is that I am not assigning the correct list position to the ads. Is there away to assign a position to a view? The reason I am thinking this is because the list item is actually hiding behind the ad itself. – Robert Vogl Aug 07 '19 at 21:26