简体   繁体   English

Recyclerview 使用两个 viewholder 重叠回收项

[英]Recyclerview using two viewholder overlap recycler item

I want to show admob ads after some notice board items.我想在一些布告栏项目之后显示 admob 广告。 So I changed recyclerview to use two viewholder and show adview if the position is in noticeitem's end.所以我改变了 recyclerview 使用两个 viewholder 并显示 adview 如果位置在 noticeitem 的末尾。 But it shows item on the first list of board item view and can't see the first item of the board但是它在板项目视图的第一个列表中显示项目并且看不到板的第一项

I tried to add first item to position+1 and it shows two items我尝试将第一个项目添加到 position+1 并显示两个项目

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
       private RecyclerView recyclerView;
       private Context context;
       private ArrayList<stTalkListContentsData> talkArrayList = new ArrayList<>();
       private ViewGroup parent;
       private int mNoticeCount = 0;

       public RecyclerAdapter(Context context, RecyclerView recyclerView, ArrayList<stTalkListContentsData> talkArrayList) {
           this.context = context;
           this.recyclerView = recyclerView;
           this.talkArrayList = talkArrayList;
       }

       public class AdViewHolder extends RecyclerView.ViewHolder {
           private AdView adView;
           AdViewHolder(View view) {
               super(view);
               adView = view.findViewById(R.id.adView);

           }
       }

       @Override
       public int getItemViewType(int position) {
           if (position == mNoticeCount) {
               return Define.AD_TYPE;
           } else {
               return Define.CONTENT_TYPE;
           }
       }
 @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            ViewHolder viewHolder = null;
            switch (viewType) {
                case Define.CONTENT_TYPE:
                    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_board_title_list, parent, false);
                    return new ViewHolder(v);
                case Define.AD_TYPE:
                    default:
                    View bannerAdView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_board_adview, parent, false);
                    return new AdViewHolder(bannerAdView);
            }
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            int type = getItemViewType(position);
            switch (type){
                case AD_TYPE:
                    AdViewHolder bannerHolder = (AdViewHolder) holder;
                    AdView adView = ((AdViewHolder) holder).adView;
                    ViewGroup adCardView = (ViewGroup) bannerHolder.itemView;
                    if (adCardView.getChildCount() > 0) {
                        adCardView.removeAllViews();
                    }
                    if (adView.getParent() != null) {
                        ((ViewGroup) adView.getParent()).removeView(adView);
                    }
                    AdRequest adRequest =  new AdRequest.Builder().build();
                    adView.loadAd(adRequest);
                    adCardView.addView(adView);
                    break;
                case CONTENT_TYPE:{
                    stTalkListContentsData msgitem = talkArrayList.get(position);

                    JSAppNoticeContentsData talk_notice_info = msgitem.getTalkNoticeInfo();
                    JSBoardInfoData talk_board_info = msgitem.getTalkListBoardInfo();
                    ViewHolder talkholder = (ViewHolder) holder;

                   ....

                    talkholder.bind(position);
                }
                    break;
            }
        }

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

The getItemCount() function of adapter should return talkArrayList.size()+1适配器的 getItemCount() 函数应该返回 talkArrayList.size()+1

 @Override
    public int getItemCount() {
        return this.talkArrayList.size()+1;
    }

Also in onBindViewHolder you cannot directly use position to bind data as the recyclerview holds ad item at some position which is not in the talkArrayList.同样在 onBindViewHolder 中,您不能直接使用 position 来绑定数据,因为 recyclerview 将广告项保存在不在 talkArrayList 中的某个位置。 If the position is before mNoticeCount use talkArrayList.get(position) to get msgItem or use talkArrayList.get(position-1), that is如果位置在 mNoticeCount 之前使用 talkArrayList.get(position) 获取 msgItem 或使用 talkArrayList.get(position-1),即

 case CONTENT_TYPE:{
                stTalkListContentsData msgitem;
                    if(position < mNoticeCount ){
                msgitem = talkArrayList.get(position);
                   }else {
                msgitem = talkArrayList.get(position-1);
               }


                JSAppNoticeContentsData talk_notice_info = msgitem.getTalkNoticeInfo();
                JSBoardInfoData talk_board_info = msgitem.getTalkListBoardInfo();
                ViewHolder talkholder = (ViewHolder) holder;

               ....

                talkholder.bind(position);
            }
                break;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM