RecyclerView加上弧形滚动条

  
界面主要是通过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;
		}


	};


}

你可能感兴趣的:(Android)