44import android .graphics .Camera ;
55import android .graphics .Canvas ;
66import android .graphics .Matrix ;
7+ import android .graphics .Paint ;
78import android .util .AttributeSet ;
89
910/**
@@ -23,45 +24,26 @@ public Wheel3DView(Context context, AttributeSet attrs) {
2324 mMatrix = new Matrix ();
2425 }
2526
26- /**
27- * @return 控件的预算宽度
28- */
29- public int getPrefWidth () {
30- int prefWidth = super .getPrefWidth ();
31- int innerHeight = (int ) (itemHeight * getVisibleItems () * 2 / Math .PI );
32- int towardRange = (int ) (Math .sin (Math .PI / 48 ) * innerHeight );
33- // 必须增加滚轮的内边距,否则当toward不为none时文字显示不全
34- prefWidth += towardRange ;
35- return prefWidth ;
36- }
37-
38- /**
39- * @return 控件的预算高度
40- */
27+ @ Override
4128 public int getPrefHeight () {
4229 int padding = getPaddingTop () + getPaddingBottom ();
43- int innerHeight = (int ) (itemHeight * getVisibleItems () * 2 / Math .PI );
30+ int innerHeight = (int ) (mItemHeight * mItemCount * 2 / Math .PI );
4431 return innerHeight + padding ;
4532 }
4633
47- /**
48- * 根据控件的测量高度,计算可见项的数量
49- */
50- public int getPrefVisibleItems () {
51- int innerHeight = getMeasuredHeight () - getPaddingTop () - getPaddingBottom ();
52- return (int ) (innerHeight * Math .PI / itemHeight / 2 );
53- }
54-
5534 protected void drawItem (Canvas canvas , int index , int offset ) {
5635 CharSequence text = getCharSequence (index );
5736 if (text == null ) return ;
5837 // 滚轮的半径
5938 final int r = (getHeight () - getPaddingTop () - getPaddingBottom ()) / 2 ;
6039 // 和中间选项的距离
61- final int range = (index - mScroller .getItemIndex ()) * itemHeight - offset ;
40+ final int range = (index - mScroller .getItemIndex ()) * mItemHeight - offset ;
6241 // 当滑动的角度和y轴垂直时(此时文字已经显示为一条线),不绘制文字
6342 if (Math .abs (range ) > r * Math .PI / 2 ) return ;
6443
44+ final int centerX = mClipRectMiddle .centerX ();
45+ final int centerY = mClipRectMiddle .centerY ();
46+
6547 final double angle = (double ) range / r ;
6648 // 绕x轴滚动的角度
6749 float rotate = (float ) Math .toDegrees (-angle );
@@ -76,62 +58,69 @@ protected void drawItem(Canvas canvas, int index, int offset) {
7658 // 透明度
7759 int alpha = (int ) (Math .cos (angle ) * 255 );
7860
79- int clipLeft = getPaddingLeft ();
80- int clipRight = getWidth () - getPaddingRight ();
81- int clipTop = getPaddingTop ();
82- int clipBottom = getHeight () - getPaddingBottom ();
83-
84- // 绘制两条分界线之间的文字
85- if (Math .abs (range ) <= 0 ) {
86- mPaint .setColor (getSelectedColor ());
87- canvas .save ();
88- canvas .translate (refractX , 0 );
89- canvas .clipRect (clipLeft , upperLimit , clipRight , lowerLimit );
90- drawText (canvas , text , 0 , translateY , translateZ , rotate );
91- canvas .restore ();
92- }
9361 // 绘制与下分界线相交的文字
94- else if (range > 0 && range < itemHeight ) {
95- mPaint .setColor (getSelectedColor ());
62+ if (range > 0 && range < mItemHeight ) {
9663 canvas .save ();
9764 canvas .translate (refractX , 0 );
98- canvas .clipRect (clipLeft , upperLimit , clipRight , lowerLimit );
99- drawText (canvas , text , 0 , translateY , translateZ , rotate );
65+ canvas .clipRect (mClipRectMiddle );
66+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mSelectedTextPaint );
10067 canvas .restore ();
10168
102- mPaint .setColor (getUnselectedColor ());
103- mPaint .setAlpha (alpha );
69+ mTextPaint .setAlpha (alpha );
10470 canvas .save ();
105- canvas .clipRect (clipLeft , lowerLimit , clipRight , clipBottom );
106- drawText (canvas , text , 0 , translateY , translateZ , rotate );
71+ canvas .clipRect (mClipRectBottom );
72+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mTextPaint );
73+ canvas .restore ();
74+ }
75+ // 绘制下分界线下方的文字
76+ else if (range >= mItemHeight ) {
77+ mTextPaint .setAlpha (alpha );
78+ canvas .save ();
79+ canvas .clipRect (mClipRectBottom );
80+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mTextPaint );
10781 canvas .restore ();
10882 }
10983 // 绘制与上分界线相交的文字
110- else if (range < 0 && range > -itemHeight ) {
111- mPaint .setColor (getSelectedColor ());
84+ else if (range < 0 && range > -mItemHeight ) {
11285 canvas .save ();
11386 canvas .translate (refractX , 0 );
114- canvas .clipRect (clipLeft , upperLimit , clipRight , lowerLimit );
115- drawText (canvas , text , 0 , translateY , translateZ , rotate );
87+ canvas .clipRect (mClipRectMiddle );
88+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mSelectedTextPaint );
11689 canvas .restore ();
11790
118- mPaint .setColor (getUnselectedColor ());
119- mPaint .setAlpha (alpha );
91+ mTextPaint .setAlpha (alpha );
92+ canvas .save ();
93+ canvas .clipRect (mClipRectTop );
94+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mTextPaint );
95+ canvas .restore ();
96+ }
97+ // 绘制上分界线上方的文字
98+ else if (range <= -mItemHeight ) {
99+ mTextPaint .setAlpha (alpha );
120100 canvas .save ();
121- canvas .clipRect (clipLeft , clipTop , clipRight , upperLimit );
122- drawText (canvas , text , 0 , translateY , translateZ , rotate );
101+ canvas .clipRect (mClipRectTop );
102+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mTextPaint );
123103 canvas .restore ();
124- } else {
125- mPaint . setColor ( getUnselectedColor ());
126- mPaint . setAlpha ( alpha );
104+ }
105+ // 绘制两条分界线之间的文字
106+ else {
127107 canvas .save ();
128- canvas .clipRect (clipLeft , clipTop , clipRight , clipBottom );
129- drawText (canvas , text , 0 , translateY , translateZ , rotate );
108+ canvas .translate (refractX , 0 );
109+ canvas .clipRect (mClipRectMiddle );
110+ drawText (canvas , text , centerX , centerY , 0 , translateY , translateZ , rotate , mSelectedTextPaint );
130111 canvas .restore ();
131112 }
132113 }
133114
134- private void drawText (Canvas canvas , CharSequence text , float translateX , float translateY , float translateZ , float rotateX ) {
115+ private void drawText (Canvas canvas ,
116+ CharSequence text ,
117+ float centerX ,
118+ float centerY ,
119+ float translateX ,
120+ float translateY ,
121+ float translateZ ,
122+ float rotateX ,
123+ Paint paint ) {
135124 mCamera .save ();
136125 mCamera .translate (translateX , 0 , translateZ );
137126 mCamera .rotateX (rotateX );
@@ -145,7 +134,10 @@ private void drawText(Canvas canvas, CharSequence text, float translateX, float
145134 mMatrix .preTranslate (-x , -y );
146135 mMatrix .postTranslate (x , y );
147136
137+ Paint .FontMetrics fontMetrics = paint .getFontMetrics ();
138+ int baseline = (int ) ((fontMetrics .top + fontMetrics .bottom ) / 2 );
139+
148140 canvas .concat (mMatrix );
149- canvas .drawText (text , 0 , text .length (), x , y - baseline , mPaint );
141+ canvas .drawText (text , 0 , text .length (), x , y - baseline , paint );
150142 }
151143}
0 commit comments