2012-01-02 2 views
6

最近私はカスタムビューグループの作成を掘り下げており、わからない問題が発生しました。カスタムビューグループ内のビューが表示されない

私は2 ViewGroups持っている - あなたが見ることができるよう

記事は、いくつかのTextViewsとImageViewのを配置ViewManager条

ViewManagerは単純に(垂直のLinearLayoutのようなつまり)、前条以下の条をレイアウトします画像。 1つの記事を作成してViewManagerに追加するとうまくいき、すべてが表示されますが、2番目の記事を追加すると、記事のコンテンツは表示されません。

Illustrates second view not showing

はなぜ(onDrawでcanvas.drawRect()()で描画された青色のバーに注意してください)TextViewsか現れてImageViewののどれもありません。私はまた、(logcatを経由して)子ビューのバインド値をプリントアウトしている(つまり、getLeft()/ TOP()/右()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; 

} 

サイドノートで、これのようなmakeMeasureSpec()のパラメータとしてLayoutParams.WRAP_CONTENTを使用しても問題ありませんか?

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

あなたは正しい答えを投稿できますか?私は理解していません –

答えて

8

onLayoutでは、子供はその親に対して配置されるべきです。子の座標にtop(およびleft)を追加しています。 topleftはゼロであるため、これは最初の記事で問題にはなりません。 2番目の記事では、leftはまだ0ですが、topはViewManagerの2番目の記事の先頭です。 newTopnewLeftを取り除き、代わりにそれぞれmarginTopouterMarginを使用してください。

脇に:makeMeasureSpecの最初の引数はディメンションになっています。 WRAP_CONTENTを使用すると、最大ディメンションを-2に設定しています。これはおそらく実行したくないものです。

+0

ありがとう、両方のカウントで、すぐに働いた – triggs

+2

Upvote for * onLayoutでは、子供は親*を基準に配置する必要があります。 – neevek

+1

私にとっては、ViewGroupから継承したように、カスタムビューのOnLayoutメソッドをオーバーライドしていましたが、OnLayoutに実装コードを追加していないという問題がありました。 OnLayoutに厄介な測位コードを書くのではなく、RelativeLayoutから継承してから、OnLayoutメソッドを完全に削除することができました。 – Justin