In a custom view I design a text with drawText function. Now, I would intercepted the click on the text. this my code:
float x = (float)position.getX() + Constants.RADIUS + Constants.OFFSET_OVER_ARCH;
float y = (float)position.getY() ;
for (String line : node.getNode().getLabel().split(Constants.CHAR_SEPARATOR)) {
canvas.drawText(line, x, y, paintSele);
y += paintSele.descent() - paintSele.ascent();
}
Draw rectangle in the text and check if the coordinates of the click is on the rectangle area? This a better solution?
Thanks a lot!
What you can do, is to Paint.measureText(), then Paint.getTextBound() of the text which will fill the inputted Rect with the text's coordinates, and then listen for clicks in that rectangle.
Related
Im using the following code to write text on rectangle.
public static void drawRectangleAndLabelOnPreview(Mat img, Rect face, String label) {
Imgproc.putText(img, label, face.tl(), Core.FONT_HERSHEY_SIMPLEX, FONT_SIZE, FACE_RECT_COLOR, FONT_THICKNESS);
}
I want the rectangle on bottom but it is still in the top. How can I be able to put it in bottom left?
Set Rect face coordinates to bottom left position where you want to put text in the image.
Suppose w and h are width and height of your text box and r and c are number of rows and columns in the image respectively. Then, set face x, y values as:
face.x = 0;
face.y = r - h - 1;
These values are for example if you want to set box on bottom left position. You can change if you want to change position.
I'm trying to draw a text to the screen and then have a rectangle in the same spot to account for knowing when the user clicks within it (and clicks the text). Problem is when I put the text in one spot on the screen and the rectangle in the same spot, it apparently isn't in the same spot. Is there some setting I need to set somewhere?
private final String[] options = {"Start", "High Scores", "Help", "Quit"};
public void draw(final Canvas g)
{
for (int i = 0; i < options.length; i++)
{
width = HORIZONTALOFFSET * 3 + spaceInvadersTitle.getWidth();
height = GamePanel.getScreenHeight() / 4 - (75 * 2 + TEXT_SIZE) / 2 + i * 75;
rect[i] = new Rect(width, height, width + 325, height + TEXT_SIZE);
g.drawRect(rect[i], paint);
g.drawText(options[i], width, height, paint);
}
}
FYI "width" and "height" are more like x- and y-coords. The horizontal alignment is not the problem - just the vertical. If you'll notice from the code, I'm setting the starting x- and y-coordinates for the drawText and drawRect the same exact position, but that's not how they're showing on the screen. Instead it seems the drawText is using that position as a lowerleft anchorpoint or something like that. Is that how it works? If so, how do I change that?
Also, if you have any suggestions on how to approach listening for when the user clicks on a drawn text, I'm all ears. This is the easiest way I could think of, and how I do it in regular desktop Java.
I am trying to find the text which is being clicked in a canvas displayed on a imageview. I've overridden the on touch on imageview.So this is the approach I used. I've stored all the x,y coordinates on the canvas where I've displayed text along with the text and Paint. when a Motion_event.ACTION_DOWN is triggered. I get the event coordinates and check if the event coordinates are with in the text bounds. Here is the code snippet.
float xRatio=(float)mTempBitmap.getWidth()/(float)mEditImageView.getWidth();
float yRatio= (float)mTempBitmap.getHeight()/(float)mEditImageView.getHeight();
mEditImageView.setImageBitmap(mTempBitmap);
for (TextItem textItem : mTextItemStack) {
Rect tempRect = new Rect();
textItem.getPaint().getTextBounds(textItem.getTextContent(), 0, textItem.getTextContent().length() - 1, tempRect);
tempRect.offset(textItem.getXCoordinate(), textItem.getYCoordinate());
if (tempRect.contains((int)(event.getX()*xRatio), (int) (event.getY()*yRatio))) {
mtextItemInFocus = textItem;
break;
}
}
But the problem arises in the getTextBounds() call.Here is the Doc for getTextBounds.
Return in bounds (allocated by the caller) the smallest rectangle that encloses all of the characters, with an implied origin at (0,0).
But I get negative bounds as a result. Clearly my understanding of the getTextBounds is wrong. Please correct me. I welcome alternate approach for doing the same.
I want to set a vertical line in center of LineChart like this:
When scrolling to each point, it can notify to change the date below (the orange date field). And it can move left or right programmatically by click on arrow button.
Currently, I can set viewport and allow moving to center with this code:
LineData data = new LineData(xVals, dataSets);
mChart.setScaleMinima((float) data.getXValCount() / 7f, 1f);
mChart.moveViewTo(0, 7, YAxis.AxisDependency.LEFT);
And get the result:
How can I draw and set a vertical line like above?
Update:
For the listener, I think OnChartGestureListener onChartTranslate(MotionEvent me, float dX, float dY) may help. What I need is the distance between 2 points and how to calculate how many points are in current view port. Does anyone know that?
Have you tried using getEntryByTouchPoint on your chart supplying the x and y coordinates of the center of the chart?
public Entry getEntryByTouchPoint(float x, float y)
returns the Entry object displayed at the touched position of the chart
Take a look at the method
protected void drawGridBackground(Canvas c) {
in the BarLineChartBase class (parent for a LineChart). In that method you have all data to draw your line right in the middle.
Something like this
RectF rectF = mViewPortHandler.getContentRect();
float xMiddle = (rectF.right - rectF.left)/2;
Paint p = new Paint();
p.setColor(Color.BLACK);
c.drawLine(xMiddle, rectF.bottom, xMiddle, rectF.top, p);
Maybe it's too late but here is my answer. It's encoded in Swift using Charts (MPAndroidCharts port for iOS) but API is 99% the same ;)
let verticalPointEntry = ChartDataEntry(x: xValue, y: yValue)
let dataSet = LineChartDataSet(values: [verticalPointEntry], label: "")
dataSet.drawCirclesEnabled = false
dataSet.drawValuesEnabled = false
dataSet.setDrawHighlightIndicators(true)
dataSet.drawHorizontalHighlightIndicatorEnabled = false
dataSet.highlightColor = UIColor.white
dataSet.highlightLineWidth = 1
let highlightPoint = Highlight(x: xValue, y: yValue, dataSetIndex: datasetIndex)
self.highlightValues([highlightPoint])
// "yourNormalDataSet" is your regular dataSet in which you want to display vertical line over it
let chartData = LineChartData(dataSets: [yourNormalDataSet, dataSet])
self.data = chartData
self.data?.notifiyDataChanged()
self.notifyDataSetChanged
This will display a vercital line over the point defined by your xValue variable.
Hope it helps!
I've drawn 5 bitmaps from .png files on a canvas - a head, a body and two arms and legs.
How can I detect which of these has been touched on an OnTouch? And, more specifically, can I detect if the OnTouch was within the actual shape of the body part touched?
What I mean is, obviously, the .pngs themselves are rectangular, but does Android know, or can I tell it, to ignore the transparency within the image?
You could get the colour of pixel touched and compare it to the colour of pixel on the background at those co-ords.
EDIT: ok, ignore that, you can't get the colour of a pixel on the canvas, so instead, get the x,y of the touch, check if any of the body part images have been touched, if so, take the x,y of the image from the touch x,y, then get the pixel of the image, which should be transparent or colour.
public boolean onTouchEvent(MotionEvent event)
{
int x = (int) event.getX();
int y = (int) event.getY();
int offsetx, offsety;
for(int i = 0;i<NUM_OF_BODY_PARTS;i++)
{
if(bodyPartRect[i].intersects(x,y,x+1,y+1))
{
offsetx = x - bodyPartRect[i].left;
offsety = y - bodyPartRect[i].top;
if(bodyPartBMP[i].getPixel(offsetx,offsety) == TRANSPARENT)
{
//whatever
}
}
}
}