2

I'm trying to add native ads in RecyclerView. I have already seen the example provided in google samples. That example is from the list which has been already populated and then adding ad native ads to it. In my case, I am loading 10 items per API call to the RecyclerView using onLoadMore in my adapter. I want my ads to show at every 8th position in the list.

According to the google example here, it checks for every 8th, 16th,24th... position in the list. But when I initially add ads in the first iteration, a total number of items becomes 12 (10 list items + 2 ads on 0th and 8th position). In the second iteration, total number of items becomes 24 (20 list items + 4 ads on 0th, 8th, 12th and 20th position). In the adapter, it checks for 8th, 16th, 24th... positions for the adview. And then I get the class cast exception because the adapter is looking the adview at the 16th position but it actually is the menu item. What am I doing wrong? Help me. Below are my fragment and adapter classes.

Adapter class:

public class NewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int REQUEST_FOR_ACTIVITY_CODE = 110;
boolean isBookmarked;
public static int lastAdPosition = 0;

public static class UserViewHolder extends RecyclerView.ViewHolder {

    ImageView thumbnail;
    CustomFontTextView share, bookmark, shortbyte;
    TextView title;
    LinearLayout linearLayout;


    public UserViewHolder(View itemView) {
        super(itemView);
        this.linearLayout = (LinearLayout) itemView.findViewById(R.id.card_view_root_layout);
        this.thumbnail = (ImageView) itemView.findViewById(R.id.activity_post_thumbnail);
        this.share = (CustomFontTextView) itemView.findViewById(R.id.share);
        this.bookmark = (CustomFontTextView) itemView.findViewById(R.id.bookmark);
        this.shortbyte = (CustomFontTextView) itemView.findViewById(R.id.shortbyte);
        this.title = (TextView) itemView.findViewById(R.id.post_title);
    }
}

public static class LoadingViewHolder extends RecyclerView.ViewHolder {
    public ProgressBar progressBar;

    public LoadingViewHolder(View itemView) {
        super(itemView);
        progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar1);
    }
}

public class AdViewHolder extends RecyclerView.ViewHolder {

    AdViewHolder(View view) {
        super(view);
    }
}

private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private final int VIEW_TYPE_AD = 2;

List<Integer> adPositionList = new ArrayList<>();

private OnLoadMoreListener mOnLoadMoreListener;

private boolean isLoading;
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
private List<Object> adapterPostList;
private Typeface customFont;
DataStorage sharedPreference;
Context context;
Activity activity;
RecyclerView recyclerView;
private static boolean isLoadingVisible;
private boolean isBookmarkCalledFromMainActivity;
private CoordinatorLayout frameLayout;
private Typeface custom_font, custom_font2;
private int screenWidth;
private LinearLayout linearLayout;
private boolean isFromSearchActivity;

public NewAdapter(List<Object> postListFromMainActivity, Context context, Activity activity,
                  RecyclerView recyclerView, boolean isBookmarkCalledFromMainActivity, CoordinatorLayout frameLayout,
                  boolean isFromSearchActivity, LinearLayout linearLayout) {

    this.frameLayout = frameLayout;
    this.linearLayout = linearLayout;
    this.isBookmarkCalledFromMainActivity = isBookmarkCalledFromMainActivity;
    this.isFromSearchActivity = isFromSearchActivity;
    this.recyclerView = recyclerView;
    this.activity = activity;
    this.context = context;
    customFont = Typeface.createFromAsset(context.getAssets(), "fonts/RobotoCondensed-Bold.ttf");
    sharedPreference = new DataStorage();
    adapterPostList = new ArrayList<>();
    adapterPostList = postListFromMainActivity;
    custom_font = Typeface.createFromAsset(context.getAssets(), "fonts/RobotoCondensed-Light_0.ttf");
    custom_font2 = Typeface.createFromAsset(context.getAssets(), "fonts/RobotoCondensed-Regular_0.ttf");
    WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    screenWidth = size.x;

    final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            totalItemCount = linearLayoutManager.getItemCount();
            lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

            if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                if (mOnLoadMoreListener != null) {
                    mOnLoadMoreListener.onLoadMore();
                }
                isLoading = true;
            }
        }
    });
}

public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
    this.mOnLoadMoreListener = mOnLoadMoreListener;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == VIEW_TYPE_ITEM) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_post_layout, parent, false);
        return new UserViewHolder(view);
    } else if (viewType == VIEW_TYPE_LOADING) {
        View view = LayoutInflater.from(context).inflate(R.layout.layout_loading_item, parent, false);
        return new LoadingViewHolder(view);
    } else if (viewType == VIEW_TYPE_AD) {
        View view = LayoutInflater.from(context).inflate(R.layout.native_express_ad_container, parent, false);
        return new AdViewHolder(view);
    }
    return null;
}

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

    if (holder instanceof UserViewHolder) {
        #some code
    } else if (holder instanceof LoadingViewHolder) {
        if (!isLoadingVisible) {
            isLoadingVisible = true;
            LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
            loadingViewHolder.progressBar.setIndeterminate(true);
        }
    } else if (holder instanceof AdViewHolder) {
        AdViewHolder nativeExpressHolder = (AdViewHolder) holder;
        NativeExpressAdView adView = (NativeExpressAdView) adapterPostList.get(position);
        ViewGroup adCardView = (ViewGroup) nativeExpressHolder.itemView;

        if (adCardView.getChildCount() > 0) {
            adCardView.removeAllViews();
        }
        if (adView.getParent() != null) {
            ((ViewGroup) adView.getParent()).removeView(adView);
        }

        // Add the Native Express ad to the native express ad view.
        adCardView.addView(adView);
    }
}


@Override
public int getItemCount() {
    return adapterPostList == null ? 0 : adapterPostList.size();
}

public void setLoaded() {
    isLoading = false;
}

@Override
public int getItemViewType(int position) {

    if (adapterPostList.get(position) == null) {
        return VIEW_TYPE_LOADING;

    } else if ( position % HomeFragment.ITEMS_PER_AD == 0) {
        return VIEW_TYPE_AD;
    } else {
        return VIEW_TYPE_ITEM;
    }
}

public void add(Posts product) {
    adapterPostList.add(product);
    notifyDataSetChanged();
}


public void remove(Posts product) {
    adapterPostList.remove(product);
    notifyDataSetChanged();
}

public void clear() {

    try {
        ((AppCompatActivity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapterPostList.clear();
                notifyDataSetChanged();
            }
        });
    } catch (WindowManager.BadTokenException e) {

    } catch (Exception e) {
    }

}

public void addAll(List<Object> list) {

    adapterPostList.addAll(list);
    notifyDataSetChanged();

}

Fragment Class:

public class HomeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

private RecyclerView postsRecyclerView;
private RecyclerView.LayoutManager layoutManager;
private List<Object> postsLists;
private NewAdapter postsListAdapter;
private int pageNo = 1;
private boolean responseCalled = false;
private Activity activity;
private ProgressBar bar;
private CoordinatorLayout coordinatorLayout;
private String url;
boolean doubleBackToExitPressedOnce = false;
private Context context;
private SwipeRefreshLayout mWaveSwipeRefreshLayout;
private boolean isRefreshing = false, isPostsAdapterClearedOnce = false;
private CardView refresh;
private TextView noInternet, cardText;
public static boolean isHomeFragment;
private DataStorage sharedPreference;


private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/1072772517";


public static final int ITEMS_PER_AD = 8;

// The Native Express ad height.
private static final int NATIVE_EXPRESS_AD_HEIGHT = 150;



@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    setHasOptionsMenu(true);
    isHomeFragment = true;
    sharedPreference = new DataStorage();
    coordinatorLayout = (CoordinatorLayout) rootView.findViewById(R.id.frame_container);
    postsRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
    url = ServiceURLManager.getInstance().getPostsUrl(pageNo);

    postsLists = new ArrayList<>();
    context = getActivity();

    activity = getActivity();

    bar = (ProgressBar) rootView.findViewById(R.id.progressBar);
    bar.setIndeterminate(true);
    bar.setVisibility(View.VISIBLE);
    refresh = (CardView) rootView.findViewById(R.id.refresh);
    cardText = (TextView) rootView.findViewById(R.id.cardText);
    cardText.setText("No Connection! Retry.");
    noInternet = (TextView) rootView.findViewById(R.id.noInternetConnection);
    refresh.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            refresh();
        }
    });
    String myUrl = ServiceURLManager.getInstance().getPostsUrl(1);
    if (!Utils.getInstance().isNetworkAvailable(context)) {
        refresh.setVisibility(View.VISIBLE);
        noInternet.setVisibility(View.INVISIBLE);
    } else if (!SingleArticleActivity.iscalledfromSingleArticleActivity) {
        VolleySingleton.getInstance(getContext()).getRequestQueue().getCache().remove(myUrl);
    }

    callMorePosts(url);
    initializeAdapter();
    initView(rootView);

    return rootView;
}

public boolean checkFavoriteItem(Posts checkProduct) {
    boolean check = false;
    List<Posts> favorites = sharedPreference.getFavorites(context);
    if (favorites != null) {
        for (Posts product : favorites) {
            if (product.getPostId().equals(checkProduct.getPostId())) {
                check = true;
                break;
            }
        }
    }
    return check;
}

public void refresh() {
    if (Utils.getInstance().isNetworkAvailable(context)) {
        bar.setVisibility(View.VISIBLE);
        refresh.setVisibility(View.INVISIBLE);
        noInternet.setVisibility(View.INVISIBLE);
        callMorePosts(url);
        initializeAdapter();
    }
}

private void initView(View view) {
    mWaveSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.main_swipe);
    mWaveSwipeRefreshLayout.setColorSchemeColors(getResources().getColor(R.color.appcolor));
    mWaveSwipeRefreshLayout.setOnRefreshListener(this);
}


private void hideProgressBar() {
    try {
        ((MainActivity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (bar != null) {
                    bar.setVisibility(View.GONE);
                }
            }
        });
    } catch (WindowManager.BadTokenException e) {

    } catch (Exception e) {

    }

}

private void initializeAdapter() {

    postsRecyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(getActivity());
    postsRecyclerView.setLayoutManager(layoutManager);
    postsListAdapter = new NewAdapter(postsLists, getActivity(), activity, postsRecyclerView, true, coordinatorLayout, false, null);
    AlphaInAnimationAdapter alphaAdapter = new AlphaInAnimationAdapter(postsListAdapter);
    postsRecyclerView.setAdapter(new ScaleInAnimationAdapter(alphaAdapter));
    postsListAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
        @Override
        public void onLoadMore() {
            postsLists.add(null);
            postsListAdapter.notifyItemInserted(postsLists.size() - 1);

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    postsLists.remove(postsLists.size() - 1);
                    postsListAdapter.notifyItemRemoved(postsLists.size());
                    responseCalled = false;
                    url = ServiceURLManager.getInstance().getPostsUrl(pageNo);
                    callMorePosts(url);
                }
            }, 5000);
        }
    });
}

@Override
public void onResume() {

    super.onResume();
    if (postsListAdapter != null)
        postsListAdapter.notifyDataSetChanged();
    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {

                if (drawer.isDrawerOpen(Gravity.LEFT)) {
                    drawer.closeDrawer(Gravity.LEFT);
                } else {
                    if (doubleBackToExitPressedOnce) {
                        getActivity().finish();
                    }
                    doubleBackToExitPressedOnce = true;
                    showSnackbar("Press again to exit");
                    new Handler().postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            doubleBackToExitPressedOnce = false;
                        }
                    }, 2000);
                    return true;
                }
            }

            return false;
        }
    });
}

public void showSnackbar(String message) {
    Snackbar snackbar = Snackbar
            .make(postsRecyclerView, message, Snackbar.LENGTH_LONG);
    snackbar.show();
}

private void callMorePosts(String url) {
    JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
            url, null, new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {
            if (!responseCalled) {
                Log.d("RECENT_RESPONSE", response.toString());
                responseCalled = true;


                try {
                    String status = response.getString("status");
                    if (status.equalsIgnoreCase("ok")) {
                        JSONArray jsonPostsArray = response.getJSONArray("posts");
                        isPostsAdapterClearedOnce = true;
                        int i;
                        if (jsonPostsArray.length() > 0) {
                            for (i = 0; i < jsonPostsArray.length(); i++) {

                                JSONObject jsonPostObject = jsonPostsArray.getJSONObject(i);
                                Posts postsItems = new Posts();
                                String thumbnailMedium = jsonPostObject.getString("thumbnail");
                                thumbnailMedium = thumbnailMedium.replace("-150x150", "");
                                postsItems.setThumbnail(thumbnailMedium);
                                postsItems.setPostId(jsonPostObject.getString("id"));
                                postsItems.setExcerpt(jsonPostObject.getString("excerpt"));
                                postsItems.setContent(jsonPostObject.getString("content"));
                                String newTitle = jsonPostObject.optString("title").replaceAll("&#822\\d;", "\"");
                                newTitle = newTitle.replaceAll("&#8217;", "'");
                                newTitle = newTitle.replaceAll("&#8216;", "'");
                                newTitle = newTitle.replaceAll("&#8211;", "-");
                                newTitle = newTitle.replaceAll("&#8212;", "-");
                                newTitle = newTitle.replaceAll("&#038;", "&");
                                postsItems.setTitle(newTitle);
                                postsItems.setUrl(jsonPostObject.optString("url"));
                                postsItems.setDate(jsonPostObject.optString("date"));
                                postsItems.setPostCountTotal(jsonPostObject.optInt("count_total"));
                                postsItems.setPageCount(jsonPostObject.optInt("pages"));
                                JSONObject jsonAuthorObject = jsonPostObject.getJSONObject("author");
                                Author author = new Author();
                                author.setFirst_name(jsonAuthorObject.getString("first_name"));
                                author.setLast_name(jsonAuthorObject.getString("last_name"));
                                author.setId(jsonAuthorObject.optInt("id"));
                                author.setDescription(jsonAuthorObject.getString("description"));
                                postsItems.setAuthor(author);
                                JSONArray jsonTagsArray = jsonPostObject.getJSONArray("tags");

                                List<Tags> tagsList = new ArrayList<Tags>();
                                for (int j = 0; j < jsonTagsArray.length(); j++) {
                                    JSONObject jsonTagsObject = jsonTagsArray.getJSONObject(j);
                                    Tags tagsItems = new Tags();
                                    tagsItems.setId(jsonTagsObject.optInt("id"));
                                    tagsItems.setTitle(jsonTagsObject.optString("title"));
                                    tagsItems.setPost_count(jsonTagsObject.getInt("post_count"));
                                    tagsList.add(tagsItems);
                                }
                                postsItems.setTags(tagsList);
                                postsItems.setSlug(jsonPostObject.optString("slug"));
                                if (isRefreshing && isPostsAdapterClearedOnce) {

                                    postsListAdapter.clear();
                                    isRefreshing = false;
                                    isPostsAdapterClearedOnce = false;
                                }

                                postsLists.add(postsItems);

                              }

                            }
                            hideProgressBar();
                            pageNo = pageNo + 1;
                            addNativeExpressAds();
                            setUpAndLoadNativeExpressAds();
                            mWaveSwipeRefreshLayout.setRefreshing(false);
                            postsListAdapter.notifyDataSetChanged();
                            postsListAdapter.setLoaded();

                        } else {

                        }


                    } else {
                        Toast.makeText(getActivity(), "Server is down. Try after sometime.", Toast.LENGTH_LONG).show();
                    }
                } catch (Exception e) {

                    Log.e("POSTLISTADAPTER", "Error on :" + pageNo + " " + e.getMessage().toString());
                }
            }
        }
    }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.d("RECENT_ERROR", "Error: " + error.getMessage());
            hideProgressBar();

            if (error != null && error.networkResponse != null && error.networkResponse.statusCode == HttpURLConnection.HTTP_NOT_FOUND) {
                Toast.makeText(getActivity(), "Error fetching content", Toast.LENGTH_LONG).show();
            }
        }
    }) {

        @Override
        protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
            try {
                Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
                if (cacheEntry == null) {
                    cacheEntry = new Cache.Entry();
                }
                long now = System.currentTimeMillis();
                final long softExpire = now + AppConstants.cacheHitButRefreshed;
                final long ttl = now + AppConstants.cacheExpired;
                cacheEntry.data = response.data;
                cacheEntry.softTtl = softExpire;
                cacheEntry.ttl = ttl;
                String headerValue;
                headerValue = response.headers.get("Date");
                if (headerValue != null) {
                    cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                headerValue = response.headers.get("Last-Modified");
                if (headerValue != null) {
                    cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
                }
                cacheEntry.responseHeaders = response.headers;
                final String jsonString = new String(response.data,
                        HttpHeaderParser.parseCharset(response.headers));
                return Response.success(new JSONObject(jsonString), cacheEntry);
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            } catch (JSONException e) {
                return Response.error(new ParseError(e));
            }
        }

        @Override
        protected void deliverResponse(JSONObject response) {
            super.deliverResponse(response);

        }

        @Override
        public void deliverError(VolleyError error) {
            super.deliverError(error);
        }

        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            return super.parseNetworkError(volleyError);
        }
    };
    VolleySingleton.getInstance(getActivity()).addToRequestQueue(jsonObjReq);
}

@Override
public void onRefresh() {
    if (Utils.getInstance().isNetworkAvailable(context)) {
        refresh.setVisibility(View.INVISIBLE);
    }
    isRefreshing = true;
    responseCalled = false;
    pageNo = 1;
    String url = ServiceURLManager.getInstance().getPostsUrl(pageNo);
    callMorePosts(url);
}

private void addNativeExpressAds() {


    for (int i = 0; i <= postsLists.size(); i += ITEMS_PER_AD) {
        final NativeExpressAdView adView = new NativeExpressAdView(context);
        postsLists.remove(i);
        postsLists.add(i, adView);
    }

}

private void setUpAndLoadNativeExpressAds() {

    postsRecyclerView.post(new Runnable() {
        @Override
        public void run() {
            final float scale = context.getResources().getDisplayMetrics().density;
            CardView cardViewTemp = null;

            for (int i = 0; i <= postsLists.size(); i += ITEMS_PER_AD) {
                final NativeExpressAdView adView =
                        (NativeExpressAdView) postsLists.get(i);
                final CardView cardView = (CardView) getActivity().findViewById(R.id.ad_card_view);
                cardViewTemp = cardView;
                if (cardView != null) {
                    final int adWidth = cardView.getWidth() - cardView.getPaddingLeft()
                            - cardView.getPaddingRight();
                    AdSize adSize = new AdSize((int) (adWidth / scale), NATIVE_EXPRESS_AD_HEIGHT);
                    adView.setAdSize(adSize);
                    adView.setAdUnitId(AD_UNIT_ID);
                }
            }

            if (cardViewTemp != null)
                loadNativeExpressAd(0);
        }
    });
}


private void loadNativeExpressAd(final int index) {

    if (index >= postsLists.size()) {
        return;
    }

    Object item = postsLists.get(index);
    if (!(item instanceof NativeExpressAdView)) {
        throw new ClassCastException("Expected item at index " + index + " to be a Native"
                + " Express ad.");
    }

    final NativeExpressAdView adView = (NativeExpressAdView) item;

    adView.setAdListener(new AdListener() {
        @Override
        public void onAdLoaded() {
            super.onAdLoaded();

            loadNativeExpressAd(index + ITEMS_PER_AD);
        }

        @Override
        public void onAdFailedToLoad(int errorCode) {


            Log.e("MainActivity", "The previous Native Express ad failed to load. Attempting to"
                    + " load the next Native Express ad in the items list.");
            loadNativeExpressAd(index + ITEMS_PER_AD);
        }
    });

    adView.loadAd(new AdRequest.Builder().build());
  }
}

0 Answers0