PieChart 笔记
1. 一个接口 Listener
OnCurrentItemChangedListener :监听 item 变化
看一下定义:
public interface OnCurrentItemChangedListener {
void OnCurrentItemChanged(PieChart source, int currentItem);
}
2. 四个内部类
Item :存储 Item 的信息
PieView : 饼图
PointerView : 小黑点
GestureListener :继承自 extends GestureDetector.SimpleOnGestureListener,自定义手势监听器
1. Item
/* 保存 item 状态信息 */
private class Item {
public String mLabel; //标签
public float mValue; // 值
public int mColor; // 颜色
// computed values
public int mStartAngle; // 开始角度
public int mEndAngle; // 结束角度
public int mHighlight; // 高亮
public Shader mShader; // 着色器
}
2. PieView
- 首先定义3个参数
private class PieView extends View {
// Used for SDK < 11 why? SDK < 11 不支持属性动画 Animator
private float mRotation = 0; //旋转
private Matrix mTransform = new Matrix(); //3x3的矩阵
private PointF mPivot = new PointF(); //中心点
RectF mBounds; //矩形左上,右下角两点坐标
Matrix
:Android提供的一个矩阵工具类,它本身不能对图像或View进行变换,但它可与其他API结合来控制图形、 View的变换,如Canvas。RectF
:矩形左上,右下角两点坐标PointF
:圆点圆心坐标
- 重写的方法
@Override //在onLayout 内调用
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mBounds = new RectF(0, 0, w, h);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); //单纯继承 View,此方法为空,do nothing
if (Build.VERSION.SDK_INT < 11) {
mTransform.set(canvas.getMatrix());
mTransform.preRotate(mRotation, mPivot.x, mPivot.y);
canvas.setMatrix(mTransform);
}
for (Item it : mData) {
mPiePaint.setShader(it.mShader);
canvas.drawArc(mBounds, //绘制圆弧,椭圆或圆的边界
360 - it.mEndAngle, //起始角度
it.mEndAngle - it.mStartAngle, //顺时旋转角度
true, //如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形
mPiePaint); //绘制圆弧的画板属性,如颜色,是否填充等
}
}
- 开启硬件加速
private void setLayerToHW(View v) {
if (!v.isInEditMode() && Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
}
3. PointerView
@Override
protected void onDraw(Canvas canvas) {
canvas.drawLine(mTextX, mPointerY, mPointerX, mPointerY, mTextPaint);
canvas.drawCircle(mPointerX, mPointerY, mPointerRadius, mTextPaint);
}
4. GestureListener
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
// Set the pie rotation directly.
float scrollTheta = vectorToScalarScroll(
distanceX,
distanceY,
e2.getX() - mPieBounds.centerX(), //e1 是down事件,e2 是move事件
e2.getY() - mPieBounds.centerY());
setPieRotation(getPieRotation() - (int) scrollTheta / FLING_VELOCITY_DOWNSCALE);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// Set up the Scroller for a fling
float scrollTheta = vectorToScalarScroll(
velocityX,
velocityY,
e2.getX() - mPieBounds.centerX(),
e2.getY() - mPieBounds.centerY());
mScroller.fling(
0,
(int) getPieRotation(),
0,
(int) scrollTheta / FLING_VELOCITY_DOWNSCALE,
0,
0,
Integer.MIN_VALUE,
Integer.MAX_VALUE);
// Start the animator and tell it to animate for the expected duration of the fling.
if (Build.VERSION.SDK_INT >= 11) {
mScrollAnimator.setDuration(mScroller.getDuration());
mScrollAnimator.start();
}
return true;
}
@Override
public boolean onDown(MotionEvent e) {
// The user is interacting with the pie, so we want to turn on acceleration
// so that the interaction is smooth.
mPieView.accelerate();
if (isAnimationRunning()) {
stopScrolling();
}
return true;
}
}
3. PieChart 实现
-
构造方法
public PieChart(Context context, AttributeSet attrs) { super(context, attrs); // attrs contains the raw values for the XML attributes // that were specified in the layout, which don't include // attributes set by styles or themes, and which may have // unresolved references. Call obtainStyledAttributes() // to get the final values for each attribute. // // This call uses R.styleable.PieChart, which is an array of // the custom attributes that were declared in attrs.xml. TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.PieChart, 0, 0 ); try { // Retrieve the values from the TypedArray and store into // fields of this class. // // The R.styleable.PieChart_* constants represent the index for // each custom attribute in the R.styleable.PieChart array. mShowText = a.getBoolean(R.styleable.PieChart_showText, false); mTextY = a.getDimension(R.styleable.PieChart_labelY, 0.0f); mTextWidth = a.getDimension(R.styleable.PieChart_labelWidth, 0.0f); mTextHeight = a.getDimension(R.styleable.PieChart_labelHeight, 0.0f); mTextPos = a.getInteger(R.styleable.PieChart_labelPosition, 0); mTextColor = a.getColor(R.styleable.PieChart_labelColor, 0xff000000); mHighlightStrength = a.getFloat(R.styleable.PieChart_highlightStrength, 1.0f); mPieRotation = a.getInt(R.styleable.PieChart_pieRotation, 0); mPointerRadius = a.getDimension(R.styleable.PieChart_pointerRadius, 2.0f); mAutoCenterInSlice = a.getBoolean(R.styleable.PieChart_autoCenterPointerInSlice, false); } finally { // release the TypedArray so that it can be reused. a.recycle(); } // 初始化 Paint、Scroller, addView init(); }
-
isInEditMode
// In edit mode it's nice to have some demo data, so add that here. if (this.isInEditMode()) { Resources res = getResources(); addItem("Annabelle", 3, res.getColor(R.color.bluegrass)); addItem("Brunhilde", 4, res.getColor(R.color.chartreuse)); addItem("Carolina", 2, res.getColor(R.color.emerald)); addItem("Dahlia", 3, res.getColor(R.color.seafoam)); addItem("Ekaterina", 1, res.getColor(R.color.slate)); }
-
网友评论