我制作了一个自定义饼图 View ,希望在该饼图可见时对其进行动画处理。目前,我拥有的动画是饼图动画,但是等到您实际在屏幕上看到动画时,动画就结束了一半。这就是我所拥有的:

public class SinglePieChart extends SurfaceView implements SurfaceHolder.Callback {
    // Chart setting variables
    private int emptyCircleCol, strokeColor, number, total;

    // Paint for drawing custom view
    private Paint circlePaint;

    private RectF rect;

    private Context context;
    private AnimThread animThread;
    private SurfaceHolder holder;

    // animation variables
    private float speed;
    private float current = 0.0f;
    private boolean percentsCalculated = false;
    private float degree;
    private int viewWidth, viewHeight;

    public SinglePieChart(Context ctx, AttributeSet attrs) {
        super(ctx, attrs);

        context = ctx;

        // Paint object for drawing in doDraw
        circlePaint = new Paint();
        circlePaint.setStyle(Style.STROKE);
        circlePaint.setStrokeWidth(3);
        circlePaint.setAntiAlias(true);
        circlePaint.setDither(true);


        rect = new RectF();

        //get the attributes specified in attrs.xml using the name we included
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
            R.styleable.DashboardChartSmall, 0, 0);

        try {
            //get the colors specified using the names in attrs.xml
            emptyCircleCol = a.getColor(R.styleable.DashboardChartSmall_smCircleColor, 0xFF65676E); // light gray is default
            strokeColor    = a.getColor(R.styleable.DashboardChartSmall_smColor, 0xFF39B54A); // green is default

            // Default number values
            total  = a.getInteger(R.styleable.DashboardChartSmall_smTotal,  1);
            number = a.getInteger(R.styleable.DashboardChartSmall_smNumber, 0);
        } finally {
            a.recycle();
        }

        this.setZOrderOnTop(true);

        holder = getHolder();
        holder.setFormat(PixelFormat.TRANSPARENT);

        holder.addCallback(this);
    }

    protected void calculateValues() {
        degree = 360 * number / total;
        percentsCalculated = true;
        speed = 10 * number / total;
        viewWidth  = this.getMeasuredWidth();
        viewHeight = this.getMeasuredHeight();

        float top, left, bottom, right;

        if (viewWidth < viewHeight) {
            left = 4;
            right = viewWidth - 4;
            top = ((viewHeight - viewWidth) / 2) + 4;
            bottom = viewHeight - top;
        } else {
            top = 4;
            bottom = viewHeight - 4;
            left = ((viewWidth - viewHeight) / 2) + 4;
            right = viewWidth - left;
        }

        rect.set(left, top, right, bottom);
    }

    protected void doDraw(Canvas canvas) {
        if (total == 0) {
            // Number values are not ready
            animThread.setRunning(false);
            return;
        }

        if (!percentsCalculated) {
            calculateValues();
        }

        // set the paint color using the circle color specified
        float last = current;
        float start = -90;

        circlePaint.setColor(strokeColor);
        canvas.drawArc(rect, start, (last > degree) ? degree : last, false, circlePaint);
        start += (last > number) ? number : last;
        last = (last < number) ? 0 : last - number;

        circlePaint.setColor(emptyCircleCol);

        if (current > 360) {
            current = 360;
        }

        canvas.drawArc(rect, start, 360 - current, false, circlePaint);

        current += speed;

        if (last > 0 || number == 0) {
            // we're done
            animThread.setRunning(false);
        }
    }

    public void setNumbers(int num, int tot) {
        number = num;
        total  = tot;

        invalidate();
        requestLayout();
    }


    public void setColor(int col) {
        strokeColor = col;
    }

    public void redraw() {
        calculateValues();
        animThread.setRunning(true);

        invalidate();
        requestLayout();
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        animThread = new AnimThread(holder, context, this);
        animThread.setRunning(true);
        animThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        animThread.setRunning(false);

        boolean retry = true;

        while(retry) {
            try {
                animThread.join();
                retry = false;
            } catch(Exception e) {
                Log.v("Exception Occured", e.getMessage());
            }
        }
    }

    public class AnimThread extends Thread {
        boolean mRun;
        Canvas mcanvas;
        SurfaceHolder surfaceHolder;
        Context context;
        SinglePieChart msurfacePanel;

        public AnimThread(SurfaceHolder sholder, Context ctx, SinglePieChart spanel) {
            surfaceHolder = sholder;
            context = ctx;
            mRun = false;
            msurfacePanel = spanel;
        }

        void setRunning(boolean bRun) {
            mRun = bRun;
        }

        @Override
        public void run() {
            super.run();
            while (mRun) {
                mcanvas = surfaceHolder.lockCanvas();
                if (mcanvas != null) {
                    msurfacePanel.doDraw(mcanvas);
                    surfaceHolder.unlockCanvasAndPost(mcanvas);
                }
            }
        }
    }
}

另外,如果您发现任何编程错误,内存泄漏,性能不佳的代码,请告诉我。我是Android的新手。

这是使用SinglePieChart类的布局:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
        <com.davidscoville.vokab.views.elements.SinglePieChart
            android:id="@+id/smallPieChart"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/dashSmNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:textSize="25sp"
            android:textColor="#FFFFFF" />

    </RelativeLayout>

    <TextView
        android:id="@+id/dashSmLabel"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:textSize="14sp"
        android:gravity="center"
        android:textColor="#FFFFFF" />
</merge>

最佳答案

好的,我要处理的饼形图不会自动设置动画,它将具有一个新功能,一旦准备好,Activity将触发该功能以开始制作动画。我希望有一个更简单的方法...

关于Android线程等到可见,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16060690/

10-11 07:59