2011-02-10 38 views
12

Tôi đang chuyển đổi thành công một ViewGroup (RelativeLayout) thành Bitmap bằng Canvas. Tuy nhiên, khi việc vẽ xảy ra, tôi chỉ thấy ViewGroup với nền của nó có thể vẽ được và không phải con của nó (hai TextView), những người sẽ được đặt trong RelativeLayout sử dụng các quy tắc như FILL_PARENT.Các vấn đề về Android Chuyển đổi ViewGroup với trẻ em thành Bitmap

Các RelativeLayout được tạo ra bằng cách sử dụng chức năng tĩnh sau:

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

sau đó tôi sử dụng sau đây để biến RelativeLayout thành một Bitmap:

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

Đúng như dự đoán này mang lại cho tôi một Bitmap ngơi thoải mái tại kích thước mà tôi yêu cầu với nền có thể vẽ được, nhưng các em không có trong bitmap. Tôi gọi những hàm này khá nhiều để xây dựng một hình ảnh lớn và sau đó được vẽ lên một khung nhìn tùy chỉnh trong hoạt động của tôi.

Đây là vòng lặp mà gọi hàm tĩnh:

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(); 
} 

xem tùy chỉnh của tôi đè OnDraw() chức năng:

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

Từ những gì tôi có thể thấy tôi tin rằng điều này là vì Android doesn 't gọi một biện pháp() trên xem trẻ em. Tôi đã thử gọi điều này bằng tay, nhưng điều này không giải quyết được vấn đề. Vì vậy, tôi đoán những gì tôi muốn biết là, làm thế nào tôi có thể đạt được chuyển đổi một RelativeLayout với trẻ em thành một Bitmap và nhận được Android để đo lường trẻ em để họ tôn trọng quy tắc bố trí tương đối của họ.

Rất cám ơn bất kỳ ai có thể giúp tôi làm việc này.

Rob

Trả lời

22

Vấn đề là bạn không đo lường và bố trí các thùng chứa. Bạn phải gọi v.measure(widthSpec, heightSpec) và sau đó v.layout(left, top, right, bottom) trước khi bản vẽ có thể hoạt động. Phương pháp đầu tiên sẽ đảm bảo rằng khung nhìn biết bạn muốn nó lớn như thế nào, và phương pháp thứ hai sẽ đảm bảo các em được định vị đúng cách.

Trong trường hợp của bạn, bạn sẽ làm gì:

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

Tuyệt vời. Cảm ơn bạn rất nhiều Romain! Tôi biết nó là một cái gì đó để làm với đo() và bố trí(), nhưng tôi chỉ không thể làm việc ra làm thế nào để buộc nó tất cả lên. Cảm ơn một lần nữa. –

+0

Làm việc cho tôi. Cảm ơn! – Doigen

+0

Làm việc cho tôi. Cảm ơn .. –

0

Giải pháp đó dựa trên DisplayMetrics cho Layouts có thể hữu ích là tốt. Để không lặp lại - look here.

Các vấn đề liên quan