Подтвердить что ты не робот

Поток Android до тех пор, пока не появится

Я создал настраиваемое графическое представление, которое я хочу оживить, начиная с круговой диаграммы. В настоящее время у меня есть анимация круговой диаграммы, но к тому времени, когда вы можете увидеть ее на экране, анимация наполовину. Это то, что у меня есть:

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>
4b9b3361

Ответ 1

Хорошо, что я собираюсь с моей круговой диаграммой, не будет автоматически анимироваться, и у нее будет новая функция, которую действие инициирует, чтобы начать анимацию, как только она будет готова. Хотелось бы, чтобы был более простой способ...

Ответ 2

В качестве альтернативы вы можете использовать рамки анимации (или девять старых андроидов, если вы хотите поддерживать более старый apis). Это позволит вам анимировать свойства на вашем представлении, в вашем случае стартовые и текущие переменные.

Я установил бы это во время onAttachedToWindow.

Обратите внимание, что если вы не делаете много других вещей в этой круговой диаграмме, то видимость поверхности может быть излишней для ваших нужд.