2013-04-17 12 views
11

Pasta grafik görünür olduğunda başlatarak animasyon uygulamak istediğim özel pasta grafik görünümü yaptım. Şu anda sahip olduğum pasta grafiği canlandırıyor ama gerçekte ekranda görebileceğiniz zaman animasyonun yarısı. Eğer herhangi bir programlama hataları, hafıza sızıntıları, yetersiz performans kod görürsenizAndroid iş parçacığı görünür görününceye kadar bekleyin

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); 
       } 
      } 
     } 
    } 
} 

Ayrıca lütfen bana bildirin: Bu aldığım şeydir. Android için yeniyim. İşte

SinglePieChart sınıfını kullanır düzenidir:

<?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> 
+0

Sorununuz nedir? – Blackbelt

+0

"Pasta grafik görünür olduğunda başlatarak animasyon yapmak istediğim özel bir pasta grafik görünümü yaptım. Şu an sahip olduğum pasta grafiği canlanıyor ama aslında ekranda görebileceğiniz zamana göre animasyonun yarısı bitiyor ." – chrislondon

+0

Özel SurfaceView'unuzu bir düzen içinde kullanıyor musunuz? – Blackbelt

cevap

5

otomatik olarak hareketli olarak benim pasta grafiği ile gidiyorum ve onu Etkinlik başlatmak için tetikleme yeni bir işleve sahip olacaktır Tamam Hazır olduğunda canlandırıyor. Keşke daha kolay bir yol olsaydı ...

1

Alternatif olarak, animation framework'u (veya daha eski apisleri desteklemek istiyorsanız nine old androids) kullanabilirsiniz. Bu, başlangıç ​​ve geçerli değişkenler durumunda, görünümünüzdeki özellikleri hareketlendirmenize izin verecektir.

Bunu, onAttachedToWindow sırasında olmasını isterim.

Bu pasta grafiğinde başka pek çok şey yapmıyorsanız, yüzey görünümü ihtiyaçlarınız için çok fazla olabilir.