19

I'm drawing a tooltip after clicking inside a custom bar chart (created with MPAndroidChart). The view hierarchy is as follows

<LinearLayout>
     <TextView text=Move & Max Pain/>
     <RelativeLayout with 2 textviews>
     <chart
       clipToChildren=false
       clipToPadding=false
     />
</LinearLayout>

While the View is inside the Chart or its inmediate sibling, everthing looks good. But the moment it collides with its sibling, the tooltip is truncated

enter image description here

Using HierarchyViewer I can see that the content is present, but it's not drawn.

In order to get the clipping, I'm using this code inside draw

    @Override
  public void draw(Canvas canvas, float posx, float posy) {
    // take offsets into consideration
    posx += getXOffset();
    posy += getYOffset();

    canvas.save();

    // translate to the correct position and draw
    canvas.translate(posx, posy);

    Rect clipBounds = canvas.getClipBounds();
    clipBounds.inset(0, -getHeight());
    canvas.clipRect(clipBounds, Region.Op.INTERSECT);

    draw(canvas);
    canvas.translate(-posx, -posy);

    canvas.restore();
  }

If I change Op to Region.Op.Replace, the tooltip is draw correctly but it replaces the Toolbar content, instead of scrolling under it.

enter image description here

Maragues
  • 37,861
  • 14
  • 95
  • 96
  • Could you post source codes of this? It looks great, I want to take a deep look at it. Thanks anyway. – SilentKnight May 27 '15 at 06:16
  • Thanks! But I'm afraid I can't, sorry. I use https://github.com/PhilJay/MPAndroidChart for the charts, but I've customized some parts (specially the X labels) – Maragues May 27 '15 at 07:14
  • 1
    Probably not your only problem, but I think you're misusing canvas.save(). Shouldn't you be calling it before your first translation, and then calling restore after you're done rather than calling translate again in the negative direction. – charliebeckwith May 28 '15 at 03:33
  • It fixes it on Lollipop, still not working on Kitkat :( – Maragues May 28 '15 at 14:19
  • I've updated the question after your comment. Thanks! – Maragues May 28 '15 at 15:56
  • I'm shooting from the hip here, but can you achieve what you need by putting the tool tip in a FrameLayout and just toggling the visibility? It's kind of a basic suggestion (because I don't have a ton of experience yet) so you've probably already thought of it, but it doesn't hurt to throw the idea out there. I'm not sure how exactly you'd align the tool tip exactly where you want it inside the FrameLayout so it lands on top of your graph in the right place, but it looks like you already have the mechanics for that. – Chamatake-san Jun 09 '15 at 04:55

1 Answers1

1

You'll need the bounds of the area in which you want to be able to draw the tooltip, and I'm assuming that would be a scrollview. Then you can intersect the tooltip bounds with the scroll to work out what the clipping should be; and if it should be drawn at all.

To explain it in code it would be something like this (untested):

Rect scrollViewRect;  // the bounds of your scrollview
Rect tooltipRect;     // the bounds of your tooltip

bool intersects = tooltipRect.intersect(scrollViewRect)
if(intersects)
{
    canvas.clipRect(tooltipRect, Region.Op.REPLACE);
    draw(canvas);
}
Wex
  • 4,434
  • 3
  • 33
  • 47