Android 4.0日历(calendar)源码分析之DayFragment

周视图

周视图和日视图都是由DayFragment管理的,因为两者有很相似的地方:

1.都是直接用自定义的view绘出来的

2.都是两个在viewswitcher中的dayview交替显示

3.整个视图基本上都只有一个dayview,没有多余的控件(actionbar除外,周视图上面的周几提示除外)

在相同的Fragment下能显示出不同view的原因是allinoneactivity他们各自的参数不一样.

case ViewType.DAY:  //如果当前为日视图

….

frag = new DayFragment(timeMillis, 1);

case ViewType. WEEK:  //如果当前为周视图

….

frag = new DayFragment(timeMillis, 7);

一周有7天,所以第二个参数为7 ,一日只有一天,所以第二个参数为1.

DayFragment中在通过将第二个参数传递给DayView,DayView根据不同的参数绘出不同的界面。

因此要分析这两个视图,重点还是集中在DayFragment和DayView两个文件中。

除此之外,你还应该了解ViewSwitcher的用法。

我们从DayFragment开始吧。

DayFragment

首先是DayFragment的构造函数:

public DayFragment(long timeMillis, int numOfDays) {
 
    mNumDays = numOfDays;
 
    if (timeMillis == 0) {
 
        mSelectedDay.setToNow();
 
    } else {
 
        mSelectedDay.set(timeMillis);
 
    }
 
}

mNumDays保存了刚刚提到参数。

然后在makeView()方法中这个值传递给了DayView

    public View makeView() {
 
        mTZUpdater.run();
 
        DayView view = new DayView(getActivity(), CalendarController
 
                .getInstance(getActivity()), mViewSwitcher, mEventLoader, mNumDays);
 
        view.setId(VIEW_ID);
 
        view.setLayoutParams(new ViewSwitcher.LayoutParams(
 
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
 
        view.setSelected(mSelectedDay, false, false);
 
        return view;
 
}

makeView会在ViewSwitcher加载的时候自动调用,因为我们在DayFragment里面将ViewSwitcher的“工厂”设置成了当前DayFragment对象。这是在onCreateView()中完成的:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 
            Bundle savedInstanceState) {
 
        View v = inflater.inflate(R.layout.day_activity, null);
 
  
 
        mViewSwitcher = (ViewSwitcher) v.findViewById(R.id.switcher);
 
        mViewSwitcher.setFactory(this);
 
        mViewSwitcher.getCurrentView().requestFocus();
 
        ((DayView) mViewSwitcher.getCurrentView()).updateTitle();
 
  
 
        return v;
 
}

onCreateView获取到了Fragment的相对应的xml文件day_activity,里面有个ViewSwitcher控件,mViewSwitcher.setFactory(this)将给自己装入子元素的工厂设置成当前DayFragment对象,以便调用上面提到的makeView,然后下面两行

mViewSwitcher.getCurrentView().requestFocus();
 
 ((DayView) mViewSwitcher.getCurrentView()).updateTitle();

是对mViewSwitcher做一些初始化。

onCreate:
 
    public void onCreate(Bundle icicle) {
 
        super.onCreate(icicle);
 
  
 
        Context context = getActivity();
 
  
 
        mInAnimationForward = AnimationUtils.loadAnimation(context, R.anim.slide_left_in);
 
        mOutAnimationForward = AnimationUtils.loadAnimation(context, R.anim.slide_left_out);
 
        mInAnimationBackward = AnimationUtils.loadAnimation(context, R.anim.slide_right_in);
 
        mOutAnimationBackward = AnimationUtils.loadAnimation(context, R.anim.slide_right_out);
 
  
 
        mEventLoader = new EventLoader(context);
 
}