huanghaibin-dev/CalendarView · warning
e.printStackTrace()
Error message
e.printStackTrace()
What it means
MonthViewPager.instantiateItem reflectively constructs the configured month view class. On failure it prints the stack trace and returns a DefaultMonthView as a fallback, so the calendar still renders but the custom month view silently never appears.
Solutions
- Give the class a public constructor taking Context and keep it lightweight (no casting to Activity).
- Make the class top-level or static nested and public.
- Check logcat for the printed exception (NoSuchMethodException, InvocationTargetException, etc.).
- Add a keep rule for the class and its constructor.
- If a constructor throws, wrap its body in try/catch or move fragile initialization to onMeasure/onDraw.
Example fix
// before
public CustomMonthView(Context context) {
super(context);
((MyActivity) context).getData(); // throws ClassCastException at instantiation
}
// after
public CustomMonthView(Context context) {
super(context);
// defer data access; obtain via listener/setup after construction
} Defensive patterns
Strategy: fallback
Validate before calling
Class<?> cls = Class.forName("com.example.CustomMonthView");
cls.getConstructor(Context.class); // throws early if reflection will fail at bind time
Type guard
static boolean instantiableMonthView(Class<?> cls) {
try {
return BaseMonthView.class.isAssignableFrom(cls)
&& cls.getConstructor(Context.class) != null;
} catch (NoSuchMethodException e) { return false; }
} Try / catch
// The library already falls back to DefaultMonthView; add your own guard:
try {
Constructor<?> ctor = CustomMonthView.class.getConstructor(Context.class);
ctor.newInstance(context);
} catch (Throwable t) {
Log.w("Calendar", "CustomMonthView unavailable, default used", t);
} Prevention
- Avoid casting Context to Activity inside the view constructor.
- Declare the class public and static; never anonymous or inner.
- Do heavy work in setup()/onDraw, not the constructor.
- Add a ProGuard keep rule for the constructor signature.
- Visually verify the custom month view in a release build.
When it happens
Trigger: Custom month view class configured via app:calendar_month_view_class lacks a public (Context) constructor, is a non-static inner class, throws in its constructor, or fails newInstance due to access/obfuscation issues.
Common situations: Declaring the custom view as an inner class of an Activity; constructor doing context.cast to Activity and throwing; ProGuard stripping the constructor; class instantiated during RecyclerView binding right after app start.
Related errors
AI-assisted analysis of huanghaibin-dev/CalendarView@f5479ea3ba (2026-09-11).
Data as JSON: /api/errors/3e43931df20ddbba.
Report an issue: GitHub.
Appendix: source
Thrown at calendarview/src/main/java/com/haibin/calendarview/MonthViewPager.java:624
return isUpdateMonthView ? POSITION_NONE : super.getItemPosition(object);
}
@Override
public boolean isViewFromObject(View view, @NonNull Object object) {
return view.equals(object);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
int year = (position + mDelegate.getMinYearMonth() - 1) / 12 + mDelegate.getMinYear();
int month = (position + mDelegate.getMinYearMonth() - 1) % 12 + 1;
BaseMonthView view;
try {
Constructor constructor = mDelegate.getMonthViewClass().getConstructor(Context.class);
view = (BaseMonthView) constructor.newInstance(getContext());
} catch (Exception e) {
e.printStackTrace();
return new DefaultMonthView(getContext());
}
view.mMonthViewPager = MonthViewPager.this;
view.mParentLayout = mParentLayout;
view.setup(mDelegate);
view.setTag(position);
view.initMonthWithDate(year, month);
view.setSelectedCalendar(mDelegate.mSelectedCalendar);
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
BaseView view = (BaseView) object;
view.onDestroy();
container.removeView(view);
}View on GitHub (pinned to f5479ea3ba)