尝试使用RecyclerView添加Admob横幅广告时,出现ClassCastException。我正在使用来自博客的JSON数据,并且在添加横幅广告之前运行良好。我正在使用here中的GitHub项目参考。
错误:com.example.abcd.CategoryItem无法转换为
com.example.abcd.CategoryAdapter.onBindViewHolder上的com.google.android.ads.AdView(CategoryAdapter.java:123)
这是我的类别活动
public class CategoryActivity extends AppCompatActivity {
public static final int ITEMS_PER_AD=8;
private static final String AD_UNIT_ID="ca-app-pub-3940256099942544/6300978111";
private RecyclerView mRecyclerView;
private CategoryAdapter mCategoryAdapter;
// List of banner ads and MenuItems that populate the RecyclerView.
private List<Object> mCategoryList = new ArrayList<>();
private RequestQueue mRequestQueue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
mRecyclerView = findViewById(R.id.recycler_view_category);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
addBannerAds();
loadBannerAds();
// Specify an adapter.
RecyclerView.Adapter<RecyclerView.ViewHolder> adapter = new CategoryAdapter(this, mCategoryList);
mRecyclerView.setAdapter(adapter);
}
private void parseJSON() {
String url="http://sambalpurijokeszone.blogspot.com/feeds/posts/summary?alt=json&max-results=0";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONObject feed=(JSONObject) response.get("feed");
JSONArray category =(JSONArray)feed.get("category");
JSONArray sortedCategory=new JSONArray();
List<JSONObject> jsonValues=new ArrayList<JSONObject>();
for (int i = 0; i < category.length(); i++) {
jsonValues.add(category.getJSONObject(i));
}
//Sorting categories
Collections.sort(jsonValues, new Comparator<JSONObject>() {
private static final String KEY_NAME="term";
@Override
public int compare(JSONObject categoryItem, JSONObject t1) {
String valA=new String();
String valB =new String();
try{
valA=(String) categoryItem.get(KEY_NAME);
valB=(String) t1.get(KEY_NAME);
}
catch (JSONException e){
}
return valA.compareToIgnoreCase(valB);
}
});
for (int i = 0; i < category.length(); i++) {
sortedCategory.put(jsonValues.get(i));
}
for (int i = 0; i < sortedCategory.length(); i++) {
JSONObject hit = sortedCategory.getJSONObject(i);
String categoryItem=hit.getString("term");
mCategoryList.add(new CategoryItem(categoryItem));
}
/*mCategoryAdapter = new CategoryAdapter(CategoryActivity.this, mCategoryList);
mRecyclerView.setAdapter(mCategoryAdapter);
mCategoryAdapter.setOnItemClickListener(CategoryActivity.this);*/
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mRequestQueue.add(request);
}
private void addBannerAds(){
//Loop through the items array and place a new banner ad in every ith position in the item list
for(int i=0;i<=mCategoryList.size();i+= ITEMS_PER_AD){
final AdView adView = new AdView (CategoryActivity.this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(AD_UNIT_ID);
mCategoryList.add(i,adView);
}
}
// Sets up and loads the banner ads.
private void loadBannerAds() {
// Load the first banner ad in the items list (subsequent ads will be loaded automatically
// in sequence).
loadBannerAd(0);
}
//Loads the banner ads in the items list.
private void loadBannerAd(final int index) {
if (index >= mCategoryList.size()) {
return;
}
Object item = mCategoryList.get(index);
if (!(item instanceof AdView)) {
throw new ClassCastException("Expected item at index " + index + " to be a banner ad"
+ " ad.");
}
final AdView adView = (AdView) item;
// Set an AdListener on the AdView to wait for the previous banner ad
// to finish loading before loading the next ad in the items list.
adView.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
super.onAdLoaded();
// The previous banner ad loaded successfully, call this method again to
// load the next ad in the items list.
loadBannerAd(index + ITEMS_PER_AD);
}
@Override
public void onAdFailedToLoad(int errorCode) {
// The previous banner ad failed to load. Call this method again to load
// the next ad in the items list.
Log.e("MainActivity", "The previous banner ad failed to load. Attempting to"
+ " load the next banner ad in the items list.");
loadBannerAd(index + ITEMS_PER_AD);
}
});
// Load the banner ad.
adView.loadAd(new AdRequest.Builder().build());
}
}
CategoryAdapter:
public class CategoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
// A menu item view type.
private static final int MENU_ITEM_VIEW_TYPE = 0;
// The banner ad view type.
private static final int BANNER_AD_VIEW_TYPE = 1;
private Context mContext;
// The list of banner ads and category items.
private final List<Object> mCategoryList;
public CategoryAdapter(Context context, List<Object> CategoryList) {
mContext = context;
mCategoryList = CategoryList;
}
@Override
public int getItemCount() {
return mCategoryList.size();
}
public class CategoryViewHolder extends RecyclerView.ViewHolder {
public TextView mTextViewCategory;
public CategoryViewHolder(View itemView) {
super(itemView);
mTextViewCategory = itemView.findViewById(R.id.text_view_category);
}
}
public class AdViewHolder extends RecyclerView.ViewHolder {
AdViewHolder(View view) {
super(view);
}
}
/* Determines the view type for the given position*/
@Override
public int getItemViewType(int position) {
if (position % CategoryActivity.ITEMS_PER_AD == 0)
return BANNER_AD_VIEW_TYPE;
else
return MENU_ITEM_VIEW_TYPE;
}
/* Creates a new view for a menu item view or a banner ad view
* based on the viewType. This method is invoked by the layout manager*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType) {
case MENU_ITEM_VIEW_TYPE:
View menuItemLayoutView = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.category_item, viewGroup, false);
return new CategoryViewHolder(menuItemLayoutView);
case BANNER_AD_VIEW_TYPE:
// fall through
default:
View bannerLayoutView = LayoutInflater.from(
viewGroup.getContext()).inflate(R.layout.banner_ad_container,
viewGroup, false);
return new AdViewHolder(bannerLayoutView);
}
}
/** Replaces the content in the views that make up the menu item view and the
* * banner ad view. This method is invoked by the layout manager.*/
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case MENU_ITEM_VIEW_TYPE:
CategoryViewHolder categoryItemHolder = (CategoryViewHolder) holder;
CategoryItem currentItem = (CategoryItem) mCategoryList.get(position);
String categoryName=currentItem.getCategoryName();
categoryItemHolder.mTextViewCategory.setText(categoryName);
break;
case BANNER_AD_VIEW_TYPE:
// fall through
default:
AdViewHolder bannerHolder = (AdViewHolder) holder;
AdView adView = (AdView) mCategoryList.get(position);
ViewGroup adCardView = (ViewGroup) bannerHolder.itemView;
if (adCardView.getChildCount() > 0) {
adCardView.removeAllViews();
}
if (adView.getParent() != null) {
((ViewGroup) adView.getParent()).removeView(adView);
}
// Add the banner ad to the ad view.
adCardView.addView(adView);
}
}
请帮我解决一下这个。提前致谢。
最佳答案
@Override public int getItemViewType(int position) {
if (mCategoryList.get(position) instanceof AdView)
return BANNER_AD_VIEW_TYPE;
else return MENU_ITEM_VIEW_TYPE;
}