huanghaibin-dev/CalendarView · warning
e.printStackTrace()
Error message
e.printStackTrace()
What it means
YearViewAdapter.onCreateDefaultViewHolder reflectively instantiates the configured custom year view. On failure it prints the stack trace and falls back to DefaultYearView, so the year picker renders with default styling instead of the user's custom year view.
Solutions
- Declare a public constructor taking Context.
- Make the class public, top-level or static nested, extending BaseYearView.
- Inspect logcat for the printed reflection exception.
- Add -keep class com.example.CustomYearView { public <init>(android.content.Context); } to proguard-rules.pro.
- Confirm app:calendar_year_view_class matches the exact fully-qualified name.
Example fix
// before
app:calendar_year_view_class="com.app.YearPage" // class has no (Context) ctor
// after
// public class YearPage extends BaseYearView { public YearPage(Context c){super(c);} }
app:calendar_year_view_class="com.app.YearPage" Defensive patterns
Strategy: fallback
Validate before calling
Class<?> cls = Class.forName("com.example.CustomYearView");
cls.getConstructor(Context.class);
Type guard
static boolean instantiableYearView(Class<?> cls) {
try {
return BaseYearView.class.isAssignableFrom(cls)
&& cls.getConstructor(Context.class) != null;
} catch (NoSuchMethodException e) { return false; }
} Try / catch
// Library falls back to DefaultYearView; preflight:
try {
CustomYearView.class.getConstructor(Context.class).newInstance(context);
} catch (Throwable t) {
Log.w("Calendar", "CustomYearView failed; DefaultYearView will be used", t);
} Prevention
- Make the custom year view public with a Context-only constructor.
- Add proguard keep rules; verify in release build.
- After refactors, re-check app:calendar_year_view_class in XML.
- Open the year picker once in CI smoke tests to catch silent fallbacks.
When it happens
Trigger: Class from app:calendar_year_view_class has no public (Context) constructor, is a non-static inner class, throws during construction, or is stripped/renamed by code shrinking.
Common situations: Custom YearView written as an Activity inner class; R8 minified release builds without keep rules; constructor expecting an Activity context; wrong XML class path after refactoring.
Related errors
AI-assisted analysis of huanghaibin-dev/CalendarView@f5479ea3ba (2026-09-11).
Data as JSON: /api/errors/c50705a1fc5509ae.
Report an issue: GitHub.
Appendix: source
Thrown at calendarview/src/main/java/com/haibin/calendarview/YearViewAdapter.java:55
}
final void setYearViewSize(int width, int height) {
this.mItemWidth = width;
this.mItemHeight = height;
}
@Override
RecyclerView.ViewHolder onCreateDefaultViewHolder(ViewGroup parent, int type) {
YearView yearView;
if (TextUtils.isEmpty(mDelegate.getYearViewClassPath())) {
yearView = new DefaultYearView(mContext);
} else {
try {
Constructor constructor = mDelegate.getYearViewClass().getConstructor(Context.class);
yearView = (YearView) constructor.newInstance(mContext);
} catch (Exception e) {
e.printStackTrace();
yearView = new DefaultYearView(mContext);
}
}
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,
RecyclerView.LayoutParams.MATCH_PARENT);
yearView.setLayoutParams(params);
return new YearViewHolder(yearView, mDelegate);
}
@Override
void onBindViewHolder(RecyclerView.ViewHolder holder, Month item, int position) {
YearViewHolder h = (YearViewHolder) holder;
YearView view = h.mYearView;
view.init(item.getYear(), item.getMonth());
view.measureSize(mItemWidth, mItemHeight);
}
private static class YearViewHolder extends RecyclerView.ViewHolder {View on GitHub (pinned to f5479ea3ba)