2

我正在尝试在 RecyclerView 中添加原生广告。我已经看过谷歌示例中提供的示例。该示例来自已填充的列表,然后向其中添加广告原生广告。就我而言,我在适配器中使用 onLoadMore 为 RecyclerView 的每个 API 调用加载 10 个项目。我希望我的广告在列表中的每 8 位展示一次。

根据此处的 google 示例,它检查列表中的每 8、16、24... 位置。但是当我最初在第一次迭代中添加广告时,项目总数变为 12(10 个列表项 + 2 个位于第 0 位和第 8 位的广告)。在第二次迭代中,项目总数变为 24(20 个列表项 + 4 个位于第 0、8、12 和 20 位的广告)。在适配器中,它检查 adview 的第 8、16、24... 位置。然后我得到类转换异常,因为适配器正在查看第 16 位的 adview,但它实际上是菜单项。我究竟做错了什么?帮我。下面是我的片段和适配器类。

适配器类:

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();

}

片段类:

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());
  }
}
4

0 回答 0