无标题文章

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; //矩形左上,右下角两点坐标
  1. Matrix:Android提供的一个矩阵工具类,它本身不能对图像或View进行变换,但它可与其他API结合来控制图形、 View的变换,如Canvas。
  2. RectF :矩形左上,右下角两点坐标
  3. 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));
      }
      

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容