2013-02-20 68 views

回答

2

如果有人仍然有兴趣,这里是我的解决方案,基于Phil的帖子和XSJoJo报告中提供的信息。如上所述,问题存在,因为mDateTextSize未分配给CalendarViewLegacyDelegate中的mMonthNumDrawPaint。我正在使用Java反射。

/** 
    * I'm doing this in my fragment's onCreateView() callback 
    */ 

    CalendarView calendarView = (CalendarView) contentView.findViewById(R.id.calendar_view); 

    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { // this bug exists only in Android 4.1 
     try { 
      Object object = calendarView; 
      Field[] fields = object.getClass().getDeclaredFields(); 
      for (Field field : fields) { 
       if (field.getName().equals("mDelegate")) { // the CalendarViewLegacyDelegate instance is stored in this variable 
        field.setAccessible(true); 
        object = field.get(object); 

        break; 
       } 
      } 

      Field field = object.getClass().getDeclaredField("mDateTextSize"); // text size integer value 
      field.setAccessible(true); 
      final int mDateTextSize = (Integer) field.get(object); 

      field = object.getClass().getDeclaredField("mListView"); // main ListView 
      field.setAccessible(true); 
      Object innerObject = field.get(object); 

      Method method = innerObject.getClass().getMethod(
        "setOnHierarchyChangeListener", ViewGroup.OnHierarchyChangeListener.class); // we need to set the OnHierarchyChangeListener 
      method.setAccessible(true); 
      method.invoke(innerObject, (Object) new ViewGroup.OnHierarchyChangeListener() { 
       @Override 
       public void onChildViewAdded(View parent, View child) { // apply text size every time when a new child view is added 
        try { 
         Object object = child; 
         Field[] fields = object.getClass().getDeclaredFields(); 
         for (Field field : fields) { 
          if (field.getName().equals("mMonthNumDrawPaint")) { // the paint is stored inside the view 
           field.setAccessible(true); 
           object = field.get(object); 
           Method method = object.getClass(). 
             getDeclaredMethod("setTextSize", float.class); // finally set text size 
           method.setAccessible(true); 
           method.invoke(object, (Object) mDateTextSize); 

           break; 
          } 
         } 
        } catch (Exception e) { 
         Log.e(APP_TAG, e.getMessage(), e); 
        } 
       } 

       @Override 
       public void onChildViewRemoved(View parent, View child) {} 
      }); 
     } catch (Exception e) { 
      Log.e(APP_TAG, e.getMessage(), e); 
     } 
    }