Search code examples
androidkotlinandroid-edittext

how to make "grid note text view" using TextView


im trying to make grid note view like this:

grid note view sample

so i tried to make this using TextView.setLetterSpacing and Canvas.drawLine method

but not all characters(such as "." and "?", "/" etc) have the same width. (uppercase and lowercase too)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="AAAAAAAAaAaAaaAA.,A,A..A"
        android:textSize="30sp"
        android:letterSpacing="1"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

not Working

how can i do?


Solution

  • Your simplest option is definitely using a monospace font, so all the characters are the same width. Other solutions (grid of individual 1-character TextViews, custom View or subclassed EditText etc.) will be way more work to set up, and get behaving the same way as what you already have.

    You can use the basic Android monospace font:

    android:fontFamily="monospace"
    

    Or you could find a monospace font you like and bundle it, and use it the same way:

    android:fontFamily="@font/my_cool_font"
    

    The finished, aligned layout with every character positioned in a fixed grid


    And since you're using sp for your font size, remember the text can scale based on the user's device preferences. So letterSpacing will need to shrink (or grow) depending on the adjusted text size, if you want the character positions to be consistent. Bigger characters = smaller spacing etc!

    You'll need to do that in code, maybe in onResume() using something like this:

    val fontScale = resources.displayMetrics.scaledDensity
    editText.letterSpacing = 1 / fontScale
    

    I don't know how consistent that will be, you'll have to investigate!