2012-01-02 4 views
6

최근에 사용자 지정보기 그룹을 만들려고했는데 알아 내지 못하는 문제가 발생했습니다.사용자 지정보기 그룹 내의보기가 표시되지 않습니다.

ViewManager 단순히 (수직의 LinearLayout 같은 예) 이전 제 아래 제

의 기사 몇 TextViews하고에서 볼 수있는 이미지 뷰를 배치를 낳는 ViewManager 조 -

나는 2 ViewGroups이 영상. Article One을 만들고 ViewManager에 추가하면 모든 것이 표시되지만 두 번째 Article을 추가하면 Article의 내용 중 아무 것도 볼 수 없습니다.

Illustrates second view not showing

는 왜 (의 onDraw에서 canvas.drawRect()()로 그려진 파란색 막대를 주) TextViews 또는 최대 보여주는 이미지 뷰의 아무도 없습니다. 또한 (로그 캣을 통해) 아이 뷰의 바운드 값을 인쇄 한 (즉 메쏘드 getLeft()/탑()/오른쪽() drawChild에서/아래()() 그들은 모두 잘 볼 것 같다

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 

그래서 아무도 내가 잘못 한 일의 아이디어가 있습니까?

문서 된 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); 
} 

과 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; 

} 

참고로 LayoutParams.WRAP_CONTENT를 makeMeasureSpec()의 매개 변수로 사용하는 것이 좋습니까?

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

정답을 게시 할 수 있습니까? 나는 이해하지 못했다 –

답변

8

onLayout에서 어린이는 부모를 기준으로 배치해야합니다. 어린이 좌표에 top (및 left)을 추가하고 있습니다. topleft이 0이므로 문제가되지 않습니다. 두 번째 기사의 경우 left은 여전히 ​​0이지만 top이 ViewManager의 두 번째 기사 상단입니다. newTopnewLeft을 제거하고 각각 marginTopouterMargin을 대신 사용하십시오.

제쳐두고 : makeMeasureSpec의 첫 번째 인수는 차원으로 간주됩니다. WRAP_CONTENT를 사용하여 최대 치수를 -2로 설정하고 있습니다. 원하는 치수가 아닐 수 있습니다.

+0

감사합니다. 두 번 모두 똑바로 작동했습니다. – triggs

+2

Upvote for * onLayout에서 자녀는 부모 *와 관련하여 배치되어야합니다. – neevek

+1

내게있어서 ViewGroup에서 상속 받았던 OnLayout 메서드를 내 사용자 지정보기에 적용했지만 OnLayout에 구현 코드를 추가하지 않은 것이 문제였습니다. OnLayout에 불쾌한 위치 지정 코드를 작성하는 대신 RelativeLayout에서 상속 한 다음 OnLayout 메서드를 완전히 제거 할 수있었습니다. – Justin