I have a customview looking like this:
public class CustomView extends View {
protected Context c;
protected String text;
... // and some more useful member variables...
public CustomView(String text, Context c, ...) {
this.text = text; this.c = c;
...
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
LinearLayout ll = new LinearLayout(c);
TextView tv = new TextView(c);
tv.setText(text);
ll.addView(tv);
ll.draw(canvas);
}
And in my main activity, I do this:
RelativeLayout gamelayout = (RelativeLayout) findViewById(R.id.gamelayout);
CustomView customview = new CustomView("Textview text", this);
gamelayout.addView(customview);
My problem is, that simply nothing is drawn, the drawn TextView does not appear in the "gamelayout". What am I doing wrong?
TextView objects are not able to draw directly to the canvas, as you've done you need to assign to a Layout and then do this:
ll.layout(0, 0, canvas.getWidth(), canvas.getHeight()); //Modify values as needed
Personally, I'm surprised there aren't errors thrown for calling ll.draw(). Unless you have a need to drawing a TextView I prefer drawing the text to the canvas:
canvas.drawText(...)
See documentation here
Your LinearLayout isn't attached to your view
try this.addView(ll) to add your LinearLayout to your view.
Related
In Android, I have a TextView and its content will be dynamic. I want to show a horizontal line after each line of text. I have searched a lot and found it for EditText( How to use ruled/horizontal lines to align text in EditText in Android?). I was planing to draw dynamic TextView and a horizontal line under them. But I don't know how can I detect an end of line. Any help will be highly appreciated. I want to have the same effect as the attached image of How to use ruled/horizontal lines to align text in EditText in Android?
I'm using the technique of drawing lines between each line of text in EditText and then I will make the EditText non-editable by setting setKeyListener(null) to the custom EditText object so that, the EditText acts like a TextView :)
A custom EditText that draws lines between each line of text that is displayed:
public class LinedEditText extends EditText {
private Rect mRect;
private Paint mPaint;
// we need this constructor for LayoutInflater
public LinedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mRect = new Rect();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(0x800000FF);
}
#Override
protected void onDraw(Canvas canvas) {
int count = getLineCount();
Rect r = mRect;
Paint paint = mPaint;
for (int i = 0; i < count; i++) {
int baseline = getLineBounds(i, r);
canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
}
super.onDraw(canvas);
}
}
Now use object of LinedEditText class where you need your TextView and make it non-editable.
An Example:
public class HorizontalLine extends Activity{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Android: Ruled/horizonal lines in Textview");
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
LayoutParams textViewLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
LinedEditText et = new LinedEditText(this, null);
et.setText("The name of our country is Bangladesh. I am proud of my country :)");
et.setLayoutParams(textViewLayoutParams);
et.setKeyListener(null);
ll.addView(et);
this.setContentView(ll);
}
}
et.setKeyListener(null) makes the EditText non-editable so, it acts like a TextView.
The Output:
Issue with cursor:
If you use et.setKeyListener(null) only then it is just not listening to keys but
user can see a cursor on the EditText. If you don't want this cursor just disable the EditText by adding this line:
et.setEnabled(false);
You can use a View for drawing line: For horizontal line:
<View
android:layout_height="1dp"
android:layout_width="fill_parent"
android:background="#ffffff" />
<TextView
android:layout_height="1dp"
android:layout_width="fill_parent"/>
I have a LinearLayout within a ScrollView in the xml file. I need to paint and write within the ScrollView so I've created a view in the layout and have been able to paint and write inside using: canvas.draw() and canvas.drawText(), my problem comes when writing text with canvas are not clearly the letters, so I need to add a TextView to the layout of the ScrollView from the class, without knowing very well how to do it.
Paste the code:
public class Calendario extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
MyView v = new MyView(this);
layout.addView(v,250,2000);
}
private class MyView extends View{
public MyView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
onDrawMethod();
//Here draw and write text//
}
}
}
A picture of what I need: I need only add textviews inside
Thankss
As I understand you, you want to add those texts programmaticaly, by saying
so I need to add a TextView to the layout of the ScrollView from the class
If so, might be this post will help you.
I've created a bar that is supposed to contain multiple views of different colors. A line has to be drawn that indicates the current position in the bar. Below is my simplified code:
public class Abar extends LinearLayout {
final Paint line_paint = new Paint();
private Context context;
public Abar(Context context) {
super(context);
this.context = context;
line_paint.setColor(Color.WHITE);
setWeightSum(2000);
setBackgroundResource(R.color.blue);
View view = new View(context);
view.setBackgroundResource(R.color.yellow);
this.addView(view, new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1000));
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(20, 80, 100, 80, line_paint);
}
}
Now, this does not seem to work. No matter if I swap the canvas.drawLine with super.onDraw, the line is not visible unless I remove the view.setBackgroundResource. How can I draw a line over the LinearLayout. I'd rather not use FrameLayout if possible.
Below are pictures of what I'm trying to achieve (adding a white line) on top of the bars (note: the white bar on the first picture is just exaggerated big for clearness on SO):
Override dispatchDraw() instead of onDraw(). You want to draw the line after the child views draw (which isn't in super.onDraw).
I can add this logo to the canavas if I do this:
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(200,200);
ImageView boo = new ImageView(ExampletouchActivity.this);
boo.setImageResource(R.drawable.ic_launcher);
boo.setLayoutParams(lp);
fr.addView(boo); //this works fine
But if I try to add the same logo to the canvas like this it does not show anything up:
fr.addView(new Toucher(ExampletouchActivity.this));
My Toucher class is like so...
public class Toucher extends View{
ImageView boo;
public Toucher(Context context)
{
super(context);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(200,200);
boo = new ImageView(context);
boo.setImageResource(R.drawable.ic_launcher);
boo.setLayoutParams(lp);
}
#Override
public void onDraw(Canvas c)
{
boo.draw(c);
}
I have been trying for ages and cannot work out why this imageview will not draw itself to the canvas?
Many Thanks
Layout and Canvas aren't the same thing. Layout is "draw this for me", and Canvas is "I'm drawing this". In your working example, you're taking a static image and putting it into a Layout.
When you are using the canvas, in a view things are different, so try using:
canvas.drawBitmap(bg, src, dst, paint);
I'm trying to call onDraw method on Button click ,button the view is updated only once also onDraw method is called . But no change in the position of line.
I have this custom view
public LineSeekbar(Context context) {
super(context);
this.setWillNotDraw(false);
setNewX(130);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e("GRAPH","draw");
paint = new Paint();
paint.setARGB(225, 215, 10, 20);
paint.setStrokeWidth(2);
paint.setStyle(Style.FILL);
canvas.drawLine(130,900,getNewX(),100, paint);
setNewX(getNewX()+15);
}
Calling this from activity class
final Bitmap mBackgroundImage = Bitmap.createBitmap(500,500, Bitmap.Config.RGB_565);
cv =new Canvas(mBackgroundImage);
LineView = new LineSeekbar(LineActivity.this);
LineView.setLayoutParams(new LayoutParams(500,500));
LineView.onMeasure(500,500);
LineView.invalidate();
LineView.draw(cv);
// LineView = null;
ImageView mImageView = new ImageView(this);
mImageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
mImageView.setBackgroundColor(android.R.color.white);
mImageView.setImageBitmap( mBackgroundImage );
LinearLayout ll =(LinearLayout) findViewById(R.id.linearLayout1);
ll.addView(mImageView);
Button inc = (Button) findViewById(R.id.increase);
inc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LineView.invalidate();
LineView.draw(cv);
}
});
You should call an instance with small letter because it is not a class: lineView insted of LineView.
Since you are calling it from another thread (UI) you should say
LineView.postInvalidate();
When you create LineView instance for the first time, onDraw will be executed on its own and show the first line.
It is not clear what is LineView.draw(cv); You can draw the background image in onDraw just before drawing the line. You can use onSizeChange method in the custom view to find its real dimensions and resize your bitmap...
In onDraw insert a line
Log.e("LineView", Integer.toString(getNewX()));
and then in DDMS - LogCat watch the output when you press the button.
Try this:
You didn't made an object of the LineView class like you should. You should use small letters for instances.
final Bitmap mBackgroundImage = Bitmap.createBitmap(500,500, Bitmap.Config.RGB_565);
cv =new Canvas(mBackgroundImage);
LineView lineView = new LineSeekbar(LineActivity.this);
lineView.setLayoutParams(new LayoutParams(500,500));
lineView.onMeasure(500,500);
lineView.invalidate();
lineView.draw(cv);
// LineView = null;
ImageView mImageView = new ImageView(this);
mImageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
mImageView.setBackgroundColor(android.R.color.white);
mImageView.setImageBitmap( mBackgroundImage );
LinearLayout ll =(LinearLayout) findViewById(R.id.linearLayout1);
ll.addView(mImageView);
Button inc = (Button) findViewById(R.id.increase);
inc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
lineView.invalidate();
lineView.draw(cv);
}
});
Solved it ,I placed custom view in xml layout ,its working fine.