【问题标题】:Display ad every n items in RecyclerAdapter在 RecyclerAdapter 中每 n 个项目显示广告
【发布时间】:2015-03-14 09:07:43
【问题描述】:

我想在我的 RecyclerAdapter 上每隔 n 个项目显示一个广告。

我期待这个

|----- Item 0 -----|
|------- AD -------|
|----- Item 1 -----|
|----- Item 2 -----|
|----- Item 3 -----|
|----- Item 4 -----|
|----- Item 5 -----|
|------ ... -------|
|----- Item 15 ----|
|------- AD -------|
|----- Item 16 ----|
|------ ... -------|

但是通过快速滚动,我可以拥有类似的东西

|----- Item 0 -----|
|------- AD -------|
|----- Item 1 -----|
|----- Item 2 -----|
|----- Item 3 -----|
|------ ... -------|
|---- Item 241 ----|
|------- AD -------|
|------ ... -------|

如果我滚动缓慢,广告会在每 15 个项目之后显示。 但如果我快速滚动,广告显示不正确。例如广告显示在 item n°241 之后,并且 241 % 15 不等于 0。

这可能是由于视图重用造成的问题吗?我可能做错了,但我不知道该怎么做。

这是我的适配器代码。

public class MyCursorRecyclerAdapter extends CursorRecyclerAdapter<RecyclerView.ViewHolder> {

private static final int AD_POS = 15;

private Context mContext;
private LayoutInflater mInflater;

class ViewHolderItem extends RecyclerView.ViewHolder {
    public TextView mTextView;
    public LinearLayout mLayout;

    public ViewHolderItem(View layout) {
        super(layout);
        mTextView = (TextView) layout.findViewById(R.id.text);
        mLayout = (LinearLayout) layout.findViewById(R.id.main_linear_layout);
    }
}

public MyCursorRecyclerAdapter(Context context, Cursor c) {
    super(c);
    mContext = context;
    mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.listview_item_layout, parent, false);

    return new ViewHolderItem(v);
}

@Override
public void onBindViewHolderCursor(RecyclerView.ViewHolder holderDefault, Cursor cursor) {

    int cursorPosition = cursor.getPosition();

    final ViewHolderItem holder = (ViewHolderItem) holderDefault;
    final String text = cursorPosition + " : "+ cursor.getString(cursor.getColumnIndex(MyTable.MY_COLUMN));

    holder.mTextView.setText(text);

    final ViewGroup layout = ((ViewHolderItem) holderDefault).mLayout;

    if (cursorPosition % AD_POS == 0) {
        NativeAd ad = new NativeAd(mContext, "ID");
        ad.setAdListener(new AdListener() {
            @Override
            public void onError(Ad ad, AdError error) {}

            @Override
            public void onAdLoaded(Ad ad) {
                mInflater.inflate(R.layout.native_ad_layout, layout);
                AdManager.inflateAd((NativeAd) ad, layout, mContext);
            }

            @Override
            public void onAdClicked(Ad ad) {}
        });
        ad.loadAd();
    } else {
        int childCount = layout.getChildCount();
        if (layout.getChildAt(childCount-1).getId() == R.id.adUnit) {
            layout.removeViewAt(childCount-1);
        }
    }
}
}

【问题讨论】:

    标签: android android-listview android-recyclerview


    【解决方案1】:

    更好的方法是使用getItemViewType(int position) 方法。

    @Override
    public int getItemViewType(int position) {
        if(cursorPosition % AD_POS == 0){
            return 0;
        }
        return 1;
    }
    

    然后你必须在 onCreateViewHolder 方法中使用 viewType 参数,来识别你必须膨胀的视图,如下面的代码所示:

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType ==0){
             View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.listview_item_layout, parent, false);    
        } else if(viewType ==1){ 
             View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.different_layout, parent, false); 
        }
    
        return new ViewHolderItem(v);
    }
    

    此外,您还必须支持 ViewHolderItem 中的第二个布局或创建 SecondViewHolderItem 并在上述方法中返回正确的 ViewHolder 并在 onBindViewHolderCursor 方法中转换为正确的 ViewHolder 取决于位置。

    你必须在getItemCount()方法中考虑这些项目。

    【讨论】:

    • 如果我的数据库中有 100 件商品,并且我想每 10 件商品展示一个广告。我的列表视图中将有 110 个项目?还是100?我是否必须覆盖 getItemCount() 才能将其增加 10 ?
    • 是的,我忘记了。您必须在 getItemCount() 方法中考虑这些项目
    • 我认为它会起作用,但我对 getItemId(int position); 有疑问我将其覆盖为始终返回 12721,但在我的列表视图中,我并不总是看到相同的报价。
    • 你为什么要这样做?是特殊原因吗? Id 应该是 -1 (NO_ID) 或者应该是唯一的。您可以返回 getItemId() 位置
    • 如果我的回答对你有帮助,请采纳或给我点赞:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多