TimePicker源码学习-TimePicker的结构

  虽然本身也看过不少的Android源码,也看过不少别人写的源码分析,可是总以为写出来的东西并不能彻底展示代码做者所写的东西或者本身看源码的思惟过程。(没法用言语形容)java

  这篇文章对经常使用的时间选择器TimePicker源码的总结,我可能不会从头一步一步的分析源代码,仅是我看完后的总结,固然也从中学习并应用后才有的总结。android

  spinner: api

 

 

1、从TimePicker.java看起
  1.TimePicker继承FrameLayout,代表TimePicker只是用于布局而不是具体的绘制,具体的绘制view确定在另外的地方画,而后再布局到这个FrameLayout上面(这个很关键!为何?) 
public class TimePicker extends FrameLayout{
    //......       
}

  2.首先从TimePicker构造方法看起源码分析

  在这里看到了MODE_CLOCK和MODE_SPINNER,分别是TimePicker的两种形式(能够在布局中对timePickerMode属性设置clockt或者spinner,本文针对api23,目前发现android4.0是只有一种模式),一种对应TimePickerClockDelegate,另一种对应的是TimePickerSpinnerDelegate。要注意this就是TimePicker,而且TimePicker被传进了mDelegate 的构造参数里面去。能够看到选择时间器最后要在mDelegate中进行绘制并布局在mDelegate 中。布局

public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);

    final TypedArray a = context.obtainStyledAttributes(
            attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
    final int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER);
    a.recycle();

    switch (mode) {
        case MODE_CLOCK:
            mDelegate = new TimePickerClockDelegate(
                    this, context, attrs, defStyleAttr, defStyleRes);
            break;
        case MODE_SPINNER:
        default:
            mDelegate = new TimePickerSpinnerDelegate(
                    this, context, attrs, defStyleAttr, defStyleRes);
            break;
    }
}

   下面咱们转移到TimePickerClockDelegate,由于TimePickerSpinnerDelegate对相应的,没有必要两个都分析学习

2、再看TimePickerClockDelegate.java,this

  1.也是从构造方法看起,spa

  在构造方法的中用一段inflate代码,用于对layout文件进行展开。能够看出,layout内容展开到delegator里面,而这个就是TimePicker!!这时咱们就知道为何TimePicker是继承FrameLayout的了,从上面能够看到Timepicker构造的时候已经传进来。代理

//下面是TimePickerClockDelegate.java的代码:
final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
R.layout.time_picker_material);
final View mainView = inflater.inflate(layoutResourceId, delegator);

mHeaderView = mainView.findViewById(R.id.time_header);

  另外咱们能够对比一下TimePickerClockDelegate和TimePickerSpinnerDelegate这段代码,发现风格有点不同,多是两我的或者同一我的在不一样的时间写的,blog

//下面是TimePickerSpinnerDelegate.java的:
final LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(layoutResourceId, mDelegator, true);

// hour
mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);

  2.如下我再汇总了TimePickerClockDelegate的成员变量,并造成TimePicker的类图结构

  从中你能够看到TimePicker用到的类的关系

  3.TimePickerClockDelegate是一个组合式的自定义view

  从TimePickerClockDelegate代码你能够看到他里面没有onDraw方法,说明他是一个组合式的自定义view

   

  再从类图中看他的成员变量和timepicker中clock显示模式能够看出,表盘是在RadialTimePickerView里面画的,即  

   RadialTimePickerVIew:时钟式的时间选择器中的表盘,
      其余TextView:显示的小时数和分钟数,上下午显示等(看TimePickerCLockDelegate的成员变量就能够知道)

 

 
  4.因此最后也是最重要的就是表盘RadialTimePickerVIew的绘制,他里面的知识或者思想能够用在不少的地方。好比一个文字两种颜色或背景色(其实就是用到了画图区域的补集和余集知识)。
    

 

 

  总结:本文主要讲述Android中的TimePicker类的代码结构,代码细节没有太细的深究,从中能够学到很多知识。

      1)好比若是一个自定义控件比较复杂,能够把它分解,而后再组合成一个总体。

      2)为了扩展或者兼容,能够采用代理的模式,由代理完成具体的实现。

 

相关文章
相关标签/搜索