2012-01-02 4 views
6

Recientemente he profundizado en la creación de grupos de visualización personalizados y he encontrado un problema que no puedo resolver.Las vistas dentro de un grupo de vista personalizado no muestran

tengo 2 ViewGroups - ViewManager y el artículo

ViewManager simplemente expone un artículo a continuación del artículo anterior (es decir, como un LinearLayout vertical)

artículo organiza varios TextViews y un ImageView como se puede ver en el imagen. Crear un solo artículo y agregarlo a ViewManager funciona bien y todo se muestra, pero cuando agrego un segundo artículo, no se ve nada del contenido del artículo.

Illustrates second view not showing

¿Por qué son ninguno de los TextViews o el ImageView a aparecer (tenga en cuenta que la barra azul se extrae con canvas.drawRect() en onDraw()). También imprimí (a través de logcat) los valores encuadernados de las vistas secundarias (es decir, getLeft()/Top()/Right()/Bottom() en drawChild() y todas 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 artículo método 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 al margen, ¿está bien usar LayoutParams.WRAP_CONTENT como parámetro para makeMeasureSpec() de esta manera?

MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.AT_MOST) 
+0

puede publicar la respuesta correcta. No entiendo –

Respuesta

8

En onLayout, los niños deben colocar con respecto a sus padres. Usted está agregando top (y left) a las coordenadas de los niños. Eso no es un problema para el primer artículo porque top y left son cero. Para el segundo artículo, left sigue siendo cero, pero top es la parte superior del segundo artículo en su ViewManager. Deshágase de newTop y newLeft y use, respectivamente, marginTop y outerMargin en su lugar.

En cuanto a su lado: el primer argumento para makeMeasureSpec se supone que es una dimensión. Al usar WRAP_CONTENT, está configurando la dimensión máxima en -2, que probablemente no sea lo que quiere hacer.

+0

Gracias, en ambos casos, funcionó de inmediato – triggs

+2

Votación a favor * En la primera página, los niños deben estar posicionados con respecto a la vista de su padre *. – neevek

+1

Para mí, el problema era que anulaba el método OnLayout de mi vista personalizada, ya que he heredado de ViewGroup, y sin embargo, no había agregado ningún código de implementación en OnLayout. En lugar de tener que escribir un código de posicionamiento desagradable en OnLayout, he heredado de RelativeLayout y luego pude eliminar el método OnLayout por completo. – Justin

Cuestiones relacionadas