Note that there are some explanatory texts on larger screens.

plurals
  1. POAndroid thread wait until visible
    primarykey
    data
    text
    <p>I've made a custom pie chart view that I want to animate starting when the pie chart is visible. Currently what I have is the pie chart animating but by the time you can actually see it on the screen the animation is half over. This is what I have:</p> <pre><code>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 &lt; 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 &gt; degree) ? degree : last, false, circlePaint); start += (last &gt; number) ? number : last; last = (last &lt; number) ? 0 : last - number; circlePaint.setColor(emptyCircleCol); if (current &gt; 360) { current = 360; } canvas.drawArc(rect, start, 360 - current, false, circlePaint); current += speed; if (last &gt; 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); } } } } } </code></pre> <p>Also if you see any programming errors, memory leaks, poor performing code, please let me know. I'm new to Android.</p> <p>Here is the layout that uses the SinglePieChart class:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;merge xmlns:android="http://schemas.android.com/apk/res/android"&gt; &lt;RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"&gt; &lt;com.davidscoville.vokab.views.elements.SinglePieChart android:id="@+id/smallPieChart" android:layout_width="match_parent" android:layout_height="match_parent" /&gt; &lt;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" /&gt; &lt;/RelativeLayout&gt; &lt;TextView android:id="@+id/dashSmLabel" android:layout_width="match_parent" android:layout_height="20dp" android:textSize="14sp" android:gravity="center" android:textColor="#FFFFFF" /&gt; &lt;/merge&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload