组合模式实现与研究 - bei1999/work GitHub Wiki
组合模式有时又叫部分-整体模式,将对象组合成树形结构来表示“部分-整体”层次结构。组合模式在处理树形结构的问题时比较方便。
android 源码中view 的使用
下面是view 的源码关系
@UiThread
public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {
...
/**
* Ignore any optimizations using the measure cache.
*/
private static boolean sIgnoreMeasureCache = false;
/**
* This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
* calling setFlags.
*/
private static final int NOT_FOCUSABLE = 0x00000000;
/**
* This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
* setFlags.
*/
private static final int FOCUSABLE = 0x00000001;
/**
* Mask for use with setFlags indicating bits used for focus.
*/
private static final int FOCUSABLE_MASK = 0x00000001;
/**
* This view will adjust its padding to fit sytem windows (e.g. status bar)
*/
private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
/** @hide */
@IntDef({VISIBLE, INVISIBLE, GONE})
@Retention(RetentionPolicy.SOURCE)
public @interface Visibility {}
}
@UiThread
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
private static final String TAG = "ViewGroup";
private static final boolean DBG = false;
/** @hide */
public static boolean DEBUG_DRAW = false;
/**
* Views which have been hidden or removed which need to be animated on
* their way out.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
protected ArrayList<View> mDisappearingChildren;
...
public void addView(View child) {
addView(child, -1);
}
/**
* Adds a child view. If no layout parameters are already set on the child, the
* default parameters for this ViewGroup are set on the child.
*
* <p><strong>Note:</strong> do not invoke this method from
* {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
* {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*
* @param child the child view to add
* @param index the position at which to add the child
*
* @see #generateDefaultLayoutParams()
*/
public void addView(View child, int index) {
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
}
/**
* Adds a child view with this ViewGroup's default layout parameters and the
* specified width and height.
*
* <p><strong>Note:</strong> do not invoke this method from
* {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
* {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*
* @param child the child view to add
*/
public void addView(View child, int width, int height) {
final LayoutParams params = generateDefaultLayoutParams();
params.width = width;
params.height = height;
addView(child, -1, params);
}
/**
* {@inheritDoc}
*
* <p><strong>Note:</strong> do not invoke this method from
* {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
* {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
*/
public void removeView(View view) {
if (removeViewInternal(view)) {
requestLayout();
invalidate(true);
}
}
/**
* Returns the view at the specified position in the group.
*
* @param index the position at which to get the view from
* @return the view at the specified position or null if the position
* does not exist within the group
*/
public View getChildAt(int index) {
if (index < 0 || index >= mChildrenCount) {
return null;
}
return mChildren[index];
}
...
}
@RemoteView
public class RelativeLayout extends ViewGroup {
public static final int TRUE = -1;
/**
* Rule that aligns a child's right edge with another child's left edge.
*/
public static final int LEFT_OF = 0;
/**
* Rule that aligns a child's left edge with another child's right edge.
*/
public static final int RIGHT_OF = 1;
/**
* Rule that aligns a child's bottom edge with another child's top edge.
*/
public static final int ABOVE = 2;
...
}
android 的ViewGroup 继承自view 做为容器类存在,子类包含了很多常见的布局,RelativeLayout,LinearLayout,FrameLayout,AbsoluteLayout等,从代码可以看到ViewGroup 内部实现了对view 的增删查询等控制方法,这其实就是组合模式。
既然提到了View和ViewGroup 那就再说下与ViewGroup平行的另一个分支吧,button 是继承textview
@RemoteView
public class Button extends TextView {
public Button(Context context) {
this(context, null);
}
public Button(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.buttonStyle);
}
public Button(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public CharSequence getAccessibilityClassName() {
return Button.class.getName();
}
}
也就是说android 系统中的ui 组件,总体继承view,一部分继承view扩展而来如textview,surfaceview,progressbar,ViewGroup等,继承自ViewGroup扩展出上面的几个容器类。
最后列出关系图