J'ai trois TextViews "hi"
, "x"
et "Hello World"
que je voudrais aligner en bas du texte Hello World (ie hi_x_World). Hello World n'est qu'une ligne, mais layout_width
et layout_height
sont tous deux définis sur wrap_content
.
Ils ont des tailles de police différentes, donc même si je peux facilement aligner le bas des boîtes des vues de texte, le texte lui-même ne s'aligne pas.
J'ai trouvé une app:layout_constraintBaseline_toBaselineOf="@+id/text
paramètres XML différente app:layout_constraintBaseline_toBaselineOf="@+id/text
qui fonctionne lorsque je n'ai qu'une seule ligne dans TextView. Cependant, lorsque j'ai 2 lignes ou plus (comme dans Hello World TextView), la ligne de base considérée est dans le "Bonjour" au lieu de "Monde".
Existe-t-il un moyen de modifier le paramètre pour considérer la ligne de base sous le mot «Monde» au lieu de «Bonjour»?
4 Réponses :
Vous pouvez utiliser:
app:layout_constraintTop_toTopOf="@+id/helloworldtextid"
N'oubliez pas non plus de définir la hauteur sur wrap_content
sorte que le bas de TextViews s'aligne jusqu'au bas de "Hello World", même s'il est encapsulé sur deux lignes ou plus.
Si vous voulez qu'il soit centré sur "Hello World" lorsqu'il est multiligne, pensez à ajouter
app:layout_constraintBottom_toBottomOf="@+id/helloworldtextid"
avec celui du bas. Il centrera le texte verticalement sur le "Hello World" à plusieurs lignes.
vous pouvez modifier le centrage (la valeur par défaut est parfaitement centrée = 0,5 en utilisant la propriété verticalBias
Ce n'est pas ce que le PO a demandé. Vous suggérez simplement d'aligner le bas de la première vue de texte sur le bas de celle souhaitée, pas sur sa ligne de base.
AFAIK, il n'y a aucun moyen d'accomplir cette tâche en utilisant ConstraintLayout à partir d'aujourd'hui.
Si vous connaissez le contenu de "helloWorldTextView" à l'avance, vous pouvez diviser les lignes en plusieurs textViews, puis utiliser app:layout_constraintBaselineToBaselineOf
.
Je sais que c'est une solution de contournement délicate, mais c'est la seule façon qui me vient à l'esprit.
Deuxième mise à jour: c'est une autre façon de voir la première solution tirée de cette réponse Stack Overflow qui fonctionnera également avec ConstraintLayout . Cette solution utilise un TextView personnalisé. Le TextView personnalisé renvoie la ligne de base de la dernière ligne de texte dans le TextView à partir de la fonction getBaseline()
au lieu de la ligne de base de la première ligne qui est l'action par défaut. C'est une solution agréable et propre (IMO) qui prend en compte les TextViews multilignes mais aussi la gravité, etc.
Version Kotlin de BaselineLastLineTextView
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:id="@+id/layout" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/hiView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hi" android:textSize="46sp" app:layout_constraintTop_toTopOf="@id/helloView" app:layout_constraintEnd_toStartOf="@+id/xView" app:layout_constraintStart_toStartOf="parent"/> <TextView android:id="@+id/xView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="x" android:textSize="36sp" app:layout_constraintTop_toTopOf="@id/helloView" app:layout_constraintEnd_toStartOf="@+id/helloView" app:layout_constraintStart_toEndOf="@+id/hiView" /> <TextView android:id="@+id/helloView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello\nWorld!" android:textSize="50sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/xView" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:text="Adjust Base Lines" android:onClick="onClick" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/helloView" /> </androidx.constraintlayout.widget.ConstraintLayout>
Première mise à jour: Ceci est une mise à jour de ma réponse ci-dessous qui est toujours une solution valide (IMO). Il s'agit d'une approche alternative qui n'implique aucun code Java / Kotlin et peut être réalisée simplement en utilisant XML.
Créez un wrap_content
wrap_content invisible qui a la même taille de police que le "Hello World!" TextView . (Vous devrez peut-être également prendre en compte le remplissage et les marges en fonction de la mise en page réelle.) Contraignez cette nouvelle vue au bas de "Hello World!", Rendez-la invisible
et définissez le contenu sur quelque chose de court qui n'occupera qu'une seule ligne. Cela vous donnera une vue cible qui a la même ligne de base que la dernière ligne de "Hello World!" vue.
Contraignez les lignes de base de "hi" et "x" à la nouvelle vue invisible
. Toutes les vues partageront désormais la même ligne de base et sans codage.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun onClick(view: View) { button.isEnabled = false // Get the StaticLayout from the TextView val layout = helloView.layout // Get the base line location for last line of Hello World! TextView, "hi" and "x" val helloBaseLIne = layout.getLineBaseline(layout.lineCount - 1) val hiBaseLine = hiView.layout.getLineBaseline(0) val xBaseLine = xView.layout.getLineBaseline(0) // Shift "hi" and "x" down so base lines match that of hello world! hiView.updatePadding(top = helloBaseLIne - hiBaseLine) xView.updatePadding(top = helloBaseLIne - xBaseLine) } }
Première réponse: comme indiqué dans une autre réponse, il n'y a aucun moyen de le faire simplement en utilisant les contraintes ConstraintLayout . Vous devrez recourir à une solution programmatique.
Dans chaque TextView se trouve un StaticLayout qui peut révéler un peu la typographie du texte. En faisant référence à la disposition statique, un remplissage peut être ajouté aux vues appropriées pour aligner les lignes de base.
Dans cette démo, les trois TextViews ont simplement leurs sommets alignés. Au départ, les vues ressemblent à ceci:
Lorsque vous cliquez sur le bouton, les emplacements de la ligne de base sont calculés et un remplissage est ajouté aux sommets des TextViews "hi" et "x".
Les détails varieront avec la mise en œuvre, mais c'est la technique générale.
MainActivity.kt
<androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/hiddenView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="A" android:textSize="50sp" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="@id/helloView" app:layout_constraintEnd_toEndOf="parent" /> <TextView android:id="@+id/hiView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hi" android:textSize="46sp" app:layout_constraintBaseline_toBaselineOf="@id/hiddenView" app:layout_constraintEnd_toStartOf="@+id/xView" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/helloView" /> <TextView android:id="@+id/xView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="x" android:textSize="36sp" app:layout_constraintBaseline_toBaselineOf="@id/hiddenView" app:layout_constraintEnd_toStartOf="@+id/helloView" app:layout_constraintStart_toEndOf="@+id/hiView" app:layout_constraintTop_toTopOf="@id/helloView" /> <TextView android:id="@+id/helloView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello\nWorld!" android:textSize="50sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/xView" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:onClick="onClick" android:text="Adjust Base Lines" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/helloView" /> </androidx.constraintlayout.widget.ConstraintLayout>
activity_main.xml
class BaselineLastLineTextView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null ) : AppCompatTextView(context, attrs) { override fun getBaseline(): Int { val layout = layout ?: return super.getBaseline() val baselineOffset = super.getBaseline() - layout.getLineBaseline(0) return baselineOffset + layout.getLineBaseline(layout.lineCount - 1) } }
L'astuce avec hiddenView
fonctionne bien, merci! Il semble qu'il n'est pas nécessaire de le rendre invisible
, vous pouvez simplement omettre l'attribut android:text
.
Utiliser la ligne directrice
Classe utilitaire représentant un objet d'assistance Guideline pour ConstraintLayout. Les objets d'assistance ne sont pas affichés sur l'appareil (ils sont marqués comme View.GONE) et ne sont utilisés qu'à des fins de mise en page. Ils ne fonctionnent que dans un ConstraintLayout.
Une ligne directrice peut être horizontale ou verticale :
a) Les lignes directrices verticales ont une largeur de zéro et la hauteur de leur parent ConstraintLayout
b) Les lignes directrices horizontales ont une hauteur de zéro et la largeur de leur parent ConstraintLayout
Les widgets peuvent ensuite être contraints à une ligne de guidage, ce qui permet de positionner facilement plusieurs widgets à partir d'une seule ligne de guidage, ou autorise un comportement de mise en page réactif en utilisant le positionnement en pourcentage.
Code:-
<?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"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent=".4" /> <TextView android:id="@+id/textViewHi" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="50dp" android:text="hi" android:textSize="30sp" app:layout_constraintBottom_toTopOf="@+id/guideline" /> <TextView android:id="@+id/textViewX" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="@+id/textViewHi" android:layout_marginLeft="50dp" android:text="x" android:textSize="30sp" app:layout_constraintBottom_toTopOf="@+id/guideline" /> <TextView android:id="@+id/textViewHelloWorld" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="@+id/textViewX" android:layout_marginLeft="50dp" android:text="Hello World" android:textSize="45sp" app:layout_constraintBottom_toTopOf="@+id/guideline" /> </androidx.constraintlayout.widget.ConstraintLayout>
Pouvez-vous montrer votre XML et votre code et également essayer de montrer ce que vous voulez réaliser avec une image comme ci-dessus.