2011-02-10 26 views
12

我成功地將一個ViewGroup(RelativeLayout)轉換成使用畫布的位圖。但是,當繪圖發生時,我只能看到帶有其背景可繪製的ViewGroup,而不是其子節點(兩個TextView),它們應該使用像FILL_PARENT這樣的規則在RelativeLayout中進行佈局。Android的問題轉換ViewGroup與兒童到位圖

的RelativeLayout的是使用下面的靜態函數創建:

public static RelativeLayout createProgrammeView(Context context, int width, int height, String title, String time) { 
    RelativeLayout.LayoutParams params; 

    // Layout Root View (RelativeLayout) 
    RelativeLayout rlv = new RelativeLayout(context); 
    params = new RelativeLayout.LayoutParams(width, height); 
    rlv.setLayoutParams(params); 
    rlv.setPadding(3, 3, 3, 3); 
    rlv.setBackgroundResource(R.drawable.background); 

    // Layout Title 
    TextView tv = new TextView(context); 
    params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 
    tv.setId(R.id.title); 
    tv.setLayoutParams(params); 
    tv.setGravity(Gravity.CENTER_VERTICAL); 
    tv.setSingleLine(true); 
    tv.setEllipsize(TruncateAt.END); 
    tv.setTextColor(Color.parseColor("#fff")); 
    tv.setTextSize(11); 
    tv.setText(title); 
    rlv.addView(tv); 

    // Layout Start Time 
    tv = new TextView(context); 
    params = new RelativeLayout.LayoutParams(16, RelativeLayout.LayoutParams.WRAP_CONTENT); 
    params.addRule(RelativeLayout.BELOW, R.id.title); 
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT); 
    params.setMargins(0, 4, 0, 0); 
    tv.setId(R.id.time); 
    tv.setLayoutParams(params); 
    tv.setGravity(Gravity.CENTER_VERTICAL); 
    tv.setSingleLine(true); 
    tv.setEllipsize(null); 
    tv.setTextColor(Color.parseColor("#fff")); 
    tv.setTextSize(10); 
    tv.setText(time); 
    rlv.addView(tv); 
    } 

    return rlv; 
} 

然後我用下面打開的RelativeLayout成位圖:

public static Bitmap loadBitmapFromView(RelativeLayout v) { 
    Bitmap b = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.RGB_565); 
    Canvas c = new Canvas(b); 
    v.draw(c); 
    return b; 
} 

正如預期的那樣這給了我一個很好的位圖我需要的背景可繪製尺寸,但孩子不在位圖中。我將這些函數調用了很多,以構建一個大的圖像,然後在我的活動中將它們繪製到自定義視圖上。

這是調用靜態函數的循環:

public static void renderViews(final Context context) { 
    largeBitmap = Bitmap.createBitmap(largeWidth, largeHeight, Bitmap.Config.RGB_565); 
    Canvas largeCanvas = new Canvas(largeBitmap); 

    for (int i = 0; i < items.size(); i++) { 
     int leftMargin = ...SOME CALCULATIONS...; 

     RelativeLayout newView = createProgrammeView(context, width, rowHeight, "Title", "21:00"); 
     Bitmap newViewBitmap = loadBitmapFromView(newView); 

     largeCanvas.drawBitmap(newViewBitmap, leftMargin, 0, new Paint()); 
    } 

    myCustomView.invalidate(); 
} 

我的自定義視圖重寫的onDraw()函數:

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    canvas.drawBitmap(largeBitmap, 0, 0, null); 
} 

從我所看到的,我相信這是由於Android沒有按對子視圖調用度量()。我曾嘗試手動調用此方法,但這並不能解決問題。

所以,我想我想知道的是,我怎樣才能實現將一個帶孩子的RelativeLayout轉換成一個位圖,並讓Android來測量孩子,以便他們尊重他們的相對佈局規則。

非常感謝任何能夠幫助我解決問題的人。

羅布

回答

22

的問題是,你沒有衡量和佈局的容器。在繪圖工作之前,您必須先撥打v.measure(widthSpec, heightSpec),然後撥打v.layout(left, top, right, bottom)。第一種方法將確保視圖知道你想要的大小,第二種方法將確保兒童定位正確。

在你的情況,你會怎麼做:即基於DisplayMetrics的佈局可能是有用的,以及

v.measure(MeasureSpec.makeMeasureSpec(v.getLayoutParams().width, MeasureSpec.EXACTLY), 
     MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY)); 
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); 

Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565); 
Canvas c = new Canvas(b); 
v.draw(c); 
+0

非常好。非常感謝羅曼!我知道這與measure()和layout()有關,但我無法弄清楚如何將它整合起來。再次感謝。 – 2011-02-10 21:36:59