java - AdMob 覆盖 Recyclerview 列表项
问题描述
我在回收站列表视图中添加了 Admob 横幅,但广告覆盖了列表项。我一直在通过堆栈寻找解决此问题的方法,我最接近的是在 Recyclerview 中嵌入广告
我尝试了本文中提供的几个答案,但均未成功。横幅添加始终覆盖列表项。从下图中可以看出,共有五场比赛,第四场比赛应显示在横幅广告下方。
有人可以帮我解决这个问题。我在下面放置了我的适配器的代码。
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;
}
解决方案
将对象列表传递给回收器视图时,它需要一个模型(单个对象类型)。在您的情况下,您正在传递一个Game对象。
假设您有一个包含 5 个对象的列表(如您的示例所示)。在构建您的持有人时,您正在用 AD_VIEW 替换第四个对象,而不是为第四个对象构建持有人。
解决方案 1: 在您的布局中添加 AdView,visibility=GONE 当您的位置变量满足要求时,将可见性设置为 VISIBLE。
解决方案 2: 创建一个看起来像这样的包装器对象:
public class Wrapper{
public Game game;
public boolean isAd;
}
并在您想要的位置传递一个对象。因此,在示例的情况下,您应该传递 5 个 Wrapper 对象并分配一个游戏对象,并在您想要的位置传递第 6 个 Wrapper 对象,该位置具有 isAd=true 和 game=null。
推荐阅读
- asp.net-core - 如何通过 FluentValidation 验证上传的文件
- ruby-on-rails - 错误:Thor:Class 的未定义方法“deprecation_warning”
- jquery - 当我在服务器上部署我的 laravel 项目时,出现此错误 try{r.send(i.hasContent&&i.data||null) 但在我的本地主机上它运行良好
- ubuntu - 包含绝对路径时的重复性 FilePrefixError
- python-3.x - 如何在 Ubuntu 服务器 18.04 中安装 tensorflow 1.15.0
- asp.net-mvc - 如何使用 ASP.NET Core 3.0 将数据从控制器发送到 cshtml
- xamarin - 如何仅在 xamarin.forms 中使用微调器项目选择打开另一个活动?
- regex - bash中的RegEx有问题吗?
- linux-capabilities - 在 clone(2)、unshare(2) 和 setns(2) 期间将更改哪些进程/线程功能集?
- haskell - 我们如何限制 Haskell 中的递归调用?