Пусть два разных элемента используют один и тот же адаптер, и каждый элемент данных не будет заменен другим элементом в RecyclerView

#java #android #android-recyclerview

#java #Android #android-recyclerview

Вопрос:

Я хочу создать свое приложение с двумя элементами (Post и Ad) в одном и том же RecyclerView .

Но мой элемент будет заменен другим элементом, а не вставлен.

Как я могу это исправить!

Я хочу правую сторону, но теперь мой код — это левая сторона, и он будет разбит!

Вот мой адаптер:

 public class PostCardImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public static final int Post_Layout = 0;
    public static final int AD_Layout = 1;

    private Context mContext;
    private ArrayList<PostCard> mData;

    private int mAdCount;
    public static NativeAd nativeAd = HomePageActivity.nativeAd;

    public PostCardImageAdapter(Context context, ArrayList<PostCard> data) {
        this.mContext = context;
        this.mData = data;
    }

    public int getmAdCount(){
        mAdCount = mData.size() / 2;
        return mAdCount;
    }

    @Override
    public int getItemViewType(int position) {

        /*if(mAdCount != 0 amp;amp; position >= dataItemCount){
            return AD_Layout;
        }

        else{
            return Post_Layout;
        }*/

        if(position!=0 amp;amp; (position % 2 == 0)){
            return AD_Layout;
        }

        else{
            return Post_Layout;
        }
    }

    public static class PostViewHolder extends RecyclerView.ViewHolder {
        private ImageView postcard_userIcon;
        private TextView postcard_name;
        private TextView postcard_time;
        private TextView postcard_postText;
        private ImageView postcard_postPic;
        private TextView postcard_likes;
        private TextView postcard_comments;

        public PostViewHolder(View postView) {
            super(postView);
            postcard_userIcon = (ImageView) postView.findViewById(R.id.postcard_userIcon);
            postcard_name = (TextView) postView.findViewById(R.id.postcard_name);
            postcard_time = (TextView) postView.findViewById(R.id.postcard_time);
            postcard_postText = (TextView) postView.findViewById(R.id.postcard_postText);
            postcard_postPic = (ImageView) postView.findViewById(R.id.postcard_postPic);
            postcard_likes = (TextView) postView.findViewById(R.id.postcard_likes);
            postcard_comments = (TextView) postView.findViewById(R.id.postcard_comments);
        }
    }

    public static class AdViewHolder extends RecyclerView.ViewHolder {

        NativeAdLayout nativeAdContainer;
        TextView nativeAdTitle;
        TextView sponsoredLabel;
        TextView nativeAdBody;
        TextView nativeAdSocialContext;

        AdIconView nativeAdIcon;
        MediaView nativeAdMedia;

        Button nativeAdCallToAction;

        //LinearLayout adChoicesContainer;

        public AdViewHolder(View adView) {
            super(adView);
            nativeAdContainer = adView.findViewById(R.id.native_ad_container);
            nativeAdTitle = adView.findViewById(R.id.native_ad_title);
            sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label);
            nativeAdBody = adView.findViewById(R.id.native_ad_body);
            nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context);

            nativeAdIcon = adView.findViewById(R.id.native_ad_icon);
            nativeAdMedia = adView.findViewById(R.id.native_ad_media);

            nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action);

            /*adChoicesContainer = adView.findViewById(R.id.ad_choices_container);
            AdOptionsView adOptionsView = new AdOptionsView(mLayoutInflater.this, nativeAd, nativeAdContainer);
            adChoicesContainer.removeAllViews();
            adChoicesContainer.addView(adOptionsView, 0);*/
        }
    }

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

        if(viewType == Post_Layout){
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.postcard_layout, parent, false);
            return new PostViewHolder(v);
        }

        else {
          View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.native_ad_layout, parent, false);
          return new AdViewHolder(v);
      }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

        if(holder instanceof PostViewHolder){
            PostCard post = mData.get(position);

            ((PostViewHolder) holder).postcard_name.setText(post.name);
            ((PostViewHolder) holder).postcard_time.setText(post.time);
            ((PostViewHolder) holder).postcard_postText.setText(post.postText);
            ((PostViewHolder) holder).postcard_likes.setText(post.likes);
            ((PostViewHolder) holder).postcard_comments.setText(post.comments);
            Glide.with(mContext)
                    .load(post.userIconUrl)
                    .into(((PostViewHolder) holder).postcard_userIcon);
            Glide.with(mContext)
                    .load(post.postPicUrl)
                    .into(((PostViewHolder) holder).postcard_postPic);
        }

        else if(holder instanceof AdViewHolder){

            AdViewHolder adViewHolder = (AdViewHolder) holder;

            View adView = NativeAdView.render(mContext, nativeAd);
            adViewHolder.nativeAdTitle.setText(nativeAd.getAdvertiserName());
            adViewHolder.sponsoredLabel.setText(nativeAd.getSponsoredTranslation());
            adViewHolder.nativeAdBody.setText(nativeAd.getAdBodyText());
            adViewHolder.nativeAdSocialContext.setText(nativeAd.getAdSocialContext());

            adViewHolder.nativeAdCallToAction.setVisibility(nativeAd.hasCallToAction() ? View.VISIBLE : View.INVISIBLE);
            adViewHolder.nativeAdCallToAction.setText(nativeAd.getAdCallToAction());

            List<View> clickableViews = new ArrayList<>();
            clickableViews.add(adViewHolder.nativeAdTitle);
            clickableViews.add(adViewHolder.nativeAdCallToAction);

            nativeAd.registerViewForInteraction(
                    adView,
                    adViewHolder.nativeAdMedia,
                    adViewHolder.nativeAdIcon,
                    clickableViews);
        }
    }

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

Вот журнал:

 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: playground.com.pgapp, PID: 29719
    java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
        at java.util.ArrayList.get(ArrayList.java:411)
        at playground.com.pgapp.PostCardImageAdapter.onBindViewHolder(PostCardImageAdapter.java:156)
        at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
        at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
        at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
        at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:286)
        at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:343)
        at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:359)
        at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:366)
        at android.support.v7.widget.GapWorker.run(GapWorker.java:397)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:241)
        at android.app.ActivityThread.main(ActivityThread.java:6274)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
 

Комментарии:

1. Можно попробовать удалить, если еще, если просто использовать только if else.

2. Кажется, что у вас mData нет данных Ad, но getItemCount() возвращается адаптер mData.size() getmAdCount() . когда позиция шансов больше mData размера, тип представления будет Post_Layout , но для этой позиции нет индекса mData . итак, приложение разбилось!

3. @AmitPrajapati Я пробую, у него все та же проблема.

4. @Choim Как я могу добавить индекс mData?

5. У @Yunting make mData тоже есть данные Ad. Или onBindViewHolder() , когда ViewHolder PostViewHolder , используя index like position - position/2 . position/2 означает количество объявлений перед текущей позицией.

Ответ №1:

     public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

            if(holder instanceof PostViewHolder){
                int index = position - position / 2;
                PostCard post = mData.get(index);

                ((PostViewHolder) holder).postcard_name.setText(post.name);
                ((PostViewHolder) holder).postcard_time.setText(post.time);
                ((PostViewHolder) holder).postcard_postText.setText(post.postText);
                ((PostViewHolder) holder).postcard_likes.setText(post.likes);
                ((PostViewHolder) holder).postcard_comments.setText(post.comments);
                Glide.with(mContext)
                        .load(post.userIconUrl)
                        .into(((PostViewHolder) holder).postcard_userIcon);
                Glide.with(mContext)
                        .load(post.postPicUrl)
                        .into(((PostViewHolder) holder).postcard_postPic);
            }

            ...
}