2

The adapter was working just fine until I decided to add Native Ads, for that I made 6 changes in the adapter.

  1. added new ViewType (AD_VIEW_TYPE)
  2. added new ViewHolder (NativeExpressAdViewHolder)
  3. changed getItemViewType (made it return AD_VIEW_TYPE at every 8th position)
  4. added a new case in onCreateViewHolder

         switch (viewType){
    
            case AD_VIEW_TYPE:
            View nativeExpressLayoutView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.native_express_ad_container, parent, false);
            return new NativeExpressAdViewHolder(nativeExpressLayoutView);
    
  5. Added a new case to onBindViewHolder

              switch (viewType){
    
              case AD_VIEW_TYPE:
              NativeExpressAdViewHolder nativeExpressHolder = (NativeExpressAdViewHolder)holder;
              NativeExpressAdView adView = (NativeExpressAdView)arrayList.get(position);
    
            ViewGroup adCardView = (ViewGroup)nativeExpressHolder.itemView;
            adCardView.removeAllViews();
    
            if(adView.getParent() != null){
                ((ViewGroup)adView.getParent()).removeView(adView);
            }
    
            adCardView.addView(adView);
            break;
    
  6. Other than the above changes, I also changed my ArrayList<CardSetterGetter> to ArrayList<Object> in Activity and Adapter too.

Now the problem is that when I run the app, it throws NullPointerException.

the logcat says

 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
                                                                      at com.company.appname.adapters.RecyclerViewAdapter$RecyclerViewHolder.<init>(RecyclerViewAdapter.java:186)
                                                                      at com.company.appname.adapters.RecyclerViewAdapter$RecyclerViewHolder.<init>(RecyclerViewAdapter.java:165)
                                                                      at com.company.appname.adapters.RecyclerViewAdapter$NativeExpressAdViewHolder.<init>(RecyclerViewAdapter.java:150)
                                                                      at com.company.appname.adapters.RecyclerViewAdapter.onCreateViewHolder(RecyclerViewAdapter.java:84)
                                                                      at com.company.appname.adapters.RecyclerViewAdapter.onCreateViewHolder(RecyclerViewAdapter.java:48)

These are the part of my code where the logcat is pointing to

/*Line 48*/public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
 public RecyclerViewAdapter(Context context, ArrayList<Object> arrayList, ArrayList<String> favouriteItemList, int totalCount {...}

 @Override
 public long getItemId(int position){...}

     @Override
     public RecyclerViewAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

         switch (viewType){

         case AD_VIEW_TYPE:
            View nativeExpressLayoutView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.native_express_ad_container, parent, false);
 /*Line 84*/               return new NativeExpressAdViewHolder(nativeExpressLayoutView); 

         case MENU_ITEM_VIEW_TYPE:

         default:
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cards, parent, false);
            return new RecyclerViewHolder(view);
        }
    }

     @Override
     public void onBindViewHolder(final RecyclerViewHolder holder, final int position){...}

         public class NativeExpressAdViewHolder extends RecyclerViewHolder{
                NativeExpressAdViewHolder(View view){
/*Line 150*/                    super(view);
                }
        }

     @Override
     public int getItemViewType(int position){...}

     @Override
     public int getItemCount(){...}


/*Line 165*/        public class RecyclerViewHolder extends RecyclerView.ViewHolder {

    TextView title;
    RelativeLayout relativeLayout;
    RelativeLayout cardDescription;
    SimpleDraweeView image;
    ImageView favourite_button;
    CardSetterGetter cardSetterGetter;
    ImageView share;


    private RecyclerViewHolder(View itemView) {
        super(itemView);
        title = (TextView) itemView.findViewById(R.id.image_title);
        relativeLayout = (RelativeLayout) itemView.findViewById(R.id.activity_dash_board);
        cardDescription = (RelativeLayout) itemView.findViewById(R.id.card_details);
        image = (SimpleDraweeView) itemView.findViewById(R.id.image);
        favourite_button = (ImageView) itemView.findViewById(R.id.favourite_button);
        share = (ImageView) itemView.findViewById(R.id.share);

 /*Line 186*/           image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Activity activity = (Activity) context;
                saveInfo(constants.SERVERIP.concat(cardSetterGetter.getImageurl()), cardSetterGetter.getImageId(), cardSetterGetter.getDescription(), cardSetterGetter.getImagetitle(), cardSetterGetter.getFavourite());
                Intent i = new Intent().setClass(context, DetailsImageviewActivity.class);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
                context.startActivity(i);
                activity.overridePendingTransition(R.anim.pull_from_right, R.anim.pull_out_to_right);
            }
        });

    }
}
}

I know what a NullPointerException is, I know the solution to those problems, but in this case it's getting hard for me to find the source and the solution of the problem. So if the solution is that simple, instead of marking the question as a duplicate, please consider helping me out with this.

Ishan hrx
  • 403
  • 8
  • 19
  • I know what a NullPointerException is and how to fix it. It's just that I can't find the problem here. That is why I need a problem specific solution instead of general solution. – Ishan hrx Sep 30 '17 at 05:23
  • why your `public class NativeExpressAdViewHolder extends RecyclerViewHolder{` inside your `onBindViewHolder`?? – ken Sep 30 '17 at 06:32
  • @ken because of the casting issues, I asked a question here on StackOverflow and someone suggested me this, it solved the issue. – Ishan hrx Sep 30 '17 at 07:13

1 Answers1

1

When come to inflate 2 different view type in a recyclerView,we need to create 2 separate ViewHolder class to contain the different element inside of each layout

Try the following:

//make this a separate class,but not inside the onBindViewHolder
private class NativeExpressAdViewHolder extends RecyclerView.ViewHolder{
    NativeExpressAdViewHolder(View view){                            
    super(view);
    //find the view here
    adView = (NativeExpressAdView)view.findViewById(R.id.native_ad);
}

private class RecyclerViewHolder extends RecyclerView.ViewHolder{
   //this one as usual..
}



//change your onCreateViewHolder for this as well,
// cause now you have 2 view type,so you just override from universal 
//RecyclerView.ViewHolder,not need RecyclerViewAdapter.RecyclerViewHolder
   @Override
     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { }




@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    int viewType = getItemViewType(position);
    switch (viewType){
      case AD_VIEW_TYPE:
      final NativeExpressAdViewHolder adHolder (NativeExpressAdViewHolder)holder
       //here find your view and load the ad


     break;
     case MENU_ITEM_VIEW_TYPE:
     final  RecyclerViewHolder viewHolder = (RecyclerViewHolder)holder
     //do your thing here,find view,assign value to the layout

    }

And one more thing,please check your XML,your XML should look like this

<com.google.android.gms.ads.NativeExpressAdView
        xmlns:ads="http://schemas.android.com/apk/res-auto"
        android:id="@+id/native_ad"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        ads:adSize="360x132"
        ads:adUnitId="@string/your_ads">

 </com.google.android.gms.ads.NativeExpressAdView>
ken
  • 2,426
  • 5
  • 43
  • 98
  • thanks for the answer ken, but the NativeExpressAdViewHolder is already out of onBindViewHolder, do you want me to make it in another java File? – Ishan hrx Sep 30 '17 at 07:10
  • if it already outside the onBindViewHolder,then nvm,just follow the step of onBindViewHolder in answer,see whether is working – ken Sep 30 '17 at 07:18
  • I did as you suggested, it gives me two errors now, on in line 48 where it says `Class 'RecyclerViewHolder' must either be declared abstract or implement abstract method 'onBindViewHolder(VH, int)' in 'Adapter'`.... and the second error is in `@Override` above the `onBindViewHolder` it says `method does not override method from it's superclass` – Ishan hrx Sep 30 '17 at 07:31
  • I updated the answer.please change your onCreateViewHolder as well.. – ken Sep 30 '17 at 07:43
  • NullPointerException is still there. Logcat message is still the same but last line is missing (the one pointing to line 48) – Ishan hrx Sep 30 '17 at 07:55
  • ok..u can upload your XML as well?? for this layout file `R.layout.native_express_ad_container`,check whether is the native ads is cast in `com.google.android.gms.ads.NativeExpressAdView` – ken Sep 30 '17 at 07:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/155645/discussion-between-ishan-hrx-and-ken). – Ishan hrx Sep 30 '17 at 08:01
  • I updated the answer,please check your XML file – ken Sep 30 '17 at 08:02
  • hey, can you explain the logic behind `adView = (NativeExpressAdView)view.findViewById(R.id.native_ad);`, system cannot resolve symbol `adView` – Ishan hrx Sep 30 '17 at 10:54
  • you need to cast the adView to load your ads?usually is `NativeExpressAdView adView = (NativeExpressAdView)view.findViewById(R.id.native_ad);` if you dont need it,then no need add in.But you didnt add in this code,I wonder how you load your ads.And why you not accept the answer?I just help you solve the problem – ken Sep 30 '17 at 14:20