不知不觉已经出来工作了7个月,今天刚刚好转正一个月了,花了1个多月的时间,在公司完成了android集成RN的项目。做的时候真的遇到好多坑,还好都一一解决了。O(∩_∩)O哈哈~,做完这个项目又闲下来的。好想有项目迭代!!!
效果图--录屏软件录的有点差
实现步骤---思路
- 设置转盘的宽高
- 绘制圆形背景
- 绘制转盘
- 绘制转盘上的文字和图片
- 转盘的旋转动画以及监听
- 指定旋转的位置
在onMeasure上设置转盘的宽高---我在布局中设置了padding=30dp
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = MeasureSpec.getSize(widthMeasureSpec);
int h = MeasureSpec.getSize(heightMeasureSpec);
int width = Math.min(w, h);
//圆心点
mCenter = width / 2;
//半径
mRadius = (width - getPaddingLeft() * 2) / 2;
//设置框高都一样
setMeasuredDimension(width, width);
}
绘制圆形背景--- canvas.drawCircle(cx,cy,radius,paint);
canvas.drawCircle(mCenter, mCenter, mCenter - getPaddingLeft() / 2, mBgPaint);
绘制转盘
//设置扇形绘制的范围
sectorRectF = new RectF(getPaddingLeft(), getPaddingLeft(),
mCenter * 2 - getPaddingLeft(), mCenter * 2 - getPaddingLeft());
for (int i = 0; i < mCount; i++) {
//扇形的颜色
mArcPaint.setColor(sectorColor[i % 2]);
//sectorRectF 扇形绘制范围 startAngle 弧开始绘制角度
//sweepAngle 每次绘制弧的角度
// useCenter 是否连接圆心
canvas.drawArc(sectorRectF, startAngle, sweepAngle, true, mArcPaint);
startAngle += sweepAngle;
}
看看效果了---背景原的半径比转盘的半径多了paddingleft()/2
绘制转盘上的文字需要使用到的方法
path.addArc--------添加圆弧路径
canvas.drawTextOnPath------根据路径绘制文字
private void drawTexts(Canvas canvas, String mString) {
Path path = new Path();
//添加一个圆弧的路径
path.addArc(sectorRectF, startAngle, sweepAngle);
String startText = null;
String endText = null;
//测量文字的宽度
float textWidth = mTextPaint.measureText(mString);
//水平偏移
int hOffset = (int) (mRadius * 2 * Math.PI / mCount / 2 - textWidth / 2);
//计算弧长 处理文字过长换行
int l = (int) ((360 / mCount) * Math.PI * mRadius / 180);
if (textWidth > l * 4 / 5) {
int index = mString.length() / 2;
startText = mString.substring(0, index);
endText = mString.substring(index, mString.length());
float startTextWidth = mTextPaint.measureText(startText);
float endTextWidth = mTextPaint.measureText(endText);
//水平偏移
hOffset = (int) (mRadius * 2 * Math.PI / mCount / 2 - startTextWidth / 2);
int endHOffset = (int) (mRadius * 2 * Math.PI / mCount / 2 - endTextWidth / 2);
//文字高度
int h = (int) ((mTextPaint.ascent() + mTextPaint.descent()) * 1.5);
//根据路径绘制文字
canvas.drawTextOnPath(startText, path, hOffset, mRadius / 6, mTextPaint);
canvas.drawTextOnPath(endText, path, endHOffset, mRadius / 6 - h, mTextPaint);
} else {
//根据路径绘制文字
canvas.drawTextOnPath(mString, path, hOffset, mRadius / 6, mTextPaint);
}
}
弧长公式 length=圆心角度数xMath.PIx半径/180 计算到弧长之后根据的需要修改
绘制转盘上的图片
求出x,y的坐标 利用三角函数
y=sin(角度)×raduis/2+mCenter
x=cos(角度)×raduis/2+mCenter
private void drawIcons(Canvas canvas, Bitmap mBitmap) {
int imageWidth = mRadius / 10;
//计算半边扇形的角度 度=Math.PI/180 弧度=180/Math.PI
float angle = (float) ((startAngle + sweepAngle / 2) * Math.PI / 180);
//计算中心点的坐标
int r = mRadius / 2;
float x = (float) (mCenter + r * Math.cos(angle));
float y = (float) (mCenter + r * Math.sin(angle));
//设置绘制图片的范围
RectF rectF = new RectF(x - imageWidth, y - imageWidth, x + imageWidth, y + imageWidth);
canvas.drawBitmap(mBitmap, null, rectF, null);
}
转盘的旋转动画监听以及指定旋转的位置
先看个图片canvas.drawArc()绘制的开始点
canvas.drawArc() 在右边x轴正方向开始绘制
指针指向的方向是270度,旋转方向为顺时针,现在这里有10个扇形就是每个占了36°,当旋转了36°,指针指向的是黄忠。我这里写以尴尬差点中奖为第0个元素,那么第1个元素就是元歌,如果我想要元歌的英雄旋转的度数就是369,公式:360/个数×(个数-位置)*
怎么获取到旋转的信息呢?
使用:Arrays.binarySearch()
public void rotate(final int i) {
rotateToPosition = 360 / mCount * (mCount - i);
float toDegree = 360f * 5 + rotateToPosition;
animator = ObjectAnimator.ofFloat(PieView.this, "rotation", 0, toDegree);
animator.setDuration(5000);
animator.setRepeatCount(0);
animator.setInterpolator(new DecelerateInterpolator());
animator.setAutoCancel(true);
animator.start();
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
//指针指向的方向为270度
if (listener != null) {
rotateToPosition = 270 - rotateToPosition;
if (rotateToPosition < 0) {
rotateToPosition += 360;
} else if (rotateToPosition == 0) {
rotateToPosition = 270;
}
position = -Arrays.binarySearch(angles, rotateToPosition) - 1;
listener.value(mStrings[position - 1]);
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
源码