studio programacion herramientas fundamentos con avanzado aplicaciones android layout view viewgroup

programacion - Diseño personalizado de Android-onDraw() nunca se llama



manual de android en pdf (2)

De forma predeterminada, onDraw() no se llama para los objetos ViewGroup . En cambio, puede anular el dispatchDraw() .

Alternativamente, puede habilitar el dibujo de setWillNotDraw(false) llamando a setWillNotDraw(false) en su constructor TableView .

Ver: explicación de Romain Guy

EDITAR:

Para # 2: - Inicialízalo en el constructor, luego simplemente llama a rect.set() en tu método onLayout() .

Para # 3: - Sí, hasta donde yo sé, la super llamada lo manejará, no debería tener que manejar eso a menos que necesite personalizar la forma en que se dibujan los niños.

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

Bueno, hay casi NINGUNOS buenos y profundos tutoriales y casi ningún dato sobre cómo hacer diseños personalizados, así que traté de entender cómo se hizo, lo que estoy tratando de implementar es un diseño que pinta un óvalo verde en el centro. de la pantalla, y quiero que todos los niños de este diseño se desplieguen alrededor del óvalo.

Puedes pensar en ese óvalo como una mesa de póquer que quiero que los niños de este diseño se sienten alrededor de él.

Lo que ocurre actualmente con este código es que obtengo una aplicación blanca scren sin óvalo, así que la depuré y vi que onDraw nunca se llama ...

3 preguntas:

  1. ¿Por qué no se llama a onDraw?
  2. el SDK me advierte que no debería asignar nuevos objetos dentro del método onLayout, entonces, ¿dónde debería calcular el RectF para que esté listo para la próxima llamada onDraw?
  3. ¿Llamar a super.onDraw () haría que todos los niños se pinten? o debería invocar explícitamente su dibujo ()?

Si lo entendí todo mal y ustedes pueden guiarme en la dirección correcta, o tienen algún enlace a ejemplos o tutoriales relacionados con este tema que también serían útiles.


Si desea que el lienzo se vuelva a dibujar, llame a invalidate (), y se volverá a ejecutar el método onDraw ()