aesion / NodeProgressView

用来显示物流进度节点的自定义View,类似于淘宝
177 stars 36 forks source link

给NodeProgressView做了一点点优化 #2

Closed pardonhan closed 8 years ago

pardonhan commented 8 years ago

我也是刚开始学习自定义view。 主要是onDraw()方法里几个耗时的操作给摘出来了做了一点点的优化,希望多多指教

public class NodeProgressView extends View {
    float width;
    float nodeRadius;

    Paint paint;

    Context context;

    /**
     * 节点间隔
     */
    int nodeInterval;

    /**
     * 边距
     */
    int left = 20;
    int top = 30;

    int dWidth;
    int dHeight;

    Paint mPaint;
    TextPaint textPaint1;
    TextPaint textPaint2;
    NodeProgressAdapter nodeProgressAdapter;
    int count = 0;
    List data;

    public NodeProgressView(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public NodeProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NodeProgressView);
        width = typedArray.getDimension(R.styleable.NodeProgressView_width, 5);
        nodeRadius = typedArray.getDimension(R.styleable.NodeProgressView_nodeRadius, 10);
        init();
        typedArray.recycle();
    }

    public NodeProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(ContextCompat.getColor(getContext(), R.color.nodeColor));
        paint.setAntiAlias(true);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setColor(ContextCompat.getColor(getContext(), R.color.nodeTextColor));

        //画文字
        mPaint.setTextSize(30);

        textPaint1 = new TextPaint();
        textPaint1.setTextSize(35.0F);
        textPaint1.setAntiAlias(true);
        textPaint1.setColor(ContextCompat.getColor(getContext(), R.color.nodeTextColor));

        textPaint2 = new TextPaint();
        textPaint2.setTextSize(35.0F);
        textPaint2.setAntiAlias(true);
        textPaint2.setColor(ContextCompat.getColor(getContext(), R.color.nodeColor));
        nodeInterval = dip2px(context, 80);

        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);

        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);

        dWidth = dm.widthPixels;
        dHeight = dm.heightPixels;
        /*dWidth = wm.getDefaultDisplay().getWidth();
        dHeight = wm.getDefaultDisplay().getHeight();*/
    }
    /**
     * 设置适配数据
     */
    public void setNodeProgressAdapter(NodeProgressAdapter nodeProgressAdapter) {
        this.nodeProgressAdapter = nodeProgressAdapter;
        data = nodeProgressAdapter.getData();
        count = nodeProgressAdapter.getCount();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (nodeProgressAdapter == null || nodeProgressAdapter.getCount() == 0) {
            return;
        }
        // canvas.translate(20,30);偏移位置,防止遮挡
        canvas.drawRect(left, top, width + left, nodeProgressAdapter.getCount() * nodeInterval + top, paint);
        for (int i = 0 ; i < count; i++) {
            if (i == 0) {
                canvas.drawText(((LogisticsData) data.get(i)).getTime() + "", left * 2 + nodeRadius * 2 + 10, (i + 1) * nodeInterval + top - 20, mPaint);
                //canvas.drawText("不换行", left * 2 + nodeRadius * 2 + 10, i * nodeInterval + top + (nodeInterval / 3), mPaint);
                //文字换行
                StaticLayout layout = new StaticLayout(((LogisticsData) data.get(i)).getContext() + "", textPaint1, (int) (dWidth * 0.8), Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
                canvas.save();
                canvas.translate(left * 2 + nodeRadius * 2 + 10, i * nodeInterval + top + (nodeInterval / 4));
                layout.draw(canvas);
                canvas.restore();//重置
                //画圆
                canvas.drawCircle(width / 2 + left, i * nodeInterval + top, nodeRadius + 2, mPaint);
                mPaint.setStyle(Paint.Style.STROKE);//设置为空心
                mPaint.setStrokeWidth(8);//空心宽度
                mPaint.setAlpha(88);
                canvas.drawCircle(width / 2 + left, i * nodeInterval + top, nodeRadius + 4, mPaint);
            } else {
                paint.setColor(ContextCompat.getColor(getContext(), R.color.nodeColor));
                canvas.drawCircle(width / 2 + left, i * nodeInterval + top, nodeRadius, paint);
                canvas.drawLine(left * 2 + nodeRadius * 2, i * nodeInterval + top, dWidth, i * nodeInterval + top, paint); //画线
                //画文字
                paint.setTextSize(30);
                canvas.drawText(((LogisticsData) data.get(i)).getTime() + "", left * 2 + nodeRadius * 2 + 10, (i + 1) * nodeInterval + top - 20, paint);
                //文字换行
                StaticLayout layout = new StaticLayout(((LogisticsData) data.get(i)).getContext() + "", textPaint2, (int) (dWidth * 0.8), Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
                canvas.save();//很重要,不然会样式出错
                canvas.translate(left * 2 + nodeRadius * 2 + 10, i * nodeInterval + top + (nodeInterval / 4));
                layout.draw(canvas);
                canvas.restore();//重置
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (nodeProgressAdapter == null || nodeProgressAdapter.getCount() == 0)
            return;
        setMeasuredDimension(widthMeasureSpec, nodeProgressAdapter.getCount() * nodeInterval + top);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
aesion commented 8 years ago

互相学习了,我会逐一改正的