I'm working in an app that uses the ml kit text recognition library; The app reads text from images and puts a Rect
around every word.
Now I want these Rects
to change color when the user tap on one of them or swipe above some words.
So, I was able to handle touch events correctly, but what I can't do is changing the color of the touched Rect
!
Should I draw new colored Rects above the touched Rect? Or can I color the existing rects (which I don't think I can)?
Classes: TextGraphic, GraphicOverlay. //This is where the Rects get drawn
I also tried this solution, so I typed this methods in the TextGraphic
class:
public void changeColor(boolean isHighlighted) {
if(isHighlighted) {
rectPaint.setColor(COLOR_HIGHLIGHTED);
rectPaint.setAlpha(400);//set opacity of rect
}else{
rectPaint.setColor(COLOR_DEFAULT);
rectPaint.setAlpha(400);//set opacity of rect
}
postInvalidate();
}
and called it when the user touches the text, but the problem is that all Rects
colors get changed, and they do not change at runtime!
A snippet from my ActivityClass, where I used some callback methods to pass things out.
ArrayList<Rect> rects = new ArrayList<>();
@Override
public void onAdd(FirebaseVisionText.Element element, Rect elementRect, String wordText) {
GraphicOverlay.Graphic textGraphic = new TextGraphic(mGraphicOverlay, element);
mTextGraphic = new TextGraphic(mGraphicOverlay, element);
mGraphicOverlay.add(textGraphic);
rects.add(elementRect);
}
A snippet from my ActivityClass where I handle touch events:
@Override
public boolean onDown(MotionEvent event) {
helper.dismissKeyboard();
touchX = Math.round(event.getX());
touchY = Math.round(event.getY());
for(int x=0; x< rects.size();x++) {
if (rects.get(x).contains(touchX, touchY)) {
// line has been clicked
mTextGraphic.changeColor(true);
return true;
}
}
return true;
}
You are changing the color using the mTextGraphic
variable. If you look closely in your onAdd()
method you will see that you are assigning a new object to mTextGraphic
that has nothing to do with the objects drawn to screen because only the objects that you add to GraphicOverlay
list using the mGraphicOverlay.add()
will get drawn to screen.
So what you need is to call changeColor()
not on mTextGraphic
but on the respective object that is already in the list inside GraphicOverlay
Since the list inside GraphicOverlay
is private you can't manipulate it in the onDown()
method. You will need to write a public method that will do the job for you.
Write the following method in GraphicOverlay
class
public TextGraphic getGraphicElementAtIndex(int index) {
return (TextGraphic)graphics.get(index)
}
Now use this method inside the if condition of onDown()
method like this
if (rects.get(x).contains(touchX, touchY)) {
// line has been clicked
Log.d("PreviewActivity", "changeColor() is called");
mGraphicOverlay.getGraphicElementAtIndex(x).changeColor();
touchedText = texts.get(x);
return true;
}
Hope this helps.
SIDE NOTE: Now even after this if for some reason the ordering of objects inside rects
list and graphics
list (which is inside GraphicOverlay
) change then you will see that when you click a rectangle some other rectangle changes color.