etMode(widthMeasureSpec);
75 int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
76 int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
77 int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
78 int paddX = getPaddingLeft() + getPaddingRight();
79 int paddY = getPaddingTop() + getPaddingBottom();
80 //光圈的大小要考虑减去view的padding值
81 mCircleRadius = widthSpecSize - paddX < heightSpecSize - paddY ? (widthSpecSize - paddX) / 2
82 : (heightSpecSize - paddY) / 2;
83 //对布局参数为wrap_content时的处理
84 if (widthSpecMode == MeasureSpec.AT_MOST
85 && heightSpecMode == MeasureSpec.AT_MOST) {
86 setMeasuredDimension(WIDTH, HEIGHT);
87 mCircleRadius = (WIDTH - paddX) / 2;
88 } else if (widthSpecMode == MeasureSpec.AT_MOST) {
89 setMeasuredDimension(WIDTH, heightSpecSize);
90 mCircleRadius = WIDTH - paddX < heightSpecSize - paddY ? (WIDTH - paddX) / 2
91 : (heightSpecSize - paddY) / 2;
92 } else if (heightSpecMode == MeasureSpec.AT_MOST) {
93 setMeasuredDimension(widthSpecSize, HEIGHT);
94 mCircleRadius = widthSpecSize - paddX < HEIGHT - paddY ? (widthSpecSize - paddX) / 2
95 : (HEIGHT - paddY) / 2;
96 }
97 if (mCircleRadius < 1) {
98 mCircleRadius = 1;
99 }
100 //measure之后才能知道所需要绘制的光圈大小
101 mPath = new Path();
102 mPath.addCircle(0, 0, mCircleRadius, Path.Direction.CW);
103 createBlade();
104 }
105
106 @Override
107 public void onDraw(Canvas canvas) {
108 canvas.save();
109 calculatePoints();
110 //先把canbvas平移到view的中间
111 canvas.translate(getWidth() / 2, getHeight() / 2);
112 //让光圈的叶片整体旋转,更加贴合实际
113 canvas.rotate(ROTATE_ANGLE * (mCurrentApert - mMinApert) / (mMaxApert - mMinApert));
114 canvas.clipPath(mPath);
115 canvas.drawColor(mBackgroundColor);
116
117 for (int i = 0; i < 6; i++) {
118 canvas.save();
119 canvas.translate(mPoints[i].x, mPoints[i].y);
120 canvas.rotate(-i * 60);
121 canvas.drawBitmap(mBlade, 0, 0, mPaint);
122 canvas.restore();
123 }
124 canvas.restore();
125 }
126
127 @Override
128 public boolean onTouchEvent(MotionEvent event) {
129 if (event.getPointerCount() > 1) {
130 return false;
131 }
132 switch (event.getAction()) {
133 case MotionEvent.ACTION_DOWN:
134 mPrevX = event.getX();
135 mPrevY = event.getY();
136 break;
137 case MotionEvent.ACTION_MOVE:
138 float diffx = Math.abs((event.getX() - mPrevX));
139 float diffy = Math.abs((event.getY() - mPrevY));
140 if (diffy > diffx) { // 竖直方向的滑动
141 float diff = (float) Math.sqrt(diffx * diffx + diffy * diffy)
142 / mCircleRadius * mMaxApert;
143 if (event.getY() > mPrevY) { //判断方向
144 setCurrentApert(mCurrentApert - diff);
145 } else {
146 setCurrentApert(mCurrentApert + diff);
147 }
148 mPrevX = event.getX();
149 mPrevY = event.getY();
150 }
151 break;
152 default:
153 break;
154 }
155 return true;
156 }
157
158 private void calculatePoints() {
159 if (mCircleRadius - mSpace <= 0) {
160 Log.e(TAG, "the size of view is too small and Space is too large");
161 return;
162 }
163 //mCircleRadius - mSpace可以保证内嵌六边形在光圈内
164 float curRadius = mCurrentApert / mMaxApert * (mCircleRadius - mSpace);
165 //利用对称关系,减少计算
166 mPoints[0].x = curRadius / 2;
167 mPoints[0].y = -curRadius * COS_30;
168 mPoints[1].x = -mPoints[0].x;
169 mPoints[1].y = mPoints[0].y;
170 mPoints[2].x = -curRadius;
171 m |