错误:不兼容的类型:无法转换为RecyclerView

时间:2017-05-21 05:48:46

标签: android android-recyclerview android-viewholder native-ads

我正在尝试按照Admob车库教程在RecyclerView中实施原生广告。但我收到错误说"错误:不兼容的类型:命中无法转换为NativeExpressAdView"

在setUpAndLoadNativeExpressAds中说" Casting' hit.get(i)'到#NativeDpressAdView'是多余的。此检查报告不必要的演员表达。"

(错误在onBindViewHolder上,注释// ERROR Lines //为了更好地理解。)

这是我的班级

package com.example.wallpaper.app.ui.adapter;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.example.wallpaper.app.model.Hit;
import com.example.wallpaper.app.model.Pic;
import com.example.wallpaper.app.ui.DiscoverFragment;
import com.example.wallpaper.app.ui.PicDetail;
import com.example.wallpaper.app.R;
import com.example.wallpaper.app.ui.util.WallpaperViewHolder;
import com.google.android.gms.ads.NativeExpressAdView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;

public class WallpaperAdapter extends RecyclerView.Adapter<WallpaperViewHolder> {

private List<Hit> hit;
private Context context;
public int width;
public int height;
public static final int IMAGE__LIST_ITEMS = 0;
public static final int NATIVE_EXPRESS_AD_VIEW_TYPE = 1;

public WallpaperAdapter (Context context){
    this.context=context;
    this.hit=new ArrayList<>();
}

public class NativeExpressAdViewHolder extends WallpaparViewHolder {

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

@Override
public int getItemViewType(int position)
{
    return (position % DiscoverFragment.ITEMS_PER_AD == 0)? NATIVE_EXPRESS_AD_VIEW_TYPE : IMAGE__LIST_ITEMS;
}

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

@Override
public WallpaperViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    switch (viewType){
        case IMAGE__LIST_ITEMS:
            View itemView = LayoutInflater.from(context).inflate(R.layout.wallp_item, null);
            final WallpaperViewHolder rcv=new WallpaperViewHolder(itemView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = rcv.getAdapterPosition();
                    Intent intent = new Intent(context, PicDetail.class);
                    intent.putExtra(PicDetail.EXTRA_PIC, hit.get(position));
                    context.startActivity(intent);
                }
            });
            return rcv;

        case NATIVE_EXPRESS_AD_VIEW_TYPE:
        default:
            View nativeExpressLayoutView = LayoutInflater.from(
                    viewGroup.getContext()).inflate(R.layout.native_express_ad_container,
                    viewGroup, false);
            return new WallpaperViewHolder(nativeExpressLayoutView);
    }
}

@Override
public void onBindViewHolder(WallpaperViewHolder holder, int position) {
    int viewType = getItemViewType(position);
    switch (viewType){

        case IMAGE__LIST_ITEMS:
            Hit photo = this.hit.get(position);
            RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) holder.discWallp.getLayoutParams();
            float height =photo.getPreviewHeight();
            float width = photo.getPreviewWidth();
            float ratio =  height/width ;
            rlp.height = (int) (rlp.width * ratio);
            holder.discWallp.setLayoutParams(rlp);
            holder.discWallp.setRatio(ratio);
            Picasso.with(context)
                    .load(photo.getWebformatURL())
                    .placeholder(R.drawable.plh)
                    .into(holder.discWallp);
            break;

        case NATIVE_EXPRESS_AD_VIEW_TYPE:
        default:

         **// ERROR Lines// // ERROR Lines// // ERROR Lines// // ERROR Lines//** 

            NativeExpressAdViewHolder nativeExpressHolder;
            nativeExpressHolder = (NativeExpressAdViewHolder) holder;
            NativeExpressAdView adView;
            adView = (NativeExpressAdView) hit.get(position);

        **// ERROR Lines// // ERROR Lines// // ERROR Lines// // ERROR Lines//** 

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

public void setPicList(Pic picList)
{
    if(picList.getHits()!=null)
        this.hit.addAll(picList.getHits());
    notifyDataSetChanged();
}
}

片段在这里

public class DiscoverFragment extends Fragment implements AsyncResponse {

public WallpaperAdapter WallpaperAdapter ;
public RecyclerView recyclerView;
public NetworkUtilities networkUtilities;
public EndlessRecyclerViewScrollListener scrollListener;
public WallpService wallpService;
public int column_no;
public static final int ITEMS_PER_AD = 4;
// List of Native Express ads and MenuItems that populate the RecyclerView.
private ArrayList<Object> hit  = new ArrayList<>();
private static final int NATIVE_EXPRESS_AD_HEIGHT = 150;
// The Native Express ad unit ID.
private static final String AD_UNIT_ID = "ca-app-pub-xxxxxxxxxx543";

public static DiscoverFragment newInstance() {
    DiscoverFragment fragment = new DiscoverFragment();
    Bundle args = new Bundle();
    fragment.setArguments(args);
    return fragment;
}


public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    networkUtilities = new NetworkUtilities(getActivity());

    recyclerView = (RecyclerView) getActivity().findViewById(R.id.discRecView);
    recyclerView.setHasFixedSize(true);

    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);

    loadNextDataFromApi(1);
    addNativeExpressAds();
    setUpAndLoadNativeExpressAds();
}

private void addNativeExpressAds() {

    // Loop through the items array and place a new Native Express ad in every ith position in
    // the items List.
    for (int i = 0; i <= hit.size(); i += ITEMS_PER_AD) {
        final NativeExpressAdView adView = new NativeExpressAdView(getActivity()
                .getApplicationContext());
        hit.add(i, adView);
    }
}

private void setUpAndLoadNativeExpressAds() {
    // Use a Runnable to ensure that the RecyclerView has been laid out before setting the
    // ad size for the Native Express ad. This allows us to set the Native Express ad's
    // width to match the full width of the RecyclerView.
    recyclerView.post(new Runnable() {
        @Override
        public void run() {
            final float scale = getActivity().getApplicationContext()
                    .getResources().getDisplayMetrics().density;

            // Set the ad size and ad unit ID for each Native Express ad in the items list.
            for (int i = 0; i <= hit.size(); i += ITEMS_PER_AD) {
                final NativeExpressAdView adView =
                        (NativeExpressAdView) hit.get(i);
                final CardView cardView = (CardView) getActivity().findViewById(R.id.ad_card_view);
                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);
            }

            // Load the first Native Express ad in the items list.
            loadNativeExpressAd(0);
        }
    });
}

private void loadNativeExpressAd(final int index) {

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

    Object item = hit.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;

    // Set an AdListener on the NativeExpressAdView to wait for the previous Native Express 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 Native Express ad loaded successfully, call this method again to
            // load the next ad in the items list.
            loadNativeExpressAd(index + ITEMS_PER_AD);
        }

        @Override
        public void onAdFailedToLoad(int errorCode) {
            // The previous Native Express ad failed to load. Call this method again to load
            // the next ad in the items list.
            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);
        }
    });

    // Load the Native Express ad.
    adView.loadAd(new AdRequest.Builder().build());
}


@Override
public void onResume() {
    super.onResume();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    if(!networkUtilities.isInternetConnectionPresent()){
        return  inflater.inflate(R.layout.fragment_no_internet, container, false);
    }
    else{
        View view = inflater.inflate(R.layout.fragment_discover, container, false);
        recyclerView=(RecyclerView) view.findViewById(R.id.discRecView);
        recyclerView.setHasFixedSize(true);
        checkScreenSize();
        StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(column_no,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(staggeredGridLayoutManager);
        scrollListener = new EndlessRecyclerViewScrollListener(staggeredGridLayoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                loadNextDataFromApi(page);
            }
        };
        scrollListener.resetState();
        recyclerView.addOnScrollListener(scrollListener);
        WallpaperAdapter = new WallpaperAdapter (getActivity());
        recyclerView.setAdapter(WallpaperAdapter );
        return view;
    }
}

@Override
public void processFinish(Pic output) {

    if (output.getHits() != null) {
        WallpaperAdapter .setPicList(output);
    }

}

public void loadNextDataFromApi(int offset) {
    String type=getResources().getString(R.string.popular);
    wallpService = new WallpService(networkUtilities, getActivity(), this,offset,type);
    wallpService.loadWallp();
}
public void checkScreenSize() {

    int screenSize = getResources().getConfiguration().screenLayout &
            Configuration.SCREENLAYOUT_SIZE_MASK;

    switch (screenSize) {
        case Configuration.SCREENLAYOUT_SIZE_XLARGE:

            column_no = 3;
            break;
        case Configuration.SCREENLAYOUT_SIZE_UNDEFINED:
            column_no = 2;
            break;
        case Configuration.SCREENLAYOUT_SIZE_LARGE:
            column_no = 2;
            break;
        case Configuration.SCREENLAYOUT_SIZE_NORMAL:
            column_no = 1;
            break;
        case Configuration.SCREENLAYOUT_SIZE_SMALL:
            column_no = 1;
            break;
        default:
            column_no = 1;
    }
}
}

1 个答案:

答案 0 :(得分:0)

您的hit变量属于List<Hit>类型。所以它显然只有Hit个对象。

此代码:

adView = (NativeExpressAdView) hit.get(position);

会失败,因为该对象不可能是NativeExpressAdView

要实现这一目标,您需要将列表设为Object类型,并在NativeExpressAdView对象中实际广告,类似于其完成方式here。我建议下载并播放这个示例,并将其中的部分移动到您的代码中以使其正常工作。