I have TextDrawable class. When i call setText, the text is change but size of drawable not change follow text size. I want size of drawable auto change same as TextView. Thanks
This is my code
public class TextDrawable extends Drawable {
private Paint paint, strokePaint;
private String text;
private int instrinsicWidth, instrinsicHeight;
private float strokeWidth;
private Rect recBounds;
public TextDrawable(String text){
this.text = text;
strokeWidth = 4f;
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setTextSize(32f);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
instrinsicWidth = (int)(paint.measureText(text, 0, text.length()) + 4);
instrinsicHeight = paint.getFontMetricsInt(null) + 4;
strokePaint = new Paint();
strokePaint.setAntiAlias(true);
strokePaint.setColor(Color.GRAY);
strokePaint.setTextSize(32f);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(4f);
strokePaint.setTextAlign(Paint.Align.CENTER);
recBounds = new Rect();
paint.getTextBounds(text, 0, text.length(), recBounds);
}
public TextDrawable(String text, float textSize, int textColor, float strokeWidth, int strokeColor){
this.text = text;
this.strokeWidth = strokeWidth;
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
instrinsicWidth = (int)(paint.measureText(text, 0, text.length()) + strokeWidth);
instrinsicHeight = (int)(paint.getFontMetricsInt(null) + strokeWidth);
strokePaint = new Paint();
strokePaint.setAntiAlias(true);
strokePaint.setColor(strokeColor);
strokePaint.setTextSize(textSize);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(strokeWidth);
strokePaint.setTextAlign(Paint.Align.CENTER);
recBounds = new Rect();
paint.getTextBounds(text, 0, text.length(), recBounds);
//Log.d("htdu87", "rW-rH; w-h: " +recBounds.width()+"-"+recBounds.height()+";"+instrinsicWidth+"-"+instrinsicHeight);
}
public void setText(String text) {
this.text = text;
instrinsicWidth = (int)(paint.measureText(text, 0, text.length()) + strokeWidth);
instrinsicHeight = (int)(paint.getFontMetricsInt(null) + strokeWidth);
setBounds(0, 0, instrinsicWidth, instrinsicHeight);
invalidateSelf();
}
#Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
Log.d("htdu87", "bouns: "+getBounds());
canvas.drawText(text, instrinsicWidth/2, instrinsicHeight-(instrinsicHeight-recBounds.height())-strokeWidth/2, strokePaint);
canvas.drawText(text, instrinsicWidth/2, instrinsicHeight-(instrinsicHeight-recBounds.height())-strokeWidth/2, paint);
}
#Override
public int getOpacity() {
// TODO Auto-generated method stub
return paint.getAlpha();
}
#Override
public void setAlpha(int alpha) {
// TODO Auto-generated method stub
paint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter filter) {
// TODO Auto-generated method stub
paint.setColorFilter(filter);
}
#Override
public int getIntrinsicHeight() {
// TODO Auto-generated method stub
return instrinsicHeight;
}
#Override
public int getIntrinsicWidth() {
// TODO Auto-generated method stub
return instrinsicWidth;
}
}
Problem is that default Views are not designed to catch changes in Drawable's size. So, you should assume that your Drawable is immutable and remove setText method at all - instead supply this parameter directly in constructor.
Basically, it leads to either recreating TextDrawable each time you want to change a text or reassigning it to respective View.
Related
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;
}
}
When i choose initially red and draw a line, and then later select blue and draw a line , now the older line is also getting changed to blue instead of red, However i want the red to remain as red, and blue as such can any one help?
I also tried to get this solution online bt not solve my problem.so please help me.
DrawingView.java
public class DrawingView extends View {
Paint mPaint;
Path mpath;
Canvas mCanvas;
Bitmap myBitmap;
//initial color
private int paintColor = 0xFF660000;
private ArrayList<PathWithPaint> _graphics1 = new ArrayList<PathWithPaint>();
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
// private Map<Path,Float> stoWid = new HashMap<Path,Float>();
private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
Drawingsetup();
}
private void Drawingsetup() {
// TODO Auto-generated method stub
mPaint = new Paint();
mpath = new Path();
mCanvas = new Canvas();
mPaint.setDither(true);
mPaint.setColor(0xFFFFFFFF);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.BEVEL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
myBitmap = Bitmap.createBitmap(820, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(myBitmap);
mCanvas.drawBitmap(myBitmap, 20, 20, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
//return super.onTouchEvent(event);
PathWithPaint pp = new PathWithPaint();
//mCanvas.drawPath(path, mPaint);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
undonePaths.clear();
mpath.moveTo(event.getX(), event.getY());
mpath.lineTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
mpath.lineTo(event.getX(), event.getY());
pp.setPath(mpath);
pp.setmPaint(mPaint);
_graphics1.add(pp);
} else if (event.getAction()==MotionEvent.ACTION_UP) {
mpath.lineTo(event.getX(), event.getY());
// commit the path to our offscreen
mCanvas.drawPath(mpath, mPaint);
// kill this so we don't double draw
paths.add(mpath);
mpath = new Path();
colorsMap.put(mpath,paintColor); // store the color of mPath
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//canvas.drawBitmap(myBitmap, 0, 0, mPaint);
for(Path p: paths){
canvas.drawPath(p, mPaint);
mPaint.setColor(colorsMap.get(p));
}
canvas.drawPath(mpath, mPaint);
canvas.setColor(paintColor);
}
public void CurrentDraw(){
}
public void StartNew(){
//colorsMap.clear();
undonePaths.clear();
paths.clear();
myBitmap.eraseColor(Color.TRANSPARENT);
mpath.reset();
invalidate();
_graphics1.clear();
}
public void ColorChanged(String newColor){
//set color
// start by invalidating the View
//parse and set the color for drawing
paintColor = Color.parseColor(newColor);
mPaint.setColor(paintColor);
invalidate();
}
public void onClickUndo()
{
if (paths.size()>0) {
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
else
{
}
}
public void onClickRedo (){
if (undonePaths.size()>0) {
paths.add(undonePaths.remove(undonePaths.size()-1));
invalidate();
}
else
{
}
}
}
DrawingActivity.java
public class DrwaingActivity extends Activity {
DrawingView drawView;
Bitmap myBitmap;
private ImageButton currentpaint ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.draw_image);
//get drawing view
drawView = (DrawingView)findViewById(R.id.drawing);
// drawView.setOnClickListener(this);
//get the palette and first color button
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
currentpaint = (ImageButton)paintLayout.getChildAt(0);
currentpaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_item, menu);
return true;
}
public void paintClicked(View view){
if(view!=currentpaint)
{
//update color
// retrieve the tag we set for each button in the layout, representing the chosen color
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
// call the new method on the custom drawing View object
drawView.ColorChanged(color);
// update the UI to reflect the new chosen paint and set the previous one back to normal
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currentpaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currentpaint=(ImageButton)view;
}
}
I am using following code to write "g" inside a circle. "g" must be centered horizontally and vertically inside the circle. But I am not able to, where am I wrong ?
//sv is surfaceview which covers whole screen
sv.getHolder().addCallback(new SurfaceHolder.Callback()
{
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
// surfaceview width
swidth=sv.getWidth();
sheight=sv.getHeight();
int height = sheight/3;
int mat = Math.min(height,swidth/2);
Paint paint= new Paint(Paint.ANTI_ALIAS_FLAG);
Paint paint1= new Paint(Paint.ANTI_ALIAS_FLAG);
Resources r = getResources();
paint.setColor(Color.CYAN);
paint1.setColor(Color.BLACK);
Canvas c = sv.getHolder().lockCanvas();
c.drawARGB(254, 254, 254, 254);
String t1="g";
int ttwidth=determineMaxTextSize(t1, mat/4);
paint1.setTextSize(ttwidth);
Rect bounds = new Rect();
paint1.getTextBounds(t1, 0, 3, bounds);
c.drawCircle(swidth/4, height+height/2, mat/4, paint);
c.drawText(t1, swidth/4-bounds.width()/2, height+height/2+bounds.height()/2, paint1);
sv.getHolder().unlockCanvasAndPost(c);
}
This is the method used in above code.
private int determineMaxTextSize(String str, float maxWidth)
{
int size = 0;
Paint paint = new Paint();
do {
paint.setTextSize(++ size);
} while(paint.measureText(str) < maxWidth);
return size;
}
Here is what I get when I try 4 different texts.
EDIT:
After editing my code with this
paint1.setTextAlign(Align.CENTER);
String t1="N";
int ttwidth=determineMaxTextSize(t1, mat/4);
paint1.setTextSize(ttwidth);
Rect bounds = new Rect();
paint1.getTextBounds(t1, 0, 3, bounds);
c.drawCircle(swidth/4, height+height/2, mat/4, paint);
c.drawText(t1, swidth/4, height+height/2+bounds.height()/2, paint1);
I get this outcome which is better
However, you can see "g" is still not aligned.
paint1.setTextAlign(Align.CENTER);
String t1="N";
int ttwidth=determineMaxTextSize(t1, mat/4);
paint1.setTextSize(ttwidth);
Rect bounds = new Rect();
paint1.getTextBounds(t1, 0, 3, bounds);
c.drawCircle(swidth/4, height+height/2, mat/4, paint);
c.drawText(t1, swidth/4, height+height/2+bounds.height()/2, paint1);
Above code is the answer
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
...
}
I've drawn a circle programmatically to act as a paint brush, but I'm having trouble scaling it. I've connected the values of the radius to progress in the seekbar methods and they scale numerically, but when I touch my tablet, the brush is still the same size. How do I get the brush to redraw itself constantly scaling while I'm sliding the seekbar?
Here is the code to change the radius of circle on seek bar progress
private class test extends View {
private int radius;
public test(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
// RectF rect = new RectF(100, 100, 200, 200);
// canvas.drawRect(rect, paint);
canvas.drawCircle(50, 50, getRadius(), paint);
canvas.drawLine(10, 10, 10, 10 + 15, paint);
}
/**
* #param radius the radius to set
*/
public void setRadius(int radius) {
this.radius = radius;
}
/**
* #return the radius
*/
public int getRadius() {
return radius;
}
}
in your activity
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(320, 420));
layout.setOrientation(LinearLayout.VERTICAL);
tt = new test(this);
tt.setLayoutParams(new LayoutParams(100, 200));
layout.addView(tt);
SeekBar bar = new SeekBar(this);
bar.setMax(40);
bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
tt.setRadius(progress);
tt.invalidate();
}
});
layout.addView(bar);
setContentView(layout);
Hope useful to you.