0
点赞
收藏
分享

微信扫一扫

android用ItemDecoration实现通讯录


本来因为代码是抄的不太想自己写一篇博客,但是用的过程中出现了意外,不知道为什么粘性头部效果完全不对,无奈之下只好重新写了。特此记录:
getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state):用于设置item之间的距离,onDraw只能画在这个距离内,多出的部分不可见
onDraw(Canvas c, RecyclerView parent, RecyclerView.State state)绘制divider,只能画在getItemOffsets之内。
onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) 绘制在recyclerview上面,不影响item间的距离,也不受getItemOffsets影响。

所以粘性头部是onDrawOver部分的代码。

参考自:​​https://www.jianshu.com/p/b46a4ff7c10a​​​
SectionDecoration 内除了onDrawOver的部分,其他部分来源于这里。效果就不贴了,和参考的图差不多。
以下为完整代码:

public class SectionDecoration extends RecyclerView.ItemDecoration
private static final String TAG = "SectionDecoration";

private DecorationCallback callback;
private TextPaint textPaint;
private Paint paint;
private int topGap;
private Paint.FontMetrics fontMetrics;

public SectionDecoration(Context context, DecorationCallback decorationCallback) {
Resources res = context.getResources();
this.callback = decorationCallback;

paint = new Paint();
paint.setColor(res.getColor(R.color.colorAccent));
textPaint = new TextPaint();
textPaint.setTypeface(Typeface.DEFAULT_BOLD);
textPaint.setAntiAlias(true);
textPaint.setTextSize(80);
textPaint.setColor(Color.BLACK);
textPaint.getFontMetrics(fontMetrics);
textPaint.setTextAlign(Paint.Align.LEFT);
fontMetrics = new Paint.FontMetrics();
topGap = res.getDimensionPixelSize(R.dimen.sectioned_top);//32dp


}


@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int pos = parent.getChildAdapterPosition(view);
if (isFirstInGroup(pos)) {//同组的第一个才添加padding
outRect.top = topGap;
} else {
outRect.top = 0;
}
}

private int charLeft = 20;

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View view = parent.getChildAt(i);
int position = parent.getChildAdapterPosition(view);
String textLine = callback.getFirstCharacter(position).toUpperCase();
if (position == 0 || isFirstInGroup(position)) {
float top = view.getTop() - topGap;
float bottom = view.getTop();
Rect bounds = new Rect();
String str = callback.getFirstCharacter(position).toUpperCase();
textPaint.getTextBounds(str, 0, str.length(), bounds);
c.drawRect(left, top, right, bottom, paint);//绘制红色矩形
c.drawText(textLine, left + charLeft, top + (topGap + bounds.height()) / 2.0f, textPaint);//绘制文本
}
}
}


private boolean isFirstInGroup(int pos) {
if (pos == 0) {
return true;
} else {
String str1 = callback.getFirstCharacter(pos).toLowerCase();
String str2 = callback.getFirstCharacter(pos - 1).toLowerCase();
return !str1.equals(str2);
}
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
int pos = ((LinearLayoutManager)(parent.getLayoutManager())).findFirstVisibleItemPosition();
View child = parent.findViewHolderForLayoutPosition(pos).itemView;
int viewBottom = child.getBottom();
if(viewBottom<topGap){//如果当前view底部距离固定头高度小于悬浮部分高度,则取下一个view的首字母
++pos;
child = parent.findViewHolderForLayoutPosition(pos).itemView;
}


paint.setColor(parent.getResources().getColor(R.color.colorAccent));
Rect bounds = new Rect();
String str = callback.getFirstCharacter(pos).toUpperCase();

int paddingTop = parent.getPaddingTop();
c.drawRect(parent.getPaddingLeft(), paddingTop, parent.getRight() - parent.getPaddingRight(), paddingTop + topGap, paint);
textPaint.getTextBounds(str, 0, str.length(), bounds);
c.drawText(callback.getFirstCharacter(pos).toUpperCase(), charLeft+child.getPaddingLeft(),
parent.getPaddingTop() + topGap - (topGap / 2 - bounds.height() / 2),
textPaint);

}

public interface DecorationCallback
String getFirstCharacter(int

AppCompatActivity.java

public class DecorationActivity extends AppCompatActivity

private RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_decoration);

recyclerView = (RecyclerView) findViewById(R.id.recycler_decoration);

initData();
MyRecyclerAdapter recycleAdapter = new MyRecyclerAdapter(DecorationActivity.this, mDatas);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
//设置布局管理器
recyclerView.setLayoutManager(layoutManager);
//设置为垂直布局,这也是默认的
layoutManager.setOrientation(OrientationHelper.VERTICAL);
//设置Adapter
recyclerView.setAdapter(recycleAdapter);
//设置增加或删除条目的动画
recyclerView.setItemAnimator(new DefaultItemAnimator());
//距离
// recyclerView.addItemDecoration(new SimplePaddingDecoration(this));
recyclerView.addItemDecoration(new SimpleDividerDecoration(this));
recyclerView.addItemDecoration(new SectionDecoration(this, new SectionDecoration.DecorationCallback() {
@Override
public String getFirstCharacter(int position) {
String contentLine = mDatas.get(position);
if (contentLine != null && contentLine.length() > 0)
return contentLine.substring(0, 1);
return "";
}
}));
// recyclerView.addItemDecoration(new LeftAndRightTagDecoration(this));
// recyclerView.addItemDecoration(new LinearLayoutColorDivider(getResources(),R.color.white,R.dimen.divider_height,LinearLayoutManager.VERTICAL));
}

private List<String> mDatas;

private void initData() {
mDatas = new ArrayList<String>();
for (char i = 'a'; i <= 'z'; i++) {
for (int j = 0; j < 3; j++) {
mDatas.add(i + ""

SimpleDividerDecoration.java

package com.dyy.yonxin.library2.test.decoration;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import com.dyy.yonxin.library2.test.R;

public class SimpleDividerDecoration extends RecyclerView.ItemDecoration

private int dividerHeight;
private Paint dividerPaint;

public SimpleDividerDecoration(Context context) {
dividerPaint = new Paint();
dividerPaint.setColor(context.getResources().getColor(R.color.black));
dividerHeight = context.getResources().getDimensionPixelSize(R.dimen.divider_height);
}


@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
int childCount = parent.getChildCount();
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();

for (int i = 0; i < childCount-1; i++) {
View view = parent.getChildAt(i);
float top = view.getBottom();
float


举报

相关推荐

0 条评论