* 用于水平容器的曝光
* Created by kevin on 16/11/30.
*/
public abstract class ExposeHorizontalView extends HorizontalScrollView {
protected LinearLayout mContainer;
protected List<Integer> mViewWidthList = new ArrayList();
protected int currentViewWidth;
protected int start;
protected int end;
protected int lastStart = -1;
protected int lastEnd = -1;
private boolean isExposed = false;
public ExposeHorizontalView(Context context) {
super(context);
init();
}
public ExposeHorizontalView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ExposeHorizontalView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mContainer = new LinearLayout(getContext());
mContainer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
mContainer.setOrientation(LinearLayout.HORIZONTAL);
this.addView(mContainer);
}
protected void initExposedView(View view) {
view.measure(0, 0);
mViewWidthList.add(currentViewWidth);
currentViewWidth += view.getMeasuredWidth();
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(mViewWidthList.size() > 0) {
calculate(l, this.getMeasuredWidth() + l);
}
}
private void calculate(int left, int right) {
for(int i = 0; i < mViewWidthList.size(); i++) {
int viewStart = mViewWidthList.get(i);
int viewEnd = currentViewWidth;
if(i < mViewWidthList.size() - 1) {
viewEnd = mViewWidthList.get(i + 1);
}
if(left >= viewStart && left < viewEnd) {
start = i;
}
if(right > viewStart && right <= viewEnd) {
end = i;
}
}
if (lastEnd < start || lastStart > end) {
expose(start, end);
} else if (start < lastEnd && end > lastEnd) {
expose(lastEnd + 1, end);
} else if (end > lastStart && start < lastStart) {
expose(start, lastStart - 1);
} else if (start == lastStart && end > lastEnd) {
expose(lastStart + 1, end);
} else if (end == lastEnd && start < lastStart) {
expose(start, lastStart - 1);
}
lastStart = start;
lastEnd = end;
}
protected abstract void expose(int start, int end);
public void clearExposeData() {
lastStart = -1;
lastEnd = -1;
}
* 在一开始时horizontalView不会调用onScrollChanged(),需要手动调用
*/
public void exposeManu() {
clearExposeData();
calculate(getScrollX(), getScrollX() + getMeasuredWidth());
}
public void notifyScroll(int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
if (mContainer != null) {
boolean isIntersect = ViewUtils.isInScreen(this, getContext());
if (isIntersect) {
if(!isExposed) {
exposeManu();
}
isExposed = true;
} else {
isExposed = false;
}
}
}
}
}