I am trying to override ondraw in EditText,use canvas to write words on EditText.
But when I setInputType in EditText,it can't display any words.
I don't know how it works.
public class Input extends EditText{
private static int paddingHintText = 30;
private static int paddingInput = 200;
private static int hintTextSize = 40;
private String textString = "test";
Paint paint;
public Input(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
setBackgroundResource(R.drawable.editseletor);
setPadding(paddingInput, 0, 0, 0);
setGravity(Gravity.CENTER);
//if I use it,it can't display any words
//setInputType(InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_PASSWORD);
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
paint.setColor(Color.rgb(50, 50, 50));
paint.setTextSize(hintTextSize);
canvas.drawText(textString, paddingHintText, this.getHeight()/2+hintTextSize/2-5, paint);
canvas.drawLine(0, 50, 200, 50, paint);
super.onDraw(canvas);
}
public void setLeftText(String textString){
this.textString = textString;
}
}
Related
I have created my custom View in Android and trying to draw a circle in that but nothing is drawing but with no errors.
Here is my code
public class ColorOptionsView extends RelativeLayout {
private View mValue;
private ImageView mImage;
private Paint paint;
String cirlceText;
int circleColor,circleTextColor;
float circleTextSize;
public ColorOptionsView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ColorOptionsView, 0, 0);
try {
cirlceText = a.getString(R.styleable.ColorOptionsView_circleText);
circleColor = a.getColor(R.styleable.ColorOptionsView_circleColor, 0);
circleTextColor = a.getColor(R.styleable.ColorOptionsView_circleTextColor, 0);
circleTextSize = a.getFloat(R.styleable.ColorOptionsView_circleTextSize,20);
} finally {
a.recycle();
}
}
public void setCirlceText(String cirlceText) {
this.cirlceText = cirlceText;
invalidate();
requestLayout();
}
public void setCircleColor(int circleColor) {
this.circleColor = circleColor;
invalidate();
requestLayout();
}
public void setCircleTextColor(int circleTextColor) {
this.circleTextColor = circleTextColor;
invalidate();
requestLayout();
}
public void setCircleTextSize(float circleTextSize) {
this.circleTextSize = circleTextSize;
invalidate();
requestLayout();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setColor(circleColor);
int centerX = this.getMeasuredWidth()/2;
int centerY = this.getMeasuredHeight()/2;
int raduis = 150;
canvas.drawCircle(centerX,centerY,raduis,paint);
paint.setColor(circleTextColor);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(cirlceText,centerX,centerY,paint);
canvas.drawLine(0,100,100,0,paint);
}
I am not getting where I went wrong. Devs check it and help me out.
its my first time to ask a question here. I have this problem with my android app.
I would like to create different draw methods inside my custom view class. There are three buttons corresponding to 3 different shapes. When a button is pressed it will draw its shape. But the app crashes when I try to call the custom draw from the MainActivity for me to test it.
MainActivity
import com.example.shapes.view.ShapesView;
public class MainActivity extends Activity {
ShapesView shapesview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
shapesview = (ShapesView) findViewById(R.id.ShapesViewID);
shapesview.DrawRectangle();
}
ShapesView
public class ShapesView extends View{
Canvas canvas;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
this.canvas = canvas;
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
My XML layout file
<com.example.shapes.view.ShapesView
android:id="#+id/ShapesViewID"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />`
Please do help! Thank you very much!
If I understand your question you need a custom view (a button) which will draw itself differently based on some event. If that is the case then you need to respect the android's guidelines about the view drawing take a look here.
Now one possible solution for your case is to set some kind of flag about the state of your view and then use that flag when you are ready to draw. For example you can do this:
public class ShapesView extends View{
public int state = 0;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (state == 1) {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
and then whenever you need to draw your view from an activity you can use the following:
myview.state = 1;
myview.invalidate();
In your code what you are doing is that you call a views function during the onCreate of your activity which in turn tries to use a null canvas because the onDraw method of your view has not be called during that time. Furthermore as others have pointed out you must not use a canvas object outside the onDraw method.
Hope this helps...
I changed your code with following.
public class ShapesView extends View {
Paint mypaint;
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
mypaint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
When you want to draw, call shapesview.invalidate();
Look at method's name its onDraw() and not getCanvas(). The documentation also doesn't makes any claims about the Canvas provided.
After onDraw() is done, that canvas may be disposed, its bitmap/buffer may be re-cycled, who knows.
So, it is not safe to use the Canvas outside of this method. Draw what you want, but only inside onDraw() method.
If you want to trigger the View to re-draw, at some other time, call invalidate().
Example:
View class to render any shape:
public class ShapeView extends View {
private Paint mPaint;
private ShapeRenderer mRenderer;
public ShapeView(Context context) {
super(context);
init();
}
public ShapeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShapeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mPaint = new Paint();
}
public void setPaintColor(int color){
mPaint.setColor(color);
}
public void setPaintStrokeWidth(float width){
mPaint.setStrokeWidth(width);
}
public void setRenderer(ShapeRenderer renderer) {
mRenderer = renderer;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mRenderer != null){
mRenderer.drawShape(canvas,mPaint);
}
}
public static interface ShapeRenderer{
public void drawShape(Canvas canvas, Paint paint);
}
}
A Class that draws a rectangle:
public class RectRenderer implements ShapeView.ShapeRenderer {
#Override
public void drawShape(Canvas canvas, Paint paint) {
canvas.drawRect(0,0,100,100,paint);
}
}
Draw a shape at runtime:
myShapeView.setPaintColor(Color.GREEN);
myShapeView.setPaintStroke(5f);
myShapeView.setRenderer(new RectRenderer());
myShapeView.invalidate();
I think you must redesign your component, so it can draw itself in onDraw method. If you need some class that must contain Canvas, you can try to do something like this.
class Drawer {
private Canvas canvas;
public Drawer(Canvas canvas) {
this.canvas = canvas;
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
On yours custom view you can do something like this.
public class ShapesView extends View{
public ShapesView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Drawer drawer = new Drawer(canvas);
drawer.DrawRectangle();
}
public void DrawRectangle() {
Paint mypaint = new Paint();
mypaint.setColor(Color.BLUE);
canvas.drawRect(30, 30, 200, 200, mypaint);
}
}
I want to make a note editor. It will have an EditText with lines. Here is my code:
LinedEditText.java
public class LinedEditText extends EditText {
private Rect mRect;
private Paint mPaint;
public LinedEditText(Context context) {
super(context);
// TODO Auto-generated constructor stub
mRect = new Rect();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(Color.BLUE); //SET YOUR OWN COLOR HERE
}
#Override
protected void onDraw(Canvas canvas) {
//int count = getLineCount();
int height = getHeight();
int line_height = getLineHeight();
int count = height / line_height;
if (getLineCount() > count)
count = getLineCount();
Rect r = mRect;
Paint paint = mPaint;
int baseline = getLineBounds(0, r);//first line
for (int i = 0; i < count; i++) {
canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
baseline += getLineHeight();//next line
}
super.onDraw(canvas);
}
TextEditorActivity.java
public class TextEditorActivity extends Activity {
private LinedEditText text;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.text=new LinedEditText(getApplicationContext());
this.setContentView(text);
}
}
And result:
result http://bekirmavus.com/k-resimler/image/android/device-2012-07-17-222950.png
What mistake am i making?
Thanks...
The line are being drawn from the position of the cursor on down. Simply move the cursor's default position from vertically centered, to the top-left, with Gravity:
text.setGravity(Gravity.NO_GRAVITY);
Or set it by default for all LinedEditTexts:
public LinedEditTexts(Context context) {
super(context);
setGravity(Gravity.NO_GRAVITY); // or Gravity.TOP | Gravity.LEFT
...
}
Hi i draw a canvas for my application
here is the code my canvas
public class Canvas1 extends View{
int i;
int k;
float l,m;
public Canvas1(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public Canvas1 (Context context, AttributeSet attrs) {
super(context, attrs);
}
public Canvas1 (Context context, AttributeSet ats, int ds) {
super(context, ats, ds);
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawRGB(255, 255, 255);
Paint paint1=new Paint(Color.BLACK);
Paint paint=new Paint(200);
paint.setStrokeWidth((float)0.5);
canvas.drawLine(0,0,0,getMeasuredHeight(), paint1);
canvas.drawLine(0,0, getMeasuredWidth(), 0, paint1);
canvas.drawLine(0,getMeasuredHeight(), getMeasuredWidth(),getMeasuredHeight(), paint1);
canvas.drawLine(getMeasuredWidth(),getMeasuredHeight(), getMeasuredWidth(), 0, paint1);
//canvas.drawLine(0, 0, ((float)getMeasuredWidth()), ((float)getMeasuredHeight()), paint);
if(l!=0||m!=0)
{
canvas.drawLine(getMeasuredWidth()/2,getMeasuredHeight()/2,getMeasuredWidth()/2,getMeasuredHeight(),paint);
canvas.drawLine(0,0,getMeasuredWidth()/2,getMeasuredHeight()/2,paint);
}
for(int i=1;i<5;i++)
canvas.drawLine(((float)getMeasuredWidth())/5*i, 0, ((float)getMeasuredWidth()/5*i),getMeasuredHeight(), paint);
for(int i=0;i<5;i++)
canvas.drawLine(0, getMeasuredHeight()/5*i, getMeasuredWidth(), getMeasuredHeight()/5*i, paint);
canvas.save();
}
public Boolean setline(float d,float e){
l=d;
m=e;
Log.i("Hello Canvas",l+" "+m+" ");
return true;
}
}
now i am trying to call the function setline() from my main activity in this activity there is an array of canvas . here is the code of my activity
public class HelloCanvasActivity extends Activity {
/** Called when the activity is first created. */
Integer[] in={R.id.can1,R.id.can2,R.id.can3,R.id.can4,R.id.can5,R.id.can6,R.id.can7,R.id.can8};
float x,y;
int j=0;
Canvas1[] can=new Canvas1[8];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
for(int i=0;i<8;i++)
{
can[i]=(Canvas1)findViewById(in[i]);
}
can[0].setline((float)0.5,(float) 0.5);
new Thread(new Runnable(){
public void run(){
for(int i=0;i<8;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
can[i].setline((float)0.5,(float)0.5);
}
}
}).start();
}
}
when i omit Thread.sleep(1000) from my code lines are drawing but when i put Thread.sleep(1000) setline is calling after 1 second i am getting log in my log table of Hello World,but no line is drawing on canvas please help me in finding where i am wrong.
In your setline method, call invalidate()
I have problem with refreching canvas in my widget. I create custom widget and I want to repaint first cell on click.
There ins activity
public class TestView extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ElementView ev = (ElementView)findViewById(R.id.surface2);
ev.setOnClickListener(evOnClick);
}
public OnClickListener evOnClick = new OnClickListener() {
#Override
public void onClick(View v) {
ElementView temp=(ElementView)v;
temp.paint.setColor(Color.RED);
temp.canvas.drawRect(new Rect(0,0,90,90),temp.paint);
temp.postInvalidate();
}
};
}
and there is ElementView ( widget which I want to repaint )
public class ElementView extends View {
private final int width=100;
private final int height=100;
public Paint paint=null;
public Canvas canvas=null;
public ElementView(Context context) {
super(context);
paint = new Paint();
}
public ElementView(Context context, AttributeSet attr) {
super(context, attr);
paint = new Paint();
}
public ElementView(Context context, AttributeSet attr, int defaultStyles) {
super(context, attr, defaultStyles);
paint = new Paint();
}
#Override
protected void onMeasure(int widthSpec, int heightSpec) {
int measuredWidth = MeasureSpec.getSize(widthSpec);
int measuredHeight = MeasureSpec.getSize(heightSpec);
setMeasuredDimension(this.width,this.height);
}
#Override
protected void onDraw(Canvas canvas) {
this.canvas=canvas;
// get the size of your control based on last call to onMeasure
int height = getMeasuredHeight();
int width = getMeasuredWidth();
// Now create a paint brush to draw your widget
paint.setColor(Color.GREEN);
//define border
this.canvas.drawLine(0, 0, 0, 99, paint);
this.canvas.drawLine(0, 0, 99,0, paint);
this.canvas.drawLine(99, 0, 99, 99, paint);
this.canvas.drawLine(0, 99, 99,99, paint);
//define cells
this.canvas.drawLine(0,50,99,50,paint);
this.canvas.drawLine(30,0,30,50,paint);
//draw green rectangle
this.canvas.drawRect(new Rect(0,0,50,50),paint);
//draw some text
paint.setTextSize(8);
paint.setColor(Color.RED);
String displayText = "test";
Float textWidth = paint.measureText(displayText);
int px = width / 2;
int py = height / 2;
this.canvas.drawText(displayText, px - textWidth / 2, py, paint);
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
paint.setColor(Color.RED);
//change color of first cell
canvas.drawRect(new Rect(0,0,50,50),paint);
return super.dispatchTouchEvent(event);
}
}
When I click on ElementView it enter in Activity in onClick and pass through code without mistake or exception , but doesn't change view . Can anybody tell me where is mistake ?
I don't think writing to the Canvas outside of the onDraw method will have any effect on the screen.
Try setting a flag in your onClick method that you read in onDraw which will trigger your drawing routine.