RecyclerViewAdapter

时间:2017-09-30 05:20:17

标签: java android nullpointerexception android-adapter

适配器工作正常,直到我决定添加原生广告,因为我在适配器中进行了6次更改。

  1. 添加了新的ViewType(AD_VIEW_TYPE)
  2. 添加了新的ViewHolder(NativeExpressAdViewHolder)
  3. 更改了getItemViewType(使其在每第8个位置返回AD_VIEW_TYPE)
  4. 在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. 为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. 除了上述更改之外,我还在活动和适配器中将ArrayList<CardSetterGetter>更改为ArrayList<Object>

  7. 现在的问题是,当我运行应用程序时,它会抛出NullPointerException

    logcat说

     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)
    

    这些是我的代码中logcat指向

    的部分
    /*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);
                }
            });
    
        }
    }
    }
    

    我知道NullPointerException是什么,我知道这些问题的解决方案,但在这种情况下,我很难找到问题的来源和解决方案。因此,如果解决方案很简单,请考虑帮助我解决问题,而不是将问题标记为重复。

1 个答案:

答案 0 :(得分:1)

当在recyclerView中膨胀2种不同的视图类型时,我们需要创建2个单独的ViewHolder类来包含每个布局中的不同元素

尝试以下方法:

//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

    }

还有一件事,请检查您的XML,您的XML应该是这样的

<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>