界面主要是通过GridLayoutManager设置每行显示两个item;
mRecyclerView = (MyRecyclerView) rootView.findViewById(R.id.id_recyclerview_grid);
mAppAddBtn = (ImageView) rootView.findViewById(R.id.app_list_add);
mManager = new GridLayoutManager(getActivity().getBaseContext(), 2);
mRecyclerView.setLayoutManager(mManager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(this);
mAdapter.setOnItemLongClickListener(this);
此处就不做介绍了,本文主要是讲在RecyclerView界面右侧加上弧形滚动条
原理:
自定义RecyclerView,继承RecyclerView,重写onDraw方法,在onDraw中画出滚动条,通过adapter中getItemCount()方法获得总的item数目来决定滚动条移动部分的长度,
优点:
借助RecyclerView的刷新
来刷新滚动条位置,不用自己去做大量的刷新,相比于单独定义view可优化部分性能;
代码实现:
public class MyRecyclerView extends RecyclerView {
private static final String TAG = "RecyclerView";
int mArcLength = 0;
private GridLayoutManager mLayoutManager;
private Paint mBgArcPaint;
private Paint mArcPaint;
private Paint mCirclePaint;
private Paint mBgCirclePaint;
private final int START_ANGLE = 320;
private final int SWEEP_ANGLE = 80;
private final int PADDING =12;
private boolean mIndicatorVisible = false; // 是否显示滚动条
private int mVisibleItemCount = 0;
private Handler mHandler = new Handler();
private int mYscroll = 0;
private MyAdapter mAdapter;
private int mItemHeight = 0;
private float mStrokeWidth = 6;
private int topBottomPadding = 30+40 ;
public MyRecyclerView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public MyRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
/**
*定义画笔样式
**/
private void init() {
mBgArcPaint = new Paint();
mBgArcPaint.setAntiAlias(true);
mBgArcPaint.setColor(Color.GRAY);
mBgArcPaint.setStrokeWidth(mStrokeWidth);
mBgArcPaint.setStyle(Style.STROKE);
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setColor(Color.WHITE);
mArcPaint.setStrokeWidth(mStrokeWidth);
mArcPaint.setStyle(Style.STROKE);
// setOnScrollListener(mOnScrollListener);
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(Color.WHITE);
mBgCirclePaint = new Paint();
mBgCirclePaint.setAntiAlias(true);
mBgCirclePaint.setColor(Color.GRAY);
setOnScrollListener(mOnScrollListener);
}
public void clear() {
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
invalidate();
}
@Override
public void draw(Canvas arg0) {
// TODO Auto-generated method stub
super.draw(arg0);
}
@Override
public void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (mIndicatorVisible) {
int width = getWidth();
int height = getHeight();
int diameter = Math.max(width, height)-PADDING;//diameter should < 200
int count = getAdapter().getItemCount();
int first = mLayoutManager.findFirstVisibleItemPosition();
int last = mLayoutManager.findLastVisibleItemPosition();
View v = mLayoutManager.getChildAt(first);
if (v != null) {
mItemHeight = v.getHeight();
}
if (mVisibleItemCount == 0) {
mVisibleItemCount = last - first;
}
Log.e(TAG,"------mItemHeight="+mItemHeight+", width = "+width+",height="+height);
int totalHeight = mItemHeight * (mAdapter.getItemCount()/mLayoutManager.getSpanCount()+mAdapter.getItemCount()%mLayoutManager.getSpanCount())+ topBottomPadding;
float offsetAngle = 0;
float sweepAngle = (height * SWEEP_ANGLE / totalHeight);
if (totalHeight != 0) {
offsetAngle = (SWEEP_ANGLE * ((float) mYscroll) / totalHeight);
} else {
offsetAngle = (SWEEP_ANGLE * ((float) first) / count);
}
RectF rect = new RectF((width - diameter) / 2,
(height - diameter) / 2, (width + diameter) / 2,
(height + diameter) / 2);
canvas.drawCircle(
(float) (width / 2 + diameter/ 2* Math.cos((START_ANGLE) * Math.PI/ 180)),
(float) (height / 2 + diameter/ 2* Math.sin((START_ANGLE) * Math.PI/ 180)), mStrokeWidth / 2, mBgCirclePaint);
canvas.drawArc(rect, START_ANGLE, SWEEP_ANGLE, false, mBgArcPaint);
canvas.drawCircle((float) (width / 2 + diameter/ 2* Math.cos((START_ANGLE + SWEEP_ANGLE) * Math.PI/ 180)),
(float) (height / 2 + diameter/ 2* Math.sin((START_ANGLE + SWEEP_ANGLE) * Math.PI/ 180)),
mStrokeWidth / 2, mBgCirclePaint);
RectF rect2 = new RectF((width - diameter) / 2,
(height - diameter) / 2, (width + diameter) / 2,
(height + diameter) / 2);
Log.d(TAG, "-------sweepAngle=" + sweepAngle + ",offsetAngle="+ offsetAngle);
canvas.drawCircle(
(float) (width / 2 + diameter
/ 2
* Math.cos((START_ANGLE + offsetAngle) * Math.PI
/ 180)),
(float) (height / 2 + diameter
/ 2
* Math.sin((START_ANGLE + offsetAngle) * Math.PI
/ 180)), mStrokeWidth / 2, mCirclePaint);
canvas.drawArc(rect2, START_ANGLE + offsetAngle, sweepAngle, false,
mArcPaint);
canvas.drawCircle(
(float) (width / 2 + diameter
/ 2
* Math.cos((START_ANGLE + offsetAngle+sweepAngle) * Math.PI
/ 180)),
(float) (height / 2 + diameter
/ 2
* Math.sin((START_ANGLE + offsetAngle+sweepAngle) * Math.PI
/ 180)), mStrokeWidth / 2, mCirclePaint);
} else {
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
}
}
@Override
public void setLayoutManager(LayoutManager layout) {
// TODO Auto-generated method stub
super.setLayoutManager(layout);
if (mLayoutManager != layout) {
// mLayoutManager = (LinearLayoutManager) layout;
mLayoutManager = (GridLayoutManager) layout;
}
}
@Override
protected void onAttachedToWindow() {
// TODO Auto-generated method stub
super.onAttachedToWindow();
if (getAdapter() != null) {
Log.e(TAG, "-----" + getAdapter().getItemCount());
}
}
Runnable mRun = new Runnable() {
public void run() {
mIndicatorVisible = false;
invalidate();
}
};
@Override
public boolean onTouchEvent(MotionEvent arg0) {
// TODO Auto-generated method stub
int action = arg0.getAction();
if (action == MotionEvent.ACTION_MOVE) {
mIndicatorVisible = true;
} else if (action == MotionEvent.ACTION_UP) {
mHandler.removeCallbacks(mRun);
mHandler.postDelayed(mRun, 3000);
}
return super.onTouchEvent(arg0);
}
@Override
public void setAdapter(Adapter adapter) {
// TODO Auto-generated method stub
super.setAdapter(adapter);
mAdapter = (MyAdapter) adapter;
}
private RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
// TODO Auto-generated method stub
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// TODO Auto-generated method stub
super.onScrolled(recyclerView, dx, dy);
mYscroll = mYscroll + dy;
}
};
}