StickyListHeaders的用法说明(带字母索引条)

本文介绍了如何使用StickyListHeaders库来创建带有字母索引条目的列表。通过示例代码展示了如何设置Activity、Adapter和布局文件,包括`activity_city_select.xml`和`item_city_letter_sort.xml`,并详细解释了关键函数如`onScroll`、`setAdapter`和`performItemClick`等的实现,帮助开发者实现列表头的固定和滚动跟随效果。
摘要由CSDN通过智能技术生成

Log.e(“parent”,“onScroll”);

if (mOnScrollListenerDelegate != null) {

mOnScrollListenerDelegate.onScroll(view, firstVisibleItem,

visibleItemCount, totalItemCount);

}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {

scrollChanged(firstVisibleItem);

}

}

};

public StickyListHeadersListView(Context context) {

this(context, null);

}

public StickyListHeadersListView(Context context, AttributeSet attrs) {

this(context, attrs, android.R.attr.listViewStyle);

}

public StickyListHeadersListView(Context context, AttributeSet attrs,

int defStyle) {

super(context, attrs, defStyle);

super.setOnScrollListener(mOnScrollListener);

// null out divider, dividers are handled by adapter so they look good

// with headers

super.setDivider(null);

super.setDividerHeight(0);

mViewConfig = ViewConfiguration.get(context);

if (mClippingToPadding == null) {

mClippingToPadding = true;

}

try {

Field selectorRectField = AbsListView.class

.getDeclaredField(“mSelectorRect”);

selectorRectField.setAccessible(true);

mSelectorRect = (Rect) selectorRectField.get(this);

mSelectorPositionField = AbsListView.class

.getDeclaredField(“mSelectorPosition”);

mSelectorPositionField.setAccessible(true);

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

if (changed) {

reset();

scrollChanged(getFirstVisiblePosition());

}

}

private void reset() {

mHeader = null;

mCurrentHeaderId = null;

mHeaderPosition = null;

mHeaderBottomPosition = -1;

}

@Override

public boolean performItemClick(View view, int position, long id) {

if (view instanceof WrapperView) {

view = ((WrapperView) view).mItem;

}

return super.performItemClick(view, position, id);

}

@Override

public void setDivider(Drawable divider) {

this.mDivider = divider;

if (divider != null) {

int dividerDrawableHeight = divider.getIntrinsicHeight();

if (dividerDrawableHeight >= 0) {

setDividerHeight(dividerDrawableHeight);

}

}

if (mAdapter != null) {

mAdapter.setDivider(divider);

requestLayout();

invalidate();

}

}

@Override

public void setDividerHeight(int height) {

mDividerHeight = height;

if (mAdapter != null) {

mAdapter.setDividerHeight(height);

requestLayout();

invalidate();

}

}

@Override

public void setOnScrollListener(OnScrollListener l) {

mOnScrollListenerDelegate = l;

}

public void setAreHeadersSticky(boolean areHeadersSticky) {

if (this.mAreHeadersSticky != areHeadersSticky) {

this.mAreHeadersSticky = areHeadersSticky;

requestLayout();

}

}

public boolean getAreHeadersSticky() {

return mAreHeadersSticky;

}

@Override

public void setAdapter(ListAdapter adapter) {

if (this.isInEditMode()) {

super.setAdapter(adapter);

return;

}

if (adapter == null) {

mAdapter = null;

reset();

super.setAdapter(null);

return;

}

if (!(adapter instanceof StickyListHeadersAdapter)) {

throw new IllegalArgumentException(

“Adapter must implement StickyListHeadersAdapter”);

}

mAdapter = wrapAdapter(adapter);

reset();

super.setAdapter(this.mAdapter);

}

private AdapterWrapper wrapAdapter(ListAdapter adapter) {

AdapterWrapper wrapper;

if (adapter instanceof SectionIndexer) {

wrapper = new SectionIndexerAdapterWrapper(getContext(),

(StickyListHeadersAdapter) adapter);

} else {

wrapper = new AdapterWrapper(getContext(),

(StickyListHeadersAdapter) adapter);

}

wrapper.setDivider(mDivider);

wrapper.setDividerHeight(mDividerHeight);

wrapper.registerDataSetObserver(mDataSetChangedObserver);

wrapper.setOnHeaderClickListener(mAdapterHeaderClickListener);

return wrapper;

}

public StickyListHeadersAdapter getWrappedAdapter() {

return mAdapter == null ? null : mAdapter.mDelegate;

}

public View getWrappedView(int position) {

View view = getChildAt(position);

if ((view instanceof WrapperView))

return ((WrapperView) view).mItem;

return view;

}

@Override

protected void dispatchDraw(Canvas canvas) {

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {

scrollChanged(getFirstVisiblePosition());

}

positionSelectorRect();

if (!mAreHeadersSticky || mHeader == null) {

super.dispatchDraw(canvas);

return;

}

if (!mDrawingListUnderStickyHeader) {

mClippingRect

.set(0, mHeaderBottomPosition, getWidth(), getHeight());

canvas.save();

canvas.clipRect(mClippingRect); 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】

}

super.dispatchDraw(canvas);

if (!mDrawingListUnderStickyHeader) {

canvas.restore();

}

drawStickyHeader(canvas);

}

private void positionSelectorRect() {

if (!mSelectorRect.isEmpty()) {

int selectorPosition = getSelectorPosition();

if (selectorPosition >= 0) {

int firstVisibleItem = fixedFirstVisibleItem(getFirstVisiblePosition());

View v = getChildAt(selectorPosition - firstVisibleItem);

if (v instanceof WrapperView) {

WrapperView wrapper = ((WrapperView) v);

mSelectorRect.top = wrapper.getTop() + wrapper.mItemTop;

}

}

}

}

private int getSelectorPosition() {

if (mSelectorPositionField == null) { // not all supported andorid

// version have this variable

for (int i = 0; i < getChildCount(); i++) {

if (getChildAt(i).getBottom() == mSelectorRect.bottom) {

return i + fixedFirstVisibleItem(getFirstVisiblePosition());

}

}

} else {

try {

return mSelectorPositionField.getInt(this);

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

return -1;

}

private void drawStickyHeader(Canvas canvas) {

int headerHeight = getHeaderHeight();

int top = mHeaderBottomPosition - headerHeight;

// clip the headers drawing region

mClippingRect.left = getPaddingLeft();

mClippingRect.right = getWidth() - getPaddingRight();

mClippingRect.bottom = top + headerHeight;

mClippingRect.top = mClippingToPadding ? getPaddingTop() : 0;

canvas.save();

canvas.clipRect(mClippingRect);

canvas.translate(getPaddingLeft(), top);

mHeader.draw(canvas);

canvas.restore();

}

private void measureHeader() {

int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getWidth()

  • getPaddingLeft() - getPaddingRight()

  • (isScrollBarOverlay() ? 0 : getVerticalScrollbarWidth()), MeasureSpec.EXACTLY);

int heightMeasureSpec = 0;

ViewGroup.LayoutParams params = mHeader.getLayoutParams();

if (params != null && params.height > 0) {

heightMeasureSpec = MeasureSpec.makeMeasureSpec(params.height,

MeasureSpec.EXACTLY);

} else {

heightMeasureSpec = MeasureSpec.makeMeasureSpec(0,

MeasureSpec.UNSPECIFIED);

}

mHeader.measure(widthMeasureSpec, heightMeasureSpec);

mHeader.layout(getPaddingLeft(), 0, getWidth()

  • getPaddingRight(), mHeader.getMeasuredHeight());

}

private boolean isScrollBarOverlay() {

int scrollBarStyle = getScrollBarStyle();

return scrollBarStyle == SCROLLBARS_INSIDE_OVERLAY || scrollBarStyle == SCROLLBARS_OUTSIDE_OVERLAY;

}

private int getHeaderHeight() {

return mHeader == null ? 0 : mHeader.getMeasuredHeight();

}

@Override

public void setClipToPadding(boolean clipToPadding) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值