
1.gif
1.上篇文章介紹了ItemDecoration里面的三個方法,本篇我們利用這個三個方法實現(xiàn)這個效果
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = (parent.getLayoutManager()).getPosition(view);
if (position == 0) {//第一個條目肯定需要Title
outRect.set(0, mTitleHeight, 0, 0);
} else if (mCitys.get(position).getPinyin().charAt(0) != mCitys.get(position - 1).getPinyin().charAt(0)) {
//當前條目和上一個條目的第一個拼音不同時需要Title
outRect.set(0, mTitleHeight, 0, 0);
} else { //
outRect.set(0, 0, 0, 3);
}
}
首先我們先確定需要Title的條目也就是第一個出現(xiàn)該拼音首字母的條目,如果下一個條目的拼音首字母相同則復用,否則就再添加一個條目
2.在這個方法中我們畫出Tilte
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
int position = (parent.getLayoutManager()).getPosition(child);
c.drawRect(0, child.getBottom(), parent.getRight(), child.getBottom() + 3, mPaint);
if (position == 0 || mCitys.get(position).getPinyin().charAt(0) != mCitys.get(position - 1).getPinyin().charAt(0)) {
//畫背景
c.drawRect(0, child.getTop() - mTitleHeight, parent.getRight(), child.getTop(), mBgPaint);
String c1 = String.valueOf(mCitys.get(position).getPinyin().charAt(0));
Rect rect = new Rect();
mTextPaint.getTextBounds(c1, 0, 1, rect);
//畫文字
c.drawText(c1, 0, child.getTop() - (mTitleHeight / 2 - rect.height() / 2), mTextPaint);
}
}
}
3.利用此方法達到Title懸停的效果,其中 c.translate(0, firstChild.getTop())這個方法是為了移動畫板達到動畫的效果
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
//第一個可見條目的位置
int position = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
View firstChild = parent.getLayoutManager().findViewByPosition(position);
View secondChild = parent.getLayoutManager().findViewByPosition(position + 1);
if (secondChild.getTop() - firstChild.getTop() > firstChild.getHeight() * 2) {
//當?shù)诙€title和第一個title重合時移動畫板,產(chǎn)生動畫效果
c.translate(0, firstChild.getTop());
}
//畫背景
c.drawRect(0, 0, parent.getRight(), mTitleHeight, mBgPaint);
String c1 = String.valueOf(mCitys.get(position).getPinyin().charAt(0));
Rect rect = new Rect();
mTextPaint.getTextBounds(c1, 0, 1, rect);
//畫文字
c.drawText(c1, 0, mTitleHeight / 2 + rect.height() / 2, mTextPaint);
}
完整代碼:
public class MyItemDecoration extends RecyclerView.ItemDecoration {
private List<CityBean.CitysBean> mCitys;
private RVActivity mContext;
private Paint mBgPaint;//畫背景
private Paint mTextPaint;//畫文字
private int mTitleHeight;//Title的高度
private final Paint mPaint;
public MyItemDecoration(List<CityBean.CitysBean> citys, RVActivity context) {
mCitys = citys;
mContext = context;
mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBgPaint.setColor(Color.GREEN);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.RED);
mTextPaint.setTextSize(SizeUtils.sp2px(mContext, 20));
mTitleHeight = SizeUtils.dp2px(mContext, 60);
mPaint = new Paint();
mPaint.setColor(Color.GRAY);
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = (parent.getLayoutManager()).getPosition(view);
if (position == 0) {//第一個條目肯定需要Title
outRect.set(0, mTitleHeight, 0, 0);
} else if (mCitys.get(position).getPinyin().charAt(0) != mCitys.get(position - 1).getPinyin().charAt(0)) {
//當前條目和上一個條目的第一個拼音不同時需要Title
outRect.set(0, mTitleHeight, 0, 0);
} else { //
outRect.set(0, 0, 0, 3);
}
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
int position = (parent.getLayoutManager()).getPosition(child);
c.drawRect(0, child.getBottom(), parent.getRight(), child.getBottom() + 3, mPaint);
if (position == 0 || mCitys.get(position).getPinyin().charAt(0) != mCitys.get(position - 1).getPinyin().charAt(0)) {
//畫背景
c.drawRect(0, child.getTop() - mTitleHeight, parent.getRight(), child.getTop(), mBgPaint);
String c1 = String.valueOf(mCitys.get(position).getPinyin().charAt(0));
Rect rect = new Rect();
mTextPaint.getTextBounds(c1, 0, 1, rect);
//畫文字
c.drawText(c1, 0, child.getTop() - (mTitleHeight / 2 - rect.height() / 2), mTextPaint);
}
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
//第一個可見條目的位置
int position = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
View firstChild = parent.getLayoutManager().findViewByPosition(position);
View secondChild = parent.getLayoutManager().findViewByPosition(position + 1);
if (secondChild.getTop() - firstChild.getTop() > firstChild.getHeight() * 2) {
//當?shù)诙€title和第一個title重合時移動畫板,產(chǎn)生動畫效果
c.translate(0, firstChild.getTop());
}
//畫背景
c.drawRect(0, 0, parent.getRight(), mTitleHeight, mBgPaint);
String c1 = String.valueOf(mCitys.get(position).getPinyin().charAt(0));
Rect rect = new Rect();
mTextPaint.getTextBounds(c1, 0, 1, rect);
//畫文字
c.drawText(c1, 0, mTitleHeight / 2 + rect.height() / 2, mTextPaint);
}
}