I have a TabLayout inside a TabLayout(second TabLayout is in a Fragment). Now when I switch tabs in the child TabLayout the recycler view is already loaded but it crashes when I scroll the recycler view. My recycler adapter uses 2 lists (2 different model classes) and 2 view holders. I am fetching the data from the firebase database.
Inner Fragment class that contains another TabLayout.
public class CommentaryFragment extends Fragment {
private TeamDetails mTeamADetails, mTeamBDetails;
private InningsScore mInningsScoreA, mInningsScoreB;
private ArrayList<PlayerDetails> mTeamASquad, mTeamBSquad;
private ArrayList<Commentary> mCommentaryListA, mCommentaryListB;
private List<TeamDetails> mTeamDetailsList;
private List<InningsScore> mInningsScoreList;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_commentary, container, false);
setupDatabase();
getDetailsFromDatabase();
setupTabIcons();
return view;
}
private void getDetailsFromDatabase() {
mDatabaseReferenceRound
.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
if (dataSnapshot.getKey().equals(getString(R.string.A))) {
mTeamADetails = dataSnapshot.child(getString(R.string.details)).getValue(TeamDetails.class);
for(DataSnapshot snapshot : dataSnapshot.child(getString(R.string.squad)).getChildren()) {
PlayerDetails playerDetails = snapshot.child(getString(R.string.details)).getValue(PlayerDetails.class);
mTeamASquad.add(playerDetails);
}
if (dataSnapshot.child(getString(R.string.batting)).exists()) {
mInningsScoreA = dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.total_score)).getValue(InningsScore.class);
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.commentary)).getChildren()) {
Commentary commentary = snapshot.getValue(Commentary.class);
mCommentaryListA.add(commentary);
}
}
}
if (dataSnapshot.getKey().equals(getString(R.string.B))) {
mTeamBDetails = dataSnapshot.child(getString(R.string.details)).getValue(TeamDetails.class);
for(DataSnapshot snapshot : dataSnapshot.child(getString(R.string.squad)).getChildren()) {
PlayerDetails playerDetails = snapshot.child(getString(R.string.details)).getValue(PlayerDetails.class);
mTeamBSquad.add(playerDetails);
}
if (dataSnapshot.child(getString(R.string.batting)).exists()) {
mInningsScoreB = dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.total_score)).getValue(InningsScore.class);
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.commentary)).getChildren()) {
Commentary commentary = snapshot.getValue(Commentary.class);
mCommentaryListB.add(commentary);
}
}
}
}
});
mDatabaseReferenceRound
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mTeamDetailsList.add(mTeamADetails);
mTeamDetailsList.add(mTeamBDetails);
mInningsScoreList.add(mInningsScoreA);
mInningsScoreList.add(mInningsScoreB);
updateWidgets();
}
}
}
This is a Full Fragment in the Child TabLayout that is causing the problem.
public class FullFragment extends Fragment {
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_full, container, false);
mCommentaryListA = new ArrayList<>();
mCommentaryListB = new ArrayList<>();
mEndOfOversListA = new ArrayList<>();
mEndOfOversListB = new ArrayList<>();
mTeamASquad = new ArrayList<>();
mTeamBSquad = new ArrayList<>();
if (getArguments() != null) {
mTournamentDetails = getArguments().getParcelable(getString(R.string.tournament_details));
mRoundName = getArguments().getString(getString(R.string.round_name));
mTeamReference = getArguments().getString(getString(R.string.teams));
}
mLinearLayoutManager = new LinearLayoutManager(getContext());
mUser = FirebaseAuth.getInstance().getCurrentUser();
mDatabaseReferenceRound = FirebaseDatabase.getInstance().getReference()
.child(getString(R.string.tournament))
.child(mUser.getUid())
.child(mTournamentDetails.getUUID())
.child(getString(R.string.rounds))
.child(mRoundName);
mRecyclerView = view.findViewById(R.id.full_recyclerView);
mRefreshLayout = view.findViewById(R.id.full_swipeRefresh);
mProgressBar = view.findViewById(R.id.full_progressBar);
getDetailsFromDatabase();
return view;
}
private void getDetailsFromDatabase() {
mRefreshLayout.setRefreshing(true);
mDatabaseReferenceRound
.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
if (dataSnapshot.getKey().equals(getString(R.string.match))) {
mCurrentBattingTeam = dataSnapshot.child(getString(R.string.current_batting_team)).getValue(String.class);
}
if (dataSnapshot.getKey().equals(getString(R.string.A))) {
mTeamADetails = dataSnapshot.child(getString(R.string.details)).getValue(TeamDetails.class);
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.squad)).getChildren()) {
PlayerDetails playerDetails = snapshot.child(getString(R.string.details)).getValue(PlayerDetails.class);
mTeamASquad.add(playerDetails);
}
if (dataSnapshot.child(getString(R.string.batting)).exists()) {
mCommentaryListA.clear();
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.commentary)).getChildren()) {
Commentary commentary = snapshot.getValue(Commentary.class);
mCommentaryListA.add(commentary);
}
mEndOfOversListA.clear();
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.end_of_over)).getChildren()) {
EndOfOver endOfOver = snapshot.getValue(EndOfOver.class);
mEndOfOversListA.add(endOfOver);
}
}
}
if (dataSnapshot.getKey().equals(getString(R.string.B))) {
mTeamBDetails = dataSnapshot.child(getString(R.string.details)).getValue(TeamDetails.class);
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.squad)).getChildren()) {
PlayerDetails playerDetails = snapshot.child(getString(R.string.details)).getValue(PlayerDetails.class);
mTeamBSquad.add(playerDetails);
}
if (dataSnapshot.child(getString(R.string.batting)).exists()) {
mCommentaryListB.clear();
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.commentary)).getChildren()) {
Commentary commentary = snapshot.getValue(Commentary.class);
mCommentaryListB.add(commentary);
}
mEndOfOversListB.clear();
for (DataSnapshot snapshot : dataSnapshot.child(getString(R.string.batting)).child(getString(R.string.end_of_over)).getChildren()) {
EndOfOver endOfOver = snapshot.getValue(EndOfOver.class);
mEndOfOversListB.add(endOfOver);
}
}
}
}
});
mDatabaseReferenceRound
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
updateWidgets();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void updateWidgets() {
if (mCurrentBattingTeam.equals(mTeamADetails.getUUID())) {
mAdapter = new SummaryCommentaryAdapter(getContext(), mCommentaryListA, mEndOfOversListA, mTeamADetails,
mTeamASquad, mTeamBSquad, getString(R.string.full));
} else {
mAdapter = new SummaryCommentaryAdapter(getContext(), mCommentaryListB, mEndOfOversListB, mTeamBDetails,
mTeamBSquad, mTeamASquad, getString(R.string.full));
}
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mRefreshLayout.setRefreshing(false);
}
This is the adapter class that uses 2 lists with 2 different ViewHolder Class.
public class SummaryCommentaryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private int mBallCounter = 0, mEndOverCounter = 0;
private int flag = 0; //FLAG = 0 BALLS // FLAG = 1 END OF OVER
private ArrayList<Commentary> commentaries = new ArrayList<>();
private Context mContext;
private List<Commentary> mCommentaryList;
private ArrayList<EndOfOver> mEndOfOversList;
private TeamDetails mTeamDetails;
private ArrayList<PlayerDetails> mBattingSquad, mBowlingSquad;
private List<String> typeOfOutList;
private String mFragmentName;
public SummaryCommentaryAdapter(Context context, List<Commentary> commentaryList, ArrayList<EndOfOver> endOfOversList,
TeamDetails teamDetails, ArrayList<PlayerDetails> battingSquad,
ArrayList<PlayerDetails> bowlingSquad, String fragmentName) {
mContext = context;
mCommentaryList = commentaryList;
mEndOfOversList = endOfOversList;
mTeamDetails = teamDetails;
mBattingSquad = battingSquad;
mBowlingSquad = bowlingSquad;
mFragmentName = fragmentName;
typeOfOutList = Arrays.asList(mContext.getResources().getStringArray(R.array.types_of_out));
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (flag == 0) {
View view = LayoutInflater.from(mContext).inflate(R.layout.summary_commentary_detail, parent, false);
return new BallsViewHolder(view);
} else {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_end_of_over, parent, false);
return new EndOfOverViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (flag == 0) {
if (mFragmentName.equals(mContext.getString(R.string.summary))) {
Commentary commentary = mCommentaryList.get(mBallCounter);
((BallsViewHolder) holder).mBallNumber.setText(String.format("%.1f", commentary.getBallNumber()));
//CHANGE BACKGROUND OF mSCORE ACCORDING TO THE RUNS SCORED.
if (commentary.getRuns().equals("0")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), " no run"));
} else if (commentary.getRuns().equals("1")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), commentary.getRuns() + " run"));
} else if (commentary.getRuns().equals("2") || commentary.getRuns().equals("3")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), commentary.getRuns() + " " + mContext.getString(R.string.runs)));
} else if (commentary.getRuns().equals("4")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setTypeface(Typeface.DEFAULT_BOLD);
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), "FOUR"));
} else if (commentary.getRuns().equals("6")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setTypeface(Typeface.DEFAULT_BOLD);
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), "SIX"));
} else if (commentary.getRuns().contains("WD")) {
String a = String.valueOf(commentary.getRuns().charAt(0));
((BallsViewHolder) holder).mScore.setText("WD");
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(),
"(wide ball), " + a + "runs"));
} else if (commentary.getRuns().contains("NB")) {
String a = String.valueOf(commentary.getRuns().charAt(0));
((BallsViewHolder) holder).mScore.setText("NB");
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(),
"(no ball), " + a + "runs"));
} else if (commentary.getRuns().contains("LB")) {
String a = String.valueOf(commentary.getRuns().charAt(0));
((BallsViewHolder) holder).mScore.setText("LB");
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(),
"(leg bye), " + a + "runs"));
} else if (commentary.getRuns().equals(typeOfOutList.get(0)) || commentary.getRuns().equals(typeOfOutList.get(1))
|| commentary.getRuns().equals(typeOfOutList.get(2)) || commentary.getRuns().equals(typeOfOutList.get(3))
|| commentary.getRuns().equals(typeOfOutList.get(4)) || commentary.getRuns().equals(typeOfOutList.get(5))
|| commentary.getRuns().equals(typeOfOutList.get(6)) || commentary.getRuns().equals(typeOfOutList.get(7))
|| commentary.getRuns().equals(typeOfOutList.get(8)) || commentary.getRuns().equals(typeOfOutList.get(9))) {
((BallsViewHolder) holder).mScore.setText("W");
((BallsViewHolder) holder).mSentence.setTypeface(Typeface.DEFAULT_BOLD);
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(),
"OUT, " + commentary.getRuns()));
((BallsViewHolder) holder).mExtraDetails.setVisibility(View.VISIBLE);
((BallsViewHolder) holder).mExtraDetails.setText(getWicketDetail(commentary.getWicket()));
} else if (commentary.getRuns().contains("B")) {
String a = String.valueOf(commentary.getRuns().charAt(0));
((BallsViewHolder) holder).mScore.setText("B");
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(),
"(bye), " + a + "runs"));
} else {
((BallsViewHolder) holder).mScore.setText("W");
((BallsViewHolder) holder).mSentence.setTypeface(Typeface.DEFAULT_BOLD);
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(),
"OUT, " + commentary.getRuns()));
((BallsViewHolder) holder).mExtraDetails.setVisibility(View.VISIBLE);
((BallsViewHolder) holder).mExtraDetails.setText(getWicketDetail(commentary.getWicket()));
}
flag = 0;
} else if (mFragmentName.equals(mContext.getString(R.string.boundary))) {
Commentary commentary = commentaries.get(position);
if (commentary.isBoundary()) {
if (commentary.getRuns().equals("4")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setTypeface(Typeface.DEFAULT_BOLD);
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), "FOUR"));
} else if (commentary.getRuns().equals("6")) {
((BallsViewHolder) holder).mScore.setText(commentary.getRuns());
((BallsViewHolder) holder).mSentence.setTypeface(Typeface.DEFAULT_BOLD);
((BallsViewHolder) holder).mSentence.setText(mContext.getString(R.string.summary_commentary_placeholder,
commentary.getBowler().getName(), commentary.getBatsman().getName(), "SIX"));
}
}
flag = 0;
}
if ((mCommentaryList.get(mBallCounter).getBallNumber() % 1) >= 0.58) {
flag = 1;
}
mBallCounter++;
} else {
// END OF OVER.
EndOfOver endOfOver = mEndOfOversList.get(mEndOverCounter);
((EndOfOverViewHolder) holder).mOverNumber.setText(mContext.getString(R.string.end_over_placeholder, endOfOver.getOverNumber()));
((EndOfOverViewHolder) holder).mRunsWickets.setText(mContext.getString(R.string.runs_wickets_placeholder, endOfOver.getOverRuns(),
endOfOver.getOverWickets()));
((EndOfOverViewHolder) holder).mTeamStat.setText(mContext.getString(R.string.team_stat_placeholder, mTeamDetails.getName(),
endOfOver.getTeamRuns(), endOfOver.getTeamWickets()));
for (int k = 0; k < mBattingSquad.size(); k++) {
if (endOfOver.getBatsman1().getUUID().equals(mBattingSquad.get(k).getUUID())) {
((EndOfOverViewHolder) holder).mPlayerAName.setText(mBattingSquad.get(k).getName());
((EndOfOverViewHolder) holder).mPlayerAStat.setText(mContext.getString(R.string.individual_runs_placeholder,
endOfOver.getBatsman1().getRuns(), endOfOver.getBatsman1().getBalls()));
break;
}
}
for (int k = 0; k < mBattingSquad.size(); k++) {
if (endOfOver.getBatsman2().getUUID().equals(mBattingSquad.get(k).getUUID())) {
((EndOfOverViewHolder) holder).mPlayerBName.setText(mBattingSquad.get(k).getName());
((EndOfOverViewHolder) holder).mPlayerBStat.setText(mContext.getString(R.string.individual_runs_placeholder,
endOfOver.getBatsman2().getRuns(), endOfOver.getBatsman2().getBalls()));
break;
}
}
for (int k = 0; k < mBowlingSquad.size(); k++) {
if (endOfOver.getBowler().getUUID().equals(mBowlingSquad.get(k).getUUID())) {
((EndOfOverViewHolder) holder).mBowlerName.setText(mBowlingSquad.get(k).getName());
((EndOfOverViewHolder) holder).mBowlerStat.setText(mContext.getString(R.string.bowler_stats_placeholder,
endOfOver.getBowler().getOvers(), endOfOver.getBowler().getMaiden(), endOfOver.getBowler().getRuns(),
endOfOver.getBowler().getWickets()));
break;
}
}
mEndOverCounter++;
flag = 0;
}
}
@Override
public int getItemCount() {
return (mCommentaryList.size() + mEndOfOversList.size());
}
static class BallsViewHolder extends RecyclerView.ViewHolder {
private TextView mBallNumber, mScore, mSentence, mExtraDetails;
public BallsViewHolder(@NonNull View itemView) {
super(itemView);
mBallNumber = itemView.findViewById(R.id.commentary_ballNumber);
mScore = itemView.findViewById(R.id.commentary_score);
mSentence = itemView.findViewById(R.id.commentary_sentence);
mExtraDetails = itemView.findViewById(R.id.commentary_extraDetails);
}
}
static class EndOfOverViewHolder extends RecyclerView.ViewHolder {
private TextView mOverNumber, mRunsWickets, mTeamStat, mPlayerAName, mPlayerBName, mPlayerAStat, mPlayerBStat;
private TextView mBowlerName, mBowlerStat;
public EndOfOverViewHolder(@NonNull View itemView) {
super(itemView);
mOverNumber = itemView.findViewById(R.id.endOfOver_overNumber);
mRunsWickets = itemView.findViewById(R.id.endOfOver_runsWickets);
mTeamStat = itemView.findViewById(R.id.endOfOver_teamStat);
mPlayerAName = itemView.findViewById(R.id.endOfOver_playerAName);
mPlayerAStat = itemView.findViewById(R.id.endOfOver_playerAStat);
mPlayerBName = itemView.findViewById(R.id.endOfOver_playerBName);
mPlayerBStat = itemView.findViewById(R.id.endOfOver_playerBStat);
mBowlerName = itemView.findViewById(R.id.endOfOver_bowlerName);
mBowlerStat = itemView.findViewById(R.id.endOfOver_bowlerStat);
}
}
}
Logcat details of the error.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.k3ptechnologies.undefeatdsports, PID: 9087
java.lang.ClassCastException: com.k3ptechnologies.undefeatdsports.Matches.Scorecard.MatchFragments.Summary.SummaryCommentaryAdapter$BallsViewHolder cannot be cast to com.k3ptechnologies.undefeatdsports.Matches.Scorecard.MatchFragments.Summary.SummaryCommentaryAdapter$EndOfOverViewHolder
at com.k3ptechnologies.undefeatdsports.Matches.Scorecard.MatchFragments.Summary.SummaryCommentaryAdapter.onBindViewHolder(SummaryCommentaryAdapter.java:194)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)