Skip to content

Instantly share code, notes, and snippets.

@caseykulm
Last active January 2, 2018 21:18
Show Gist options
  • Save caseykulm/c0221b56a2a9d9f4a1ca135dd8ae3598 to your computer and use it in GitHub Desktop.
Save caseykulm/c0221b56a2a9d9f4a1ca135dd8ae3598 to your computer and use it in GitHub Desktop.
Draw Lines for different measurements around a TextView in Android
// Using https://medium.com/@orhanobut/android-and-typography-101-5f06722dd611 for reference
// Update with https://github.com/suragch/AndroidFontMetrics/blob/master/app/src/main/java/net/studymongolian/fontmetrics/FontMetricsView.java
// Need to take into account multiple lines
public class LinesView extends FrameLayout {
private static final Paint
RED_PAINT = new Paint(Color.RED),
BLUE_PAINT = new Paint(Color.BLUE),
GREEN_PAINT = new Paint(Color.GREEN),
PURPLE_PAINT = new Paint(Color.MAGENTA);
private final List<Line> lines = new ArrayList<>();
public LinesView(@NonNull Context context) {
this(context, null);
}
public LinesView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
updateLines();
}
private void updateLines() {
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
TextView tv = (TextView) getChildAt(0);
createLines(tv);
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
private void createLines(TextView tv) {
lines.clear();
final int[] location = new int[2];
tv.getLocationOnScreen(location);
final Paint tvPaint = tv.getPaint();
final int baseLine = tv.getBaseline();
final Paint.FontMetrics tvFontMetrics = tvPaint.getFontMetrics();
final float startX = location[0];
final float stopX = tv.getMeasuredWidth() + startX;
// Top
final float topY = baseLine - tvFontMetrics.top;
final Line topLine = new Line("top", startX, topY, stopX, topY, RED_PAINT);
lines.add(topLine);
// Ascent
final float ascentY = baseLine - tvFontMetrics.ascent;
final Line ascentLine = new Line("ascent", startX, ascentY, stopX, ascentY, BLUE_PAINT);
lines.add(ascentLine);
// Mean Line
// final float meanLineY = tvFontMetrics.??;
// Line meanLine = new Line("mean", startX, meanLineY, stopX, meanLineY, GREEN_PAINT);
// lines.add(meanLine);
// Baseline
final Line baseLineY = new Line("base", startX, baseLine, stopX, baseLine, PURPLE_PAINT);
lines.add(baseLineY);
// Descent
final float descentLineY = baseLine + tvFontMetrics.descent;
final Line descentLine = new Line("decent", startX, descentLineY, stopX, descentLineY, BLUE_PAINT);
lines.add(descentLine);
// Bottom
final float bottomLineY = baseLine + tvFontMetrics.bottom;
final Line bottomLine = new Line("bottom", startX, bottomLineY, stopX, bottomLineY, RED_PAINT);
lines.add(bottomLine);
requestLayout();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Line line : lines) {
line.draw(canvas);
}
}
private static class Line {
private final String tag;
private final float startX, startY, stopX, stopY;
private final Paint paint;
public Line(float startX, float startY, float stopX, float stopY, Paint paint) {
this("line", startX, startY, stopX, stopY, paint);
}
public Line(String tag, float startX, float startY, float stopX, float stopY, Paint paint) {
this.tag = tag;
this.startX = startX;
this.startY = startY;
this.stopX = stopX;
this.stopY = stopY;
this.paint = paint;
}
public void draw(Canvas canvas) {
Timber.d(toString());
canvas.drawLine(startX, startY, stopX, stopY, paint);
}
@Override
public String toString() {
return String.format(Locale.US, "Drawing line (%1$s) at x1: %2$f, y1: %3$f, x2: %4$f, y2: %5$f",
tag, startX, startY, stopX, stopY);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment