Is it possible to add TextView and ImageView on canvas?
Canvas does not inherit from ViewGroup, so it does not have the ability to add child views to it.
With Canvas, you use drawBitmap and drawText methods to draw images and text instead of adding child controls like TextView and ImageView.
It's a round about way, but this tutorial adds a textview to his canvas:
http://www.helloandroid.com/tutorials/how-draw-multiline-text-canvas-easily
If you need to freely position ImageViews and TextViews, you should use a RelativeLayout.
The RelativeLayout has advanced positioning features and allows overlapping.
- put your view (which is using canvas) inside the RelativeLayout,
public class YourComponent extends View{
#Override
protected void onDraw(Canvas canvas)
...
public void onDraw(){
....
....
ImageView yourImageView = .....
RelativeLayout.LayoutParams fParams = new RelativeLayout.LayoutParams(25,25);
fParams.leftMargin = 100; //x coordinate
fParams.topMargin = 25; /y coordinate
yourImageView.setLayoutParams(fParams);
((RelativeLayout) YourComponent.this.getParent()).addView(yourImageView);
}
}
above code : i created layout params which shows 25x25 dimensions for view. and after that , i used margins to set proper position on the parent layout. and set this LayoutParams to ImageView. and for last, i added this imageView to parent Layout.
But beware that during the onDraw() execution, calling operation on external view may stop onDraw(). so if you want to use this way be sure you already completed all onDraw operation.
I am not so sure why this happens. I did not try to observe too much on it yet.
Related
I wanted to implement a custom view which is combined by a ImageView and a TextView like this.
A class called IconTextView is created by extending TextView, and the onDraw function was rewrittend by this.
#Override
protected void onDraw(Canvas canvas)
{
if (bitmap != null)
{
//something are done before
canvas.drawBitmap(bitmap, src, target, getPaint());
canvas.translate(target.right + 2, 0);
}
super.onDraw(canvas);
}
Then a IconTextView was added into the main layout like this.
<com.liujilong.carson.icontextview.IconTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
mobile:iconSrc="#drawable/ic_launcher"
android:text="myIconTextView"
android:textSize="30sp"
/>
The IconTextView shown in my phone like this.
Sorry that i can not post picture.
The problem is that the width of the View was still the width of the TextView, and I translated the canvas. So the text could not show totally.
How can I change the width of the IconTextView?
I don't think you should have to do anything as drastic as override onDraw.
You could just have a horizontal LinearLayout that has an ImageView and a TextView
Even simpler, you can set the left drawable of the TextView using the the attribute android:drawableLeft="#drawable/my_icon". If you have to change it in code, the corresponding method is TextView.setCompoundDrawablesWithIntrinsicBounds(int,int,int,int). The images would have to be set up as drawable resources for this to work.
Is there something special about your custom view that these ideas won't work?
I have a custom view which is a RelativeLayout which contains a ListView (both are set to match parent - width and height).
On top of the list I have a View as seen in the picture below:
I want that the only part that will be drawn is the rect of my View (marked with gray), while all the other portion of the view will be transparent.
is there a way I can do this?
I already tried to extend RelativeLayout and override its onDraw() method, but I didn't manage to draw only the specific region (marked in gray).
Eventually, I did it by extending RelativeLayout and override its draw() method.
#Override
protected void draw(Canvas canvas) {
canvas.clipRect(magnifiedRegion.getLeft(), magnifiedRegion.getTop(), magnifiedRegion.getRight(), magnifiedRegion.getBottom());
super.draw(canvas);
}
where magnifiedRegion is my View as it mentioned in the question above.
Note: you must set this.setWillNotDraw(false); in the constructor or else, draw() method won't be called by the framework (since our root view is a ViewGroup - it's an optimization Android framework does by default).
I have a class that extends View that I draw into.
In spite of the fact that the view is set up as a child to a RelativeLayout that has specific dimensions, the View's canvas reports that it is 1280 wide (which is as wide as the device).
I'm trying to understand what I need to do to have the canvas be constrained by the dimensions of its View (as common sense would dictate).
Curious what I'm overlooking... here are the relevant code snippets...
dv = new DrawView(this, getWindowManager());
dv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
//this wrapper is 500x500
((RelativeLayout)findViewById(R.id.drawWrapper)).addView(dv);
L.log("DRAWVIEW WIDTH = " + dv.getWidth()); //this reports 0... why?
inside DrawView...
#Override
public void onDraw(Canvas canvas) {
L.log("CANVAS WIDTH ON DRAW = " + canvas.getWidth()); //this always reports 1280 on xoom
this.canvas = canvas;
drawElementsOntoCanvas(canvas, true, false);
...
}
Is there something I'm overlooking or is the canvas inside a View always the width and height of the entire screen?
The XML for the relative layout:
<RelativeLayout
android:id="#+id/drawWrapper"
android:layout_width="500px"
android:layout_height="500px"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dip"
android:clipChildren="true"
android:background="#drawable/cut_out_frame"
/>
Ah, now I see it :)
You have clipChildren = true but this applies to the containing layout. Child views can draw outside the bounds of their parent but the drawing will simply be clipped to the parent dimensions.
It seems that here, you are using the window manager to construct your DrawView
dv = new DrawView(this, getWindowManager());
dv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
Without seeing the constructor, I am guessing that the subsequent setLayoutParams is using FILL_PARENT, i.e. the entire screen.
If I were you, I would implement the standard constructors for your DrawView and then lay it out in the layout XML. This is the "Android" way. You can also override onMeasure() to track how big DrawView is, storing the x and y in internal fields, which you can use to do any scaling you need. That way, if your layout every changes (orientation change, different resolution support, new version) your code doesn't need to change.
Finally, never (unless you REALL know why) use PX in layouts. Use DIP instead.
Within the onDraw() method of the view, I paint a small line. When the view is dynamically added to my layout, it takes up the entire screen. How can I make sure the view is the size of my line that I drew?
In Constructor write this :
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(WidthOfYourLine,HeightOfYourLine);
this.setLayoutParams(lp);
I am a beginner android developer and I am trying to have a button display on top of the bitmaps I am outputting.
Here is what I have:
my activity sets this:
setContentView(new FrameView(this));
FrameView is a class that extends View:
public FrameView(Context context) {
super(context);
setFocusable(false);
Inside FrameView I have
#Override protected void onDraw(Canvas canvas){
...
canvas.drawBitmap(image1.getBitmap(), 0, 0, null);
...
}
main.xml is FrameLayout that I stuck a button on top of, that's it.
I guess my question is, how do I insert something into the main.xml as a "canvas" in order to paste my bitmaps to, but still have the button always on top regardless of how many bitmaps i draw?
Use a RelativeLayout. Put your "canvas" as the first child, sized and positioned as you see fit. Put your button as the second child, sized and positioned as you see fit. Your button will "float" over your "canvas", because later children of a RelativeLayout are higher on the Z axis.