I am working on localizing my app into Bengal. I found that the Bengal numbers take up more line height than the arabic numbers do, and now I want to dynamically make sure that all TextView
s have the same line height and spacing, independently of the content displayed inside them.
However, the TextView
s containing arabic numbers / letters always occupy less space per line, which leads to a cumulated offset as shown in below screenshot:
How can I make secondTextView
symmetric to firstTextView
? Note that it is not possible to merge the two TextView
s into one, I just provided a minimal simple sample here.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
val firstTextView = findViewById<TextView>(R.id.firstText)
val secondTextView = findViewById<TextView>(R.id.secondText)
firstTextView.setText("২\n২\n২\n২\n২\n২\n২\n২")
secondTextView.setText("2\n2\n2\n2\n2\n2\n2\n2")
// Attempts
TextViewCompat.setLineHeight(secondTextView, firstTextView.lineHeight)
secondTextView.setLineSpacing(firstTextView.lineSpacingExtra, firstTextView.lineSpacingMultiplier)
firstTextView.includeFontPadding = false
secondTextView.includeFontPadding = false
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=";
xmlns:app=";
xmlns:tools=";
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/firstText"
android:paddingEnd="4dp"
android:textSize="24sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/secondText"
android:textSize="24sp"
app:layout_constraintStart_toEndOf="@id/firstText"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I am working on localizing my app into Bengal. I found that the Bengal numbers take up more line height than the arabic numbers do, and now I want to dynamically make sure that all TextView
s have the same line height and spacing, independently of the content displayed inside them.
However, the TextView
s containing arabic numbers / letters always occupy less space per line, which leads to a cumulated offset as shown in below screenshot:
How can I make secondTextView
symmetric to firstTextView
? Note that it is not possible to merge the two TextView
s into one, I just provided a minimal simple sample here.
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
val firstTextView = findViewById<TextView>(R.id.firstText)
val secondTextView = findViewById<TextView>(R.id.secondText)
firstTextView.setText("২\n২\n২\n২\n২\n২\n২\n২")
secondTextView.setText("2\n2\n2\n2\n2\n2\n2\n2")
// Attempts
TextViewCompat.setLineHeight(secondTextView, firstTextView.lineHeight)
secondTextView.setLineSpacing(firstTextView.lineSpacingExtra, firstTextView.lineSpacingMultiplier)
firstTextView.includeFontPadding = false
secondTextView.includeFontPadding = false
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android/apk/res/android"
xmlns:app="http://schemas.android/apk/res-auto"
xmlns:tools="http://schemas.android/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="16dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/firstText"
android:paddingEnd="4dp"
android:textSize="24sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/secondText"
android:textSize="24sp"
app:layout_constraintStart_toEndOf="@id/firstText"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Share
Improve this question
edited Mar 28 at 6:30
BenjyTec
asked Mar 27 at 11:48
BenjyTecBenjyTec
11.1k4 gold badges23 silver badges50 bronze badges
1 Answer
Reset to default 0I ended up manually checking the height of both TextView
s and then using setLineSpacing
to compensate for any height difference:
val mainView = findViewById<ContraintLayout>(R.id.main)
mainView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
val firstHeight = firstTextView.height
val secondHeight = secondTextView.height
val lineCount = firstTextView.lineCount
if (lineCount > 0 && firstHeight > secondHeight) {
val heightRatio = firstHeight.toFloat() / secondHeight.toFloat()
secondTextView.setLineSpacing(0f, heightRatio)
mainView.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
})
It might depend on the total number of lines of the TextView
s how well it works, as there is a rounding error cumulating. If you have many lines, you need to consider a more layout-based approach like using individual TextView
s per line and then aliging these, for example by using a GridLayout
.