我是靠谱客的博主 优美铃铛,这篇文章主要介绍Android自定义RecyclerView实现不固定刻度的刻度尺,现在分享给大家,希望可以做个参考。

本文实例为大家分享了自定义RecyclerView实现不固定刻度的刻度尺的具体代码,供大家参考,具体内容如下

##不均匀刻度效果图

##等比例刻度效果图

实现功能目前

1、实现类似日期/分类等大小不固定的水平刻度尺效果
2、实现标准刻度尺效果
3、监听RecyclerView滑动时居中条目
4、去掉边缘阴影

定义RecyclerView

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
public class CenterRecyclerView extends RecyclerView { //设置RecyclerView的速度 private static final int MAXIMUM_FLING_VELOCITY = 3000; //画中轴线 private Paint mCenterLinePaint; private Context context; private CenterLayoutManager mLayoutManager; private Paint mTextPaint; private String text = ""; private String textUnit = ""; private Paint mTextUnitPaint; private int mWidth; private int mHeight; private int mLineStartY; private int mLineEndY; private int mTextStartY; public CenterRecyclerView(@NonNull Context context) { this(context, null); } public CenterRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, -1); } public CenterRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { this.context = context; initPaint(); } public void setTypeface(Typeface typeface) { mTextPaint.setTypeface(typeface); mTextUnitPaint.setTypeface(typeface); } private void initPaint() { mCenterLinePaint = new Paint(); mCenterLinePaint.setAntiAlias(true); mCenterLinePaint.setStrokeWidth(ScreenUtil.dip2px(context, 4)); mCenterLinePaint.setTextAlign(Paint.Align.CENTER); mCenterLinePaint.setColor(0xff6e9fff); mTextUnitPaint = new Paint(); mTextUnitPaint.setStyle(Paint.Style.FILL); mTextUnitPaint.setStrokeWidth(ScreenUtil.dip2px(context, 4)); mTextUnitPaint.setTextSize(ScreenUtil.dip2px(context, 15)); mTextUnitPaint.setColor(Color.parseColor("#DD5F00")); mTextPaint = new Paint(); mTextPaint.setStyle(Paint.Style.FILL); mTextPaint.setStrokeWidth(ScreenUtil.dip2px(context, 4)); mTextPaint.setTextSize(ScreenUtil.dip2px(context, 60)); mTextPaint.setColor(Color.parseColor("#DD5F00")); mTextPaint.setTextAlign(Paint.Align.CENTER); } @Override public void addOnScrollListener(@NonNull OnScrollListener listener) { super.addOnScrollListener(listener); postInvalidate(); } @Override protected void onMeasure(int widthSpec, int heightSpec) { super.onMeasure(widthSpec, heightSpec); } //获取相关参数 @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); mWidth = getWidth(); mHeight = getHeight(); int lineHeight = ScreenUtil.dip2px(context, 58); mLineStartY = mHeight / 2 - lineHeight / 2; mLineEndY = mHeight / 2 + lineHeight / 2; mTextStartY = mHeight / 2 - ScreenUtil.dip2px(context, 55); } @Override public void draw(Canvas c) { super.draw(c); Log.d("szjjyh", "draw: " + getWidth()); drawCenterLine(c); drawText(c); } //画线 private void drawCenterLine(Canvas canvas) { canvas.drawLine(mWidth / 2, mLineStartY, mWidth / 2, mLineEndY, mCenterLinePaint); } //画字/画单位 private void drawText(Canvas c) { c.drawText(text, mWidth / 2, mTextStartY, mTextPaint); if (textUnit != null && textUnit.length() != 0) { float textWidth = mTextPaint.measureText(text); c.drawText(textUnit, (mWidth + textWidth) / 2, mTextStartY, mTextUnitPaint); } } public String getText() { return text; } public void setText(String text) { if (text == null) { return; } this.text = text; } public String getTextUnit() { return textUnit; } public void setTextUnit(String textUnit) { if (textUnit == null) { return; } this.textUnit = textUnit; } @Override public void setAdapter(@Nullable Adapter adapter) { super.setAdapter(adapter); } @Override public void setLayoutManager(@Nullable LayoutManager layout) { super.setLayoutManager(layout); mLayoutManager = (CenterLayoutManager) layout; } @Override public boolean fling(int velocityX, int velocityY) { velocityX = solveVelocity(velocityX); velocityY = solveVelocity(velocityY); return super.fling(velocityX, velocityY); } private int solveVelocity(int velocity) { if (velocity > 0) { return Math.min(velocity, MAXIMUM_FLING_VELOCITY); } else { return Math.max(velocity, -MAXIMUM_FLING_VELOCITY); } } // @Override // protected float getLeftFadingEdgeStrength() { // return 0; // } }

定义LinearLayoutManager

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class CenterLayoutManager extends LinearLayoutManager { public CenterLayoutManager(Context context) { super(context); } public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } //计算偏移量自己适配 @Override public void scrollToPosition(int position) { scrollToPositionWithOffset(position,-15); } @Override public void scrollToPositionWithOffset(int position, int offset) { super.scrollToPositionWithOffset(position, offset); } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext()); smoothScroller.setTargetPosition(position); startSmoothScroll(smoothScroller); } public void smoothScrollToPosition(RecyclerView recyclerView, int position) { RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext()); smoothScroller.setTargetPosition(position); startSmoothScroll(smoothScroller); } private static class CenterSmoothScroller extends LinearSmoothScroller { CenterSmoothScroller(Context context) { super(context); } //滑动到中间位置 @Override public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) { return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2); } //滚动速度设置 @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return 4; } @Override protected int getVerticalSnapPreference() { return super.getVerticalSnapPreference(); } } }

滑动事件监听

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
public class CenterScrollListener extends RecyclerView.OnScrollListener { private CenterLayoutManager mLayoutManager; RecyclerView recyclerView; private int mPosition; private double intScrollState; private int mFirstItemPosition1; private int mLastItemPosition1; private boolean is_Stop; private String TAG = "CenterScrollListener"; private double is_playSound; public CenterScrollListener(OnItemCenterScrollistner onItemCenterScrollistner) { this.onItemCenterScrollistner = onItemCenterScrollistner; } public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { init(recyclerView); intScrollState = newState; is_Stop = false; if (intScrollState == RecyclerView.SCROLL_STATE_IDLE) { Log.e(TAG, "onScrollStateChanged: 11111:"+mPosition); CeterScroll(0, mPosition); } } public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { init(recyclerView); int x = Math.abs(dx); if (!is_Stop && x <= 1) { is_Stop = true; if (dx >= 0) { mPosition = (mFirstItemPosition1 + mLastItemPosition1) / 2; View childAt = mLayoutManager.findViewByPosition(mPosition); if (childAt.getLeft() < ScreenUtil.getScreenWidth(recyclerView.getContext()) / 2) { mPosition = mPosition + 1; } Log.e(TAG, "111111: w:" + childAt.getWidth() + " :l:" + childAt.getLeft() + " :r:" + childAt.getRight()); } else { mPosition = (mFirstItemPosition1 + mLastItemPosition1) / 2; View childAt = mLayoutManager.findViewByPosition(mPosition); if (childAt.getLeft() > ScreenUtil.getScreenWidth(recyclerView.getContext()) / 2) { mPosition = mPosition - 1; } } } CeterScroll(x, mPosition); } //事件监听 private void init(@NonNull RecyclerView recyclerView) { this.recyclerView = recyclerView; if (mLayoutManager == null) { mLayoutManager = (CenterLayoutManager) recyclerView.getLayoutManager(); } int firstItemPosition = mLayoutManager.findFirstVisibleItemPosition(); int lastItemPosition = mLayoutManager.findLastVisibleItemPosition(); mFirstItemPosition1 = mLayoutManager.findFirstCompletelyVisibleItemPosition(); mLastItemPosition1 = mLayoutManager.findLastCompletelyVisibleItemPosition(); mPosition = (mFirstItemPosition1 + mLastItemPosition1) / 2; if (is_playSound != mPosition) { is_playSound = mPosition; int count = mLayoutManager.getItemCount(); // soundpool.play(soundmap.get(1), 1, 1, 0, 0, 1); if (onItemCenterScrollistner != null) { //中间条目事件监听 onItemCenterScrollistner.onItemCenterScrollistner(mLastItemPosition1, mPosition,count); } } //目前由于要实现灰色条目当条目间距为10dp,屏幕宽度360时不能继续滑动 if (mPosition <= 18) { CeterScroll(0, 18); } } //速度变小时自动滚动到中间位置 private void CeterScroll(int dx, int position) { if ((intScrollState == RecyclerView.SCROLL_STATE_SETTLING || intScrollState == RecyclerView.SCROLL_STATE_IDLE) && Math.abs(dx) <= 1) { mLayoutManager.smoothScrollToPosition(recyclerView, position); } } OnItemCenterScrollistner onItemCenterScrollistner; public void setOnItemCenterScrollistner(OnItemCenterScrollistner onItemCenterScrollistner) { this.onItemCenterScrollistner = onItemCenterScrollistner; } public interface OnItemCenterScrollistner { void onItemCenterScrollistner(int lastItemPosition1, int position, int count); }

adpater实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DateAdapter extends BaseRecyclerAdapter<CalendarDateBean> { private static final int layoutId = R.layout.view_item_date; public DateAdapter(Context context, List<CalendarDateBean> datas) { super(context, datas, layoutId); } @Override protected void bindData(BaseViewHolder holder, CalendarDateBean data, int position) { if (data.getDay() == 1) { //R.id.tv_1为线需要居中否则和中轴线不会完全对称 R.id.tv_2为大刻度文字 holder.getView(R.id.tv_1).setScaleX(2F); holder.setText(R.id.tv_2, data.getMonth() + "月"); holder.getView(R.id.tv_2).setVisibility(View.VISIBLE); holder.getView(R.id.tv_1).setBackgroundColor(Color.parseColor("#ffffff")); } else if (data.getDay() ==-1){ holder.getView(R.id.tv_1).setScaleX(1F); holder.getView(R.id.tv_2).setVisibility(View.GONE); holder.getView(R.id.tv_1).setBackgroundColor(Color.parseColor("#222222")); }else { holder.getView(R.id.tv_1).setScaleX(1F); holder.getView(R.id.tv_2).setVisibility(View.GONE); holder.getView(R.id.tv_1).setBackgroundColor(Color.parseColor("#ffffff")); } } }

activity 加载view展示

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private void initRecyclerView() { //此处试配时注意item10dp 宽度360 计算发放 360/10/2得到记得适配 for (int i = 0; i < 18; i++) { TimeBean timeBean = new TimeBean(); mList.add(timeBean); } for (int i = 0; i < 1440; i++) { int minute = i % 60; int hour = i / 60; if (CalendarUtil.getHourTime()==hour&&CalendarUtil.getMinuteTime()==minute){ mPostion = i; } TimeBean timeBean = new TimeBean(); timeBean.setHour(hour); timeBean.setMinute(minute); timeBean.setTimeDate(CalendarUtil.getHourToMinute(hour,minute)); mList.add(timeBean); } for (int i = 0; i < 18; i++) { TimeBean timeBean = new TimeBean(); // timeBean.setMinute(-1); mList.add(timeBean); } rv_data = findViewById(R.id.rv_data); mAdapter = new TimeAdapter(this, mList); rv_data.setAdapter(mAdapter); //设置字体 rv_data.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/dincond_boldalternate.ttf")); CenterLayoutManager layoutManager = new CenterLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); rv_data.setLayoutManager(layoutManager); rv_data.scrollToPosition(mPostion); rv_data.addOnScrollListener(new CenterScrollListener((lastItemPosition, position,count) -> { //更新文本和单位 rv_data.setText(mList.get(position).getTimeDate()); if (mList.get(position).getHour()>12){ rv_data.setTextUnit("PM"); }else { rv_data.setTextUnit("AM"); } })); }

实现了基本代码全部写了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。

最后

以上就是优美铃铛最近收集整理的关于Android自定义RecyclerView实现不固定刻度的刻度尺的全部内容,更多相关Android自定义RecyclerView实现不固定刻度内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(170)

评论列表共有 0 条评论

立即
投稿
返回
顶部