2012-10-24 20 views
35
public class MainActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     TableView tv = new TableView(this); 
     tv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); 
     setContentView(tv);  
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 
} 

public class TableView extends ViewGroup { 
    private Paint oval; 
    private RectF rect; 

    public TableView(Context context) { 
     super(context); 
     oval= new Paint(Paint.ANTI_ALIAS_FLAG); 
     oval.setColor(Color.GREEN); 
    } 


    public void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawOval(rect , oval); 
    } 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     int wspec = MeasureSpec.makeMeasureSpec(
       getMeasuredWidth(), MeasureSpec.EXACTLY); 
     int hspec = MeasureSpec.makeMeasureSpec(
       getMeasuredHeight(), MeasureSpec.EXACTLY); 
     for(int i=0; i<getChildCount(); i++){ 
      View v = getChildAt(i); 
      v.measure(wspec, hspec); 
     } 
    } 


    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     float w=r-l; 
     float h=b-t; 
     rect=new RectF(w/8,h/8,7*w/8,7*h/8); 
     float theta = (float) (2 * Math.PI/getChildCount()); 
     for(int i=0; i< getChildCount(); i++) { 
      View v = getChildAt(i); 
      w = (rect.right-rect.left)/2; 
      h = (rect.bottom-rect.top)/2; 
      float half = Math.max(w, h)/2; 
      float centerX = rect.centerX()+w*FloatMath.cos(theta); 
      float centerY = rect.centerY()+h*FloatMath.sin(theta); 
      v.layout((int)(centerX-half),(int)(centerY-half),(int)(centerX+half),(int)(centerY+half)); 
     } 
    } 
} 

Beh ci sono quasi nessuno buone e tutorial profonde e quasi nessun pezzo di dati su come fare layout personalizzati a destra, così ho cercato di capire come il suo fare, che cosa Sto cercando di implementare un layout che dipinge un ovale verde al centro dello schermo e voglio che ogni bambino di questo layout sia disposto attorno all'ovale.Android personalizzato Layout - OnDraw() non viene mai chiamato

si può pensare a quell'ovale come a un tavolo da poker che voglio che i bambini di questo layout si siedano attorno ad esso.

Cosa accade attualmente con questo codice è che ottengo un bianco scren app senza ovale, così ho il debug e vide che OnDraw non viene mai chiamato ...

3 domande:

  1. perché è onDraw non viene chiamato?
  2. lo sdk mi avverte che non devo allocare nuovi oggetti nel metodo onLayout, quindi dove dovrei calcolare il RectF in modo che sia pronto per la chiamata onDraw a venire?
  3. la chiamata a super.onDraw() farebbe dipingere tutti i bambini da soli? o dovrei invocare esplicitamente il loro draw()?

Se ho sbagliato tutto e voi ragazzi potete guidarmi nella giusta direzione, o avere qualche link ad esempi o tutorial relativi a questo argomento che sarebbe utile anche!

risposta

119

Per impostazione predefinita, onDraw() non viene chiamato per gli oggetti ViewGroup. Invece, è possibile ignorare dispatchDraw().

In alternativa, è possibile abilitare il disegno ViewGroup chiamando lo setWillNotDraw(false) nel costruttore .

See: Romain Guy's explanation

EDIT:

Per 2 #: - inizializzare nel costruttore, quindi basta chiamare rect.set() nel metodo onLayout().

Per n. 3: - Sì, per quanto a mia conoscenza la chiamata super sarà gestita, non è necessario gestirla a meno che non sia necessario personalizzare il modo in cui i bambini sono disegnati.

+0

grande che ha funzionato, grazie !, e che dire le mie altre domande? –

+0

@kcoppock
Il nome del metodo menzionato è ** non ** 'setWillNotDrawEnabled', ma semplicemente' setWillNotDraw' (metodo pubblico del 'View'class). – lambruscoAcido

0

Se si desidera che la tela è essere ri-disegnare chiamata invalidate(), e il metodo OnDraw() verrà nuovamente eseguito

Problemi correlati