how can I display a programmatically created ImageView on top of a previously created View Canvas? I tried using bringToFront(), but without success.
Code:
RelativeLayout root = findViewById(R.id.layout);
ImageView img = new ImageView(GameGuessActivity.context);
img.setImageResource(R.drawable.image);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width, height);
params.leftMargin = x;
params.topMargin = y;
root.addView(img, params);
img.bringToFront();
The Image is being displayed, but underneath the canvas, which I don't want.
You have to redraw your imageview on canvas:
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bitmap, 0, 0, null);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
image.draw(pcanvas);
img.bringToFront();
img.invalidate();
img.draw(pcanvas);
Related
image is set in imageview. I draw text successfully on image with the help of below code.
BitmapFactory.Options myOptions = new BitmapFactory.Options();
myOptions.inDither = true;
myOptions.inScaled = false;
myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
myOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.awais, myOptions);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
Bitmap workingBitmap = Bitmap.createBitmap(bitmap);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
// canvas.drawCircle(60, 50, 25, paint);
canvas.drawText(String.valueOf(f), h, w, paint);
imageView.setAdjustViewBounds(true);
imageView.setImageBitmap(mutableBitmap);
but I want draw Buttons on image with different height and width.
If you already define your imageView inside relative layout in xml than just instantiate it by findViewById
//RelativeLayout relativeLayout =(RelativeLayout)(findViewById(.....));
otherwise dynamically create relative layout like this
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
relativeLayout.setLayoutParams(lp);
relativeLayout.addView(imageview);
//than create button dynmaically
Button b = new Button(this);
b.setText("Button");
RelativeLayout.LayoutParams btnrl = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
btnrl.addRule(RelativeLayout.ALIGN_BOTTOM);
b.setLayoutParams(btnrl);
relativeLayout.addView(b);
**Edit:**
In case you want arbitrary width and height than set button with and height like this
int width = 0; // assign your width
int height = 0; // assign your height
RelativeLayout.LayoutParams btnrl = new RelativeLayout.LayoutParams(
width,height);
btnrl.addRule(RelativeLayout.ALIGN_BOTTOM);
b.setLayoutParams(btnrl);
I added a button and a point in my project and put the point and button in the relative layout and set them same params like this code:
rllp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
rllp.topMargin = 0 ;
rllp.leftMargin = 0 ;
rllp2 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
rllp2.topMargin = 0 ;
rllp2.leftMargin = 0 ;
drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
.getDefaultDisplay().getWidth(), (int) getWindowManager()
.getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawingImageView.setImageBitmap(bitmap);
Paint paint = new Paint();
paint.setStrokeWidth(6);
drawingImageView.setLayoutParams(rllp);
canvas.drawPoint(0, 0, paint);
btn = (Button) findViewById(R.id.button1);
btn.setLayoutParams(rllp2);
but result is not what I wanted!! the button and the point is not in the same position ... and I was going to put both of them in the (0,0).
I think problem is here:
Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
.getDefaultDisplay().getWidth(), (int) getWindowManager()
.getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
but I don't have any solution for this ... how can I set their position in one place??
it's the picture of result :
http://i.stack.imgur.com/IWx7V.png
I want to put the point at the top-left corner of the button.
I think bitmap width and height make this ploblem... can I draw a line without using bitmap??
This is my code. I am Getting null value. i was trying to find out the solution since morning, i have created layout by using xml file then i got the bitmap of view, but i want it dynamically and I have created layout programatically see bellow code.
My view is appearing fine but still getting getDrawingCache() null bitmap
LinearLayout mainlayout = new LinearLayout(getApplicationContext());
mainlayout.setOrientation(LinearLayout.VERTICAL);
mainlayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
ImageView top= new ImageView(getApplicationContext());
ImageView bot= new ImageView(getApplicationContext());
Bitmap bottomImage = BitmapFactory.decodeResource(getResources(), R.drawable.collagebot);
Bitmap topImage =BitmapFactory.decodeResource(getResources(), R.drawable.collagetop);
top.setImageBitmap(topImage);
bot.setImageBitmap(bottomImage);
LinearLayout midLayout = new LinearLayout(getApplicationContext());
midLayout.setOrientation(LinearLayout.HORIZONTAL);
midLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
Bitmap midlaybg =BitmapFactory.decodeResource(getResources(), R.drawable.bg);
Drawable middrow = new BitmapDrawable(getResources(),midlaybg);
midLayout.setBackground(middrow);
ImageView right= new ImageView(getApplicationContext());
ImageView left= new ImageView(getApplicationContext());
Bitmap rightImage = BitmapFactory.decodeResource(getResources(), R.drawable.fb);
Bitmap leftImage =BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
Drawable rightdrow = new BitmapDrawable(getResources(),rightImage);
Drawable leftdrow = new BitmapDrawable(getResources(),leftImage);
right.setBackground(rightdrow);
left.setBackground(leftdrow);
right.setLayoutParams(new LayoutParams(150,150));
left.setLayoutParams(new LayoutParams(150,150));
left.setLayoutParams(new LinearLayout.LayoutParams(150, 150, 10));
midLayout.setPadding(50, 0, 0, 0);
midLayout.addView(right);
midLayout.addView(left);
mainlayout.addView(top);
mainlayout.addView(midLayout);
mainlayout.addView(bot);
Bitmap mainlaybg =BitmapFactory.decodeResource(getResources(), R.drawable.bg);
Drawable maindrow = new BitmapDrawable(getResources(),mainlaybg);
mainlayout.setBackground(maindrow);
mainlayout.setDrawingCacheEnabled(true);
mainlayout.buildDrawingCache();
// setContentView(mainlayout); // i dont want to setContentView
Log.e("ceche",""+mainlayout.getDrawingCache());// here i am getting null bitmap of mainlayout view
Bitmap imgb=mainlayout.getDrawingCache();
mainlayout.measure(MeasureSpec.makeMeasureSpec(
mainlayout.getLayoutParams().width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(
mainlayout.getLayoutParams().height,
MeasureSpec.EXACTLY));
mainlayout.layout(0, 0, mainlayout.getMeasuredWidth(),
mainlayout.getMeasuredHeight());
mainlayout.setDrawingCacheEnabled(true);
final Bitmap bitmap_ = Bitmap
.createBitmap(mainlayout.getDrawingCache());
mainlayout.setDrawingCacheEnabled(true);
i write text on a picture with this code :
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.file);
Canvas g = new Canvas(mBitmap);
Paint p = new Paint();
p.setColor(Color.BLACK);
p.setAntiAlias(true);
g.drawText("Text", 10, 10, p);
How can i show result in a imageview ?
thanks
Create an ImageView (if you don't have one in your layout), and use setImageDrawable() :
ImageView image = new ImageView(this);
image.setImageDrawable(new BitmapDrawable(mBitmap));
Then add your ImageView to your layout with addView().
I'm successfully converting a ViewGroup (RelativeLayout) into Bitmap using a Canvas. However, when the draw happens I only see the ViewGroup with its background drawable and not its children (two TextViews) who should be laid out within the RelativeLayout using rules like FILL_PARENT.
The RelativeLayout is created using the following static function:
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;
}
I then use the following to turn the RelativeLayout into a 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;
}
As expected this gives me a nice Bitmap in the dimensions that I require with the background drawable, but the children are not in the bitmap. I call these functions quite a lot to build a large image which then gets drawn onto a custom view in my activity.
This is the loop which calls the static function:
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();
}
My custom view overrides the onDraw() function:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(largeBitmap, 0, 0, null);
}
From what I can see I believe this is because Android doesn't call a measure() on the child Views. I have tried calling this manually, but this doesn't solve the problem.
So, I guess what I would like to know is, how can I achieve converting a RelativeLayout with children into a Bitmap and get Android to measure the children so they respect their relative layout rules.
Many thanks to anyone who can help me work this out.
Rob
The problem is that you did not measure and layout the container. You must call v.measure(widthSpec, heightSpec) and then v.layout(left, top, right, bottom) before drawing can work. The first method will make sure the view knows how big you want it to be, and the second method will ensure the children are positioned properly.
In your case you would do:
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);
Solution that based on DisplayMetrics for the Layouts could be useful as well. In order not to repeat - look here .