我有一个应用程序,我在其中从 Firebase 的实时数据库中获取数据,然后在 RecyclerView 中使用它。然后我浏览了教程并通过更新 recyclerAdapter 将原生广告添加为 recyclerview 中的项目。一切正常。但是,每当我在运行应用程序的情况下更改 firebase 中的数据时,它就会崩溃。这是我的活动和适配器
public class MainActivity extends AppCompatActivity implements BaseSliderView.OnSliderClickListener
, ViewPagerEx.OnPageChangeListener{
//Firebase Related
private DatabaseReference mMainDatabase;
private DatabaseReference mMatchesListDatabase;
private SliderLayout mMainSlider;
private DefaultSliderView defaultSliderView;
private ArrayList<String> adUrl = new ArrayList<>();
private TextView mUpdateTv;
private ProgressDialog mProgressDialog;
//Native Express ad related
// A Native Express ad is placed in every nth position in the RecyclerView.
public static final int ITEMS_PER_AD = 4;
// The Native Express ad height.
private static final int NATIVE_EXPRESS_AD_HEIGHT = 132;
// The Native Express ad unit ID.
private static final String AD_UNIT_ID = "ca-app-pub-9016057534718300/6254629155";
// The RecyclerView that holds and displays Native Express ads and menu items.
private RecyclerView mRecyclerView;
// List of Native Express ads and MenuItems that populate the RecyclerView.
private List<Object> mRecyclerViewItems = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Admob related important code*/
AdView mAdView = (AdView) findViewById(R.id.adView_main);
com.google.android.gms.ads.AdRequest adRequest = new com.google.android.gms.ads.AdRequest.Builder().build();
mAdView.loadAd(adRequest);
mUpdateTv = (TextView) findViewById(R.id.updates_tv);
mMatchesListDatabase = FirebaseDatabase.getInstance().getReference().child("matcheslist");
mRecyclerView = (RecyclerView) findViewById(R.id.main_matches_list);
// Use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView.
mRecyclerView.setHasFixedSize(true);
// Specify a linear layout manager.
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
// Update the RecyclerView item's list with menu items and Native Express ads.
addMatchesListFromFirebase();
//addNativeExpressAds();
//setUpAndLoadNativeExpressAds();
//Setup the progress dialog that is displayed later when authenticating with Firebase
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle("Loading...");
mProgressDialog.setMessage("Please wait while we load data for you!");
mProgressDialog.setCancelable(false);
mMainSlider = (SliderLayout) findViewById(R.id.main_slider);
mMainDatabase = FirebaseDatabase.getInstance().getReference();
mMainDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
mProgressDialog.show();
//Match Updates Section of firebase database
String update = "";
for(DataSnapshot eachMatchUpdate: dataSnapshot.child("matchupdates").getChildren()) {
update = update + " * " + eachMatchUpdate.getValue().toString();
}
mUpdateTv.setText(update);
//Ads Section of firebase database
adUrl.clear();
//Data for Slider images
for (DataSnapshot eachAdUrl : dataSnapshot.child("ads").getChildren()) {
adUrl.add(String.valueOf(eachAdUrl.getValue()));
}
//To shuffle the ads
Collections.shuffle(adUrl);
for (int i = 0; i < adUrl.size(); i++) {
defaultSliderView = new DefaultSliderView(MainActivity.this);
//Initialize a SliderLayout
defaultSliderView
.image(adUrl.get(i))
.setScaleType(BaseSliderView.ScaleType.Fit)
.setOnSliderClickListener(MainActivity.this);
mMainSlider.addSlider(defaultSliderView);
}
mProgressDialog.dismiss();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
// Specify an adapter.
RecyclerView.Adapter adapter = new MainActivityAdapter(MainActivity.this, mRecyclerViewItems);
mRecyclerView.setAdapter(adapter);
mMainSlider.setPresetTransformer(SliderLayout.Transformer.DepthPage);
mMainSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
mMainSlider.setCustomAnimation(new DescriptionAnimation());
mMainSlider.setDuration(4000);
mMainSlider.addOnPageChangeListener(this);
}
private void addMatchesListFromFirebase() {
mMatchesListDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot eachMatch : dataSnapshot.getChildren()) {
MatchesList match = eachMatch.getValue(MatchesList.class);
mRecyclerViewItems.add(match);
}
addNativeExpressAds();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
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 <= mRecyclerViewItems.size(); i += ITEMS_PER_AD) {
final NativeExpressAdView adView = new NativeExpressAdView(this);
//Extra here
adView.setAdUnitId(AD_UNIT_ID);
mRecyclerViewItems.add(i, adView);
}
mRecyclerView.post(new Runnable() {
@Override
public void run() {
final float scale = MainActivity.this.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 <= mRecyclerViewItems.size(); i += ITEMS_PER_AD) {
final NativeExpressAdView adView =
(NativeExpressAdView) mRecyclerViewItems.get(i);
final CardView cardView = (CardView) findViewById(R.id.ad_card_view);
final CardView cardViewMatchContainer = (CardView) findViewById(R.id.match_card_view);
final int adWidth = cardView.getWidth() - cardView.getPaddingLeft()
- cardView.getPaddingRight();
Log.d("cardviewheight", String.valueOf((int)(cardViewMatchContainer.getHeight()/scale)));
AdSize adSize = new AdSize((int) (adWidth / scale), NATIVE_EXPRESS_AD_HEIGHT);
adView.setAdSize(adSize);
adView.loadAd(new AdRequest.Builder().build());
}
}
});
}
适配器代码
public class MainActivityAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
// A menu item view type.
private static final int MATCH_ITEM_VIEW_TYPE = 0;
// The Native Express ad view type.
private static final int NATIVE_EXPRESS_AD_VIEW_TYPE = 1;
// An Activity's Context.
private final Context mContext;
// The list of Native Express ads and menu items.
private final List<Object> mRecyclerViewItems;
public MainActivityAdapter(Context context, List<Object> recyclerViewItems) {
mContext = context;
mRecyclerViewItems = recyclerViewItems;
}
/**
* Creates a new view for a menu item view or a Native Express 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 NATIVE_EXPRESS_AD_VIEW_TYPE :
View nativeExpressLayoutView = LayoutInflater.from(
viewGroup.getContext()).inflate(R.layout.native_express_ad_container,
viewGroup, false);
return new NativeExpressAdViewHolder(nativeExpressLayoutView);
case MATCH_ITEM_VIEW_TYPE :
// fall through
default:View matchItemLayoutView = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.match_item_container, viewGroup, false);
return new MatchItemViewHolder(matchItemLayoutView);
}
}
/**
* Replaces the content in the views that make up the menu item view and the
* Native Express 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 NATIVE_EXPRESS_AD_VIEW_TYPE:
NativeExpressAdViewHolder nativeExpressHolder =
(NativeExpressAdViewHolder) holder;
NativeExpressAdView adView =
(NativeExpressAdView) mRecyclerViewItems.get(position);
ViewGroup adCardView = (ViewGroup) nativeExpressHolder.itemView;
// The NativeExpressAdViewHolder recycled by the RecyclerView may be a different
// instance than the one used previously for this position. Clear the
// NativeExpressAdViewHolder of any subviews in case it has a different
// AdView associated with it, and make sure the AdView for this position doesn't
// already have a parent of a different recycled NativeExpressAdViewHolder.
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);
break;
case MATCH_ITEM_VIEW_TYPE:
default:
MatchItemViewHolder matchItemHolder = (MatchItemViewHolder) holder;
MatchesList match = (MatchesList) mRecyclerViewItems.get(position);
// This is used to pass the key which is creating some problems
matchItemHolder.itemView.setTag(position);
matchItemHolder.setKeys(match);
matchItemHolder.mSeriesName.setText(match.getSeries());
matchItemHolder.mTeam1Name.setText(match.getTeam1());
matchItemHolder.mTeam2Name.setText(match.getTeam2());
matchItemHolder.mAddTime.setText("Added " + match.getTime() + " IST");
Picasso.with(matchItemHolder.viewholderContext)
.load(match.getImaget1())
//.placeholder(R.drawable.noimage)
.centerCrop()
.resize(256,256)
.into(matchItemHolder.mTeam1Image);
Picasso.with(matchItemHolder.viewholderContext)
.load(match.getImaget2())
//.placeholder(R.drawable.noimage)
.centerCrop()
.resize(256,256)
.into(matchItemHolder.mTeam2Image);
break;
}
}
@Override
public int getItemCount() {
return mRecyclerViewItems.size();
}
/**
* Determines the view type for the given position.
*/
@Override
public int getItemViewType(int position) {
return (position % MainActivity.ITEMS_PER_AD == 0) ? NATIVE_EXPRESS_AD_VIEW_TYPE
: MATCH_ITEM_VIEW_TYPE;
}
public class MatchItemViewHolder extends RecyclerView.ViewHolder {
private TextView mSeriesName, mTeam1Name, mTeam2Name, mAddTime;
private ImageView mTeam1Image, mTeam2Image;
private Context viewholderContext;
private ArrayList<String> tempKeys = new ArrayList<>();
private MatchesList tempMatchForKey;
private void setKeys(MatchesList key) {
tempMatchForKey = key;
}
public MatchItemViewHolder(final View itemView) {
super(itemView);
viewholderContext = itemView.getContext();
mSeriesName = (TextView) itemView.findViewById(R.id.series_name);
mTeam1Name = (TextView) itemView.findViewById(R.id.team1_name);
mTeam2Name = (TextView) itemView.findViewById(R.id.team2_name);
mAddTime = (TextView) itemView.findViewById(R.id.add_time);
mTeam1Image = (ImageView) itemView.findViewById(R.id.team1_image);
mTeam2Image = (ImageView) itemView.findViewById(R.id.team2_image);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// This is used to pass the key which is creating some problems
int position=(Integer)v.getTag();
Intent singleMatchIntent = new Intent(viewholderContext, MatchActivity.class);
singleMatchIntent.putExtra("MATCHSELECTIONKEY", tempMatchForKey.getKey());
viewholderContext.startActivity(singleMatchIntent);
}
});
}
}
public class NativeExpressAdViewHolder extends RecyclerView.ViewHolder {
NativeExpressAdViewHolder(View view) {
super(view);
}
}
}
Logcat 窗口
FATAL EXCEPTION: main
Process: in.protechlabz.www.dream11predictionguru, PID: 9397
java.lang.ClassCastException: com.google.android.gms.ads.NativeExpressAdView cannot be cast to in.protechlabz.www.dream11predictionguru.model.MatchesList
at in.protechlabz.www.dream11predictionguru.adapters.MainActivityAdapter.onBindViewHolder(MainActivityAdapter.java:107)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6356)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6389)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5335)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5598)
at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:282)
at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:336)
at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:349)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:356)
at android.support.v7.widget.GapWorker.run(GapWorker.java:387)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)