2011-02-10 13 views
12

Udało mi się przekonwertować ViewGroup (RelativeLayout) na Bitmapę używając Canvas. Jednak w momencie losowania widzę tylko grupę ViewGroup z tłem do rysowania, a nie jej dzieci (dwa widoki tekstowe), które powinny zostać ułożone w RelativeLayout przy użyciu reguł takich jak FILL_PARENT.Problemy z Androidem Konwertowanie ViewGroup z dziećmi na bitmapę

RelativeLayout tworzony jest za pomocą następującego statyczną funkcję:

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

Następnie używać następujących czynności, aby włączyć RelativeLayout w 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; 
} 

Zgodnie z oczekiwaniami to daje mi piękny bitmapę w wymiary, których wymagam, z tłem do rysowania, ale dzieci nie znajdują się w bitmapie. Te funkcje często nazywam budowaniem dużego obrazu, który następnie zostanie narysowany w widoku niestandardowym w mojej działalności.

Jest to pętla, która wywołuje funkcję statycznego:

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

Mam zwyczaj widok przesłania OnDraw() funkcja:

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

Z tego co widzę, że to dlatego, że Android nie robi Wywołanie metody measure() na widokach podrzędnych. Próbowałem wywoływać to ręcznie, ale to nie rozwiązuje problemu.

Zgaduję, co chciałbym wiedzieć, jak mogę przekonwertować RelativeLayout z dziećmi na Bitmapę i sprawić, by Android mierzył dzieci tak, aby respektowały one reguły względnego układu.

Wielkie dzięki dla każdego, kto może mi pomóc to rozwiązać.

Rob

Odpowiedz

22

Problemem jest to, że że nie mierzyć i układ pojemnika. Musisz zadzwonić pod numer v.measure(widthSpec, heightSpec), a następnie v.layout(left, top, right, bottom), zanim zaczniesz działać. Pierwsza metoda sprawi, że widok będzie wiedział, jak duża ma być, a druga metoda zapewni prawidłowe rozmieszczenie dzieci.

W twoim przypadku to zrobić:

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

Doskonały. Dziękuję bardzo Romain! Wiedziałem, że to ma coś wspólnego z measure() i layout(), ale nie mogłem pojąć, jak to wszystko powiązać. Dzięki jeszcze raz. –

+0

Pracowałem również dla mnie. Dzięki! – Doigen

+0

Pracowałem również dla mnie. Dzięki .. –

0

Rozwiązanie to opiera się na DisplayMetrics dla układów mogą być przydatne również. Aby nie powtarzać - look here.

Powiązane problemy