Las vistas dentro de un Grupo de vistas personalizado no se muestran
Recientemente he investigado la creación de ViewGroups personalizados y he encontrado un problema que no puedo entender.
Tengo 2 ViewGroups – ViewManager y el artículo
- Barra de desplazamiento a ViewGroup personalizado
- Agregar y eliminar un TextView dinámicamente en Android
- Cómo agregar un marcador pin en la vista de la imagen en android
- Cómo obtener el índice de una vista particular (personalizada) de ViewGroup (FrameLayout) después de hacer onLongClick en la vista
- Estado de envío de los controles compuestos
ViewManager simplemente establece un artículo por debajo del artículo anterior (es decir, como un LinearLayout vertical)
El artículo organiza varios TextViews y un ImageView como se puede ver en la imagen. Creación de un solo artículo y su adición a ViewManager funciona bien y todo se muestra, pero cuando agrego un segundo artículo no es visible el contenido del artículo.
Entonces, ¿por qué no aparecen ninguno de los TextViews o el ImageView (nota que la barra azul está dibujada con canvas.drawRect () en onDraw ()). También he impreso (vía logcat) los valores enlazados de las vistas secundarias (es decir, getLeft () / Top () / Right () / Bottom () en drawChild () y todos parecen estar bien
FIRST TextView FIRST left 5 right 225 top 26 bottom 147 FIRST TextView FIRST left 5 right 320 top 147 bottom 198 FIRST TextView FIRST left 5 right 180 top 208 bottom 222 FIRST ImageView FIRST left 225 right 315 top 34 bottom 129 SECOND TextView SECOND left 10 right 53 top 238 bottom 257 SECOND TextView SECOND left 5 right 325 top 257 bottom 349 SECOND TextView SECOND left 5 right 320 top 349 bottom 400 SECOND TextView SECOND left 5 right 180 top 410 bottom 424
¿Así que alguien tiene una idea de lo que he hecho mal?
El método del artículo onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); specWidth = widthSpecSize; int totalHeight=0; int width = 0; if(mImage!=null&&mImage.getParent()!=null){ measureChild(mImage,MeasureSpec.makeMeasureSpec(100, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(100, MeasureSpec.AT_MOST)); width=widthSpecSize-mImage.getWidth(); imageWidth = mImage.getMeasuredWidth(); } for(int i = 0;i<this.getChildCount();i++){ final View child = this.getChildAt(i); //get the width of the available view minus the image width if(imageWidth > 0) width =widthSpecSize- imageWidth; else width = widthSpecSize; //measure only the textviews if(!(child instanceof ImageView)){ measureChild(child, MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), heightMeasureSpec); //calculate total height of the views, used to set the dimension totalHeight+=child.getMeasuredHeight(); } } //if the title height is greater than the image then the snippet //can stretch to full width if(mTitle.getMeasuredHeight()>mImage.getMeasuredHeight()) measureChild(mSnippet, MeasureSpec.makeMeasureSpec(widthSpecSize, MeasureSpec.AT_MOST), heightMeasureSpec); //measure source to make it full width measureChild(mSource,MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST), heightMeasureSpec); setMeasuredDimension(widthSpecSize, totalHeight); }
Y el método onLayout
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int newLeft = left+outerMargin; int newTop = top+marginTop; int prevHeight = 0; if(mEngine!=null){ int height = mEngine.getMeasuredHeight(); int childRight = newLeft+mEngine.getMeasuredWidth(); mEngine.layout(newLeft+marginLeft, newTop+prevHeight+2, childRight+marginLeft, newTop+height+prevHeight+2); maxRight = Math.max(maxRight, childRight); prevHeight += height+2; topBarHeight = mEngine.getMeasuredHeight()+(marginLeft*2); maxBottom = Math.max(maxBottom, mEngine.getBottom()); } if(mTitle!=null){ int height = mTitle.getMeasuredHeight(); int childRight = newLeft+mTitle.getMeasuredWidth(); mTitle.layout(newLeft, newTop+prevHeight, childRight, newTop+height+prevHeight); maxRight = Math.max(maxRight, childRight); prevHeight += height; maxBottom = Math.max(maxBottom, mTitle.getBottom()); } if(mSnippet!=null){ int height = mSnippet.getMeasuredHeight(); int childRight = newLeft+mSnippet.getMeasuredWidth(); mSnippet.layout(newLeft, newTop+prevHeight, right, newTop+height+prevHeight); maxRight = Math.max(maxRight, childRight); prevHeight += height; maxBottom = Math.max(maxBottom, mSnippet.getBottom()); } if(mSource !=null){ int height = mSource.getMeasuredHeight(); int childRight = newLeft+mSource.getMeasuredWidth(); mSource.layout(newLeft, newTop+prevHeight+(marginTop*2), childRight, newTop+height+prevHeight+(marginTop*2)); maxRight = Math.max(maxRight, childRight); prevHeight += height; maxBottom = Math.max(maxBottom, mSource.getBottom()); } if(mImage!=null){ int height = mImage.getMeasuredHeight(); log("mxW "+maxRight); int childRight = maxRight+mImage.getMeasuredWidth(); mImage.layout(right-mImage.getMeasuredWidth()+5, newTop+topBarHeight, right-5, height+topBarHeight); totalWidth = childRight; maxBottom = Math.max(maxBottom, mImage.getBottom()); }else totalWidth = maxRight; }
En una nota lateral está bien usar LayoutParams.WRAP_CONTENT como un parámetro para makeMeasureSpec () como este?
MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST)
- Escala de diseño relativo personalizado?
- Proceso de construcción de Android secreto
- Android: usando MotionEvent para arrastrar y soltar el posicionamiento de vistas en un grupo de vistas personalizado
- Vistas dentro de un grupo de vistas personalizado que no se representan después de un cambio de tamaño
- Android: obtener Viewgroup de la vista?
- NullPointerException: Intento de leer del campo 'int android.view.View.mViewFlags'
- Construcción de un contenedor capaz de hacer zoom
- Android en la vista eliminado de los padres
En onLayout
, los niños deben ser posicionados con respecto a sus padres. Usted está agregando top
(ya la left
) a las coordenadas de los niños. Eso no es un problema para el primer artículo porque top
e left
son cero. Para el segundo artículo, la left
sigue siendo cero, pero top
es la parte superior del segundo artículo en su ViewManager. Simplemente deshágase de newTop
y newLeft
y use, respectivamente, marginTop
y outerMargin
en su lugar.
Respecto a su aparte: el primer argumento a makeMeasureSpec
se supone que es una dimensión. Al usar WRAP_CONTENT, está estableciendo la dimensión máxima en -2, lo que probablemente no sea lo que desea hacer.
- Android: ¿Cómo configurar el selector de spinner para poseer imagen / icono?
- ¿Cómo conectarse con un dispositivo Bluetooth pareado programático en Android?