前言:接着上一篇《Android PullToRefresh 分析之一、初识PullToRefresh》,这一篇主要分析UI结构,尽可能每一篇只说一点,然后将该点讲解清楚。
// ===========================================================
// Constructors
// ===========================================================
public PullToRefreshBase(Context context) {
super(context);
init(context, null);
}
public PullToRefreshBase(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public PullToRefreshBase(Context context, Mode mode) {
super(context);
mMode = mode;
init(context, null);
}
public PullToRefreshBase(Context context, Mode mode, AnimationStyle animStyle) {
super(context);
mMode = mode;
mLoadingAnimationStyle = animStyle;
init(context, null);
}
可以发现,这几个构造函数都不约而同的调用了一个方法,PullToRefreshBase#init(context, attrs);今天的主角就是它了,那它都进行了哪些初始操作呢:
@SuppressWarnings("deprecation")
private void init(Context context, AttributeSet attrs) {
// ①、获取刷新加载的方向
switch (getPullToRefreshScrollDirection()) {
case HORIZONTAL:
setOrientation(LinearLayout.HORIZONTAL);
break;
case VERTICAL:
default:
setOrientation(LinearLayout.VERTICAL);
break;
}
......
// ②、获取配置的刷新加载模式
if (a.hasValue(R.styleable.PullToRefresh_ptrMode)) {
mMode = Mode.mapIntToValue(a.getInteger(R.styleable.PullToRefresh_ptrMode, 0));
}
......
// ③、初始化刷新加载View
mRefreshableView = createRefreshableView(context, attrs);
// ④、将刷新加载View添加到布局
addRefreshableView(context, mRefreshableView);
// ⑤、初始"刷新头部"和"加载外部"布局
mHeaderLayout = createLoadingLayout(context, Mode.PULL_FROM_START, a);
mFooterLayout = createLoadingLayout(context, Mode.PULL_FROM_END, a);
......
// ⑥、根据刷新加载模式更新控件
updateUIForMode();
}
private void addRefreshableView(Context context, T refreshableView) {
mRefreshableViewWrapper = new FrameLayout(context);
mRefreshableViewWrapper.addView(refreshableView, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
addViewInternal(mRefreshableViewWrapper, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
}
protected LoadingLayout createLoadingLayout(Context context, Mode mode, TypedArray attrs) {
LoadingLayout layout = mLoadingAnimationStyle.createLoadingLayout(context, mode,
getPullToRefreshScrollDirection(), attrs);
layout.setVisibility(View.INVISIBLE);
return layout;
}
LoadingLayout createLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
switch (this) {
case ROTATE:
default:
return new RotateLoadingLayout(context, mode, scrollDirection, attrs);
case FLIP:
return new FlipLoadingLayout(context, mode, scrollDirection, attrs);
}
}
是根据刷新加载样式不同来生成布局,可以看到默认提供了两种样式,一个是这样的
,另一个是这样的。
protected void updateUIForMode() {
// We need to use the correct LayoutParam values, based on scroll
// direction
final LinearLayout.LayoutParams lp = getLoadingLayoutLayoutParams();
......
if (mMode.showHeaderLoadingLayout()) {
addViewInternal(mHeaderLayout, 0, lp);
}
......
if (mMode.showFooterLoadingLayout()) {
addViewInternal(mFooterLayout, lp);
}
// Hide Loading Views
refreshLoadingViewsSize();
......
}
在这里把头部和尾部 加载到自身LinearLayout上,并隐藏头部和尾部。