Android customView cómo calcular onMeasure para rellenar parent
Estoy tratando de dibujar una vista personalizada, todo se está haciendo bien, excepto la parte más derecha es cortada. Quiero que la vista llene el padre y sólo utilice la cantidad de altura necesaria (es decir, la altura del mapa de bits que estoy dibujando.) Cuando quito el relleno del diseño xml de la actividad la vista personalizada hace bien. Calculando onMeasure con el relleno de los padres tomado en cuenta.
Por favor, ¿alguien podría echar un vistazo a este código y describir por qué y cómo me voy mal? Gracias
- Diferencia entre hardware y software en Android
- Cómo agregar varias vistas al gestor de ventanas en Android
- ¿Qué son las constantes de orientación para las vistas?
- ¿Por qué no hay un método getContentView () para la actividad?
- Cómo deshabilitar la caché de dibujo?
EDITADO PARA incluir la respuesta de @ nicko y más detalles:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int parentHeight = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); ViewParent parent = getParent(); int leftPadding = 0; int rightPadding = 0; if (parent instanceof ViewGroup) { leftPadding = ((ViewGroup) parent).getPaddingLeft(); rightPadding = ((ViewGroup) parent).getPaddingRight(); } float wanabeHeight = calendar.getHeight(); float wanabeWidth = parentWidth - leftPadding - rightPadding; int height = 0; //Determine Height switch(heightMode){ case MeasureSpec.EXACTLY: height = parentHeight; break; case MeasureSpec.AT_MOST: height = Math.min((int)wanabeHeight, parentHeight); break; case MeasureSpec.UNSPECIFIED: default: height = (int)wanabeHeight; break; } setMeasuredDimension((int)wanabeWidth, height); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); calendarX = left; personX = (int)((right - left) * 0.5); checkX = right - check.getWidth() - getPaddingRight(); lineY = (int)((bottom - top) * 0.5); bitmapY = (int)(((bottom - top) * 0.5) - (calendar.getHeight() * 0.5)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(calendar, calendarX, bitmapY, paint); canvas.drawBitmap(person, personX, bitmapY, paint); canvas.drawBitmap(check, checkX, bitmapY, paint); canvas.drawLine((calendarX + calendar.getWidth() + PADDING), lineY, personX - PADDING, lineY, linePaint); canvas.drawLine((personX + person.getWidth() + PADDING), lineY, checkX - PADDING, lineY, linePaint); }
- Android: Duplicar el elemento View en el grupo ViewGroup
- Android: fitsSystemWindows no funciona
- ¿Es un Android ViewParent garantizado que es un Viewgroup?
- Diferencia entre SurfaceView y ImageView
- Android - Diferencia entre View.getResources () y View.getContext (). GetResources ()
- ¿Cómo cambiar el color de la lista de "final de desplazamiento" drag color?
- Cómo evitar el puntero nulo en View.getDrawingCache ()?
- Problema con revelación circular y CircularRevealLibrary en Android
En el onDraw
, todo es relativo al lienzo – pero parece que estás dibujando todo según las posiciones de vista que vienen a través de onLayout
que son relativas a la pantalla.
Por lo tanto, para su imagen de la mano derecha, realmente necesita calcular la posición X de esta manera:
checkX = right - left - check.getWidth();
Probablemente también encontrará que la imagen de la mano izquierda está sangría un poco si el padre tiene algún relleno, así que intente colocarlo en 0:
calendarX = 0;
Puede obtener el relleno de los padres de la siguiente manera:
ViewParent parent = getParent(); int topPadding = 0; int bottomPadding = 0; if (parent instanceof ViewGroup) { topPadding = ((ViewGroup) parent).getPaddingTop(); bottomPadding = ((ViewGroup) parent).getPaddingBottom(); }
Y usarlo:
parentHeight -= topPadding - bottomPadding; int height = 0; //Determine Height switch(heightMode){ case MeasureSpec.EXACTLY: height = parentHeight; break; case MeasureSpec.AT_MOST: height = Math.min((int)wanabeHeight, parentHeight); break; case MeasureSpec.UNSPECIFIED: default: height = (int)wanabeHeight; break; }
- ¿Cómo comprobar si el archivo es compatible con videoview android por código?
- Invalidar todos los tokens gcm