2017-05-04 4 views
0

J'utilise Handler délai de poste pour appeler onDraw chaque fois que je veux dessiner nouveau rectangle, mais pour chaque nouveau rectangle effacer le précédent ..
Comment puis-je faire la toile garder le contenu de tous les rectangles: Mon code:dessiner plusieurs rectangles avec des retards entre les

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Rect; 
import android.os.CountDownTimer; 
import android.os.Handler; 
import android.util.Log; 

import com.adhamenaya.microchart.model.ChartData; 

import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.Map; 

/** 
* Created by Admin on 18/12/2016. 
*/ 

public class ColumnChart extends Chart implements Runnable { 

    private int mSpace = 0; 
    private int mColumnSize = 0; 
    private int mColumnsCount = 0; 
    private int mCurrentStart = 0; 
    private float mHeightUnit = 0; 
    private int mHeightDiff; 
    int columnIndex = 0; 

    private Handler mHandler; 
    private Canvas mCanvas; 
    private Iterator mDataIterator; 

    static final long FRAME_TIME = 100; 
    private ArrayList<Rect> rectangles = new ArrayList<Rect>(); 


    public ColumnChart(Context context) { 
     super(context); 
     mHandler = new Handler(); 
    } 

    @Override 
    protected void prepare() { 
     if (mChartData != null && mChartData.getSingleData().size() > 0) { 
      mColumnsCount = mChartData.getSingleData().size(); 

      // Column size, 1 is added to reserve a space at the end of the chart 
      mColumnSize = (int) ((mWidth/(mColumnsCount)) * 0.9); 

      // Calculate the space between the bars 
      mSpace = (mWidth/mColumnsCount) - mColumnSize; 

      // Calculate height unit 
      // Calculate 80% of the total height 
      float height08 = mHeight * 0.8f; 
      mHeightUnit = height08/mChartData.getMax(); 

      // Draw bars 
      mDataIterator = mChartData.getSingleData().entrySet().iterator(); 

      mMainPaint = getRectPaint(); 


      // Create rect objects 
      while (mDataIterator.hasNext()) { 
       Map.Entry entry = (Map.Entry) mDataIterator.next(); 

       int columnHeight = (int) ((int) entry.getValue() * mHeightUnit); 
       String key = (String) entry.getKey(); 

       // Shift the 
       mCurrentStart += mSpace; 

       // Calculate the difference between the total height and the height of the column 
       mHeightDiff = mHeight - columnHeight; 

       mCurrentStart += mColumnSize; 

       mDataIterator.remove(); 

       Rect rect = new Rect(mCurrentStart, mHeightDiff, 
         mCurrentStart + mColumnSize, mHeight); 
       rectangles.add(rect); 
      } 
     } 
    } 

    @Override 
    protected void paintChart(Canvas canvas) { 

    } 

    @Override 
    public void setData(ChartData data) { 
     this.mChartData = data; 
     prepare(); 
     mHandler.post(this); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     // Get measured height and width of the view 
     setMeasuredDimension(getMeasurement(widthMeasureSpec, mWidth), 
       getMeasurement(heightMeasureSpec, mHeight)); 

     // mWidth = MeasureSpec.getSize(widthMeasureSpec); 
     // mHeight = MeasureSpec.getSize(heightMeasureSpec); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     if(columnIndex > 0 && columnIndex<rectangles.size()) 
      canvas.drawRect(rectangles.get(columnIndex), getRectPaint()); 
    } 

    @Override 
    public void run() { 

     if(columnIndex<rectangles.size()){ 
      invalidate(); 
      columnIndex++; 
      mHandler.postDelayed(this,FRAME_TIME); 
     }else{ 
      mHandler.removeCallbacks(this); 
     } 
    } 
} 
+0

Où gardez-vous le r ects pour le dessin? – Krish

Répondre

0

Créer un FrameLayout sur lequel vous voulez dessiner des rectangles. Créez une vue chaque fois que vous dessinez un nouveau cercle. Dessinez un cercle sur la vue nouvellement créée et ajoutez cette vue à FrameLayout. L'arrière-plan de la vue sera transparent par défaut. Si ce n'est pas le cas, définissez l'arrière-plan comme transparent. De cette façon, vos rectangles précédents seront visibles et un nouveau rectangle sera dessiné sur les rectangles existants.

0

Vous êtes sur le point de le faire! Il suffit d'appeler vous préparer après avoir appelé la méthode invalidate.

@Override 
public void run() { 

    if(columnIndex<rectangles.size()){ 
     invalidate(); 
     columnIndex++; 
     mHandler.postDelayed(this,FRAME_TIME); 
    }else{ 
     mHandler.removeCallbacks(this); 
     eraseAll(); 
    } 
} 

...

public void eraseAll() { 
    this.canvas.drawColor(0, PorterDuff.Mode.CLEAR); 
    invalidate(); 
    prepare(); 
} 
+0

où appeler eraseAll? –

+0

Je modifie la question afin que vous puissiez voir. – matio

+0

Je ne peux pas obtenir le point de cette fonction eraseAll? Je veux garder tous les rectangles déjà dessinés. –

0

Pour moi, cette logique fonctionne très bien

@Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     if(columnIndex < rectangles.size()) { 
      for (int i = 0; i <= columnIndex; ++i) { 
       canvas.drawRect(rectangles.get(i), paint); 
      } 
     } 
    } 
0

Simplest diable est de garder l'objet de toile comme variable de niveau de classe et toujours tirer sur cet objet de toile et dans super.onDraw() passez sur cette toile, il gardera toujours vos rectangles précédents dessinés

+0

Voulez-vous dire une variable statique? Je l'ai fait, mais rien n'a changé –

+0

private Canvas mCanvas; @Override protected void onDraw (Canevas) {if (mCanvas == null) mCanvas = canvas; Pour pour (int i = 0; i <= columnIndex; } super.onDraw (mCanvas); } – Sunny