J'ai une verticale LinearLayout
avec deux TextView
à l'intérieur. Le premier contient une propriété de texte statique (son texte ne change jamais) et le dernier contient un minuteur régressif. L'image ci-dessous montre les deux éléments:
Je veux éliminer l’espace vide que les deux textes ont en haut et en bas. J'ai essayé plusieurs approches ...
Android:includeFontPadding="false"
Android:lineSpacingMultiplier="1"
Android:lineSpacingExtra="0dp"
Android:paddingTop="0dp"
Android:paddingBottom="0dp"
Android:layout_marginTop="0dp"
Android:layout_marginBottom="0dp"
... mais aucun d'eux n'a supprimé l'espace au-dessus du texte. Comment puis-je rapprocher les deux textes sans espace supplémentaire?
PS: J'ai trouvé cette question similaire , mais personne n'y a répondu.
Code de mise en page complet:
<LinearLayout
Android:id="@+id/boxTime"
Android:orientation="vertical"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentTop="true"
Android:layout_centerHorizontal="true"
Android:layout_marginTop="20dp" >
<TextView
Android:id="@+id/textRemainingTime2"
Android:layout_width="wrap_content"
Android:layout_heigh="wrap_content"
Android:layout_gravity="center"
Android:gravity="center_horizontal"
Android:textSize="70sp"
Android:includeFontPadding="false"
Android:lineSpacingMultiplier="1"
Android:lineSpacingExtra="0dp"
Android:paddingTop="0dp"
Android:paddingBottom="0dp"
Android:layout_marginTop="0dp"
Android:layout_marginBottom="0dp"
Android:text="@string/title" />
<TextView
Android:id="@+id/textRemainingTime"
Android:layout_width="wrap_content"
Android:layout_heigh="wrap_content"
Android:layout_gravity="center"
Android:gravity="center_horizontal"
Android:includeFontPadding="false"
Android:lineSpacingMultiplier="1"
Android:lineSpacingExtra="0dp"
Android:paddingTop="0dp"
Android:paddingBottom="0dp"
Android:layout_marginTop="0dp"
Android:layout_marginBottom="0dp"
Android:textSize="107sp"
Android:text="@string/timer" />
</LinearLayout>
Essayez d'utiliser des marges négatives. Il faudra peut-être un peu de jeu avec les chiffres pour bien faire les choses, mais je l’ai déjà fait et cela a bien fonctionné.
Android:layout_marginTop="-5dp"
Faites en sorte que la ligne de base du texte soit égale au bas de TextView.
public class BaselineTextView extends TextView {
public BaselineTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
int yOffset = getHeight() - getBaseline();
canvas.translate(0, yOffset);
super.onDraw(canvas);
}
}
REMARQUE: pour éviter de couper les descendeurs, appelez setClipChildren(false)
sur le parent de votre TextView
ViewGroup
(Android:clipChildren="false"
en XML).
Par défaut, un TextView inclut une certaine marge pour laisser de la place aux caractères accentués . Vous pouvez désactiver cela avec:
Android:includeFontPadding="false"
ou
textView.setIncludeFontPadding(false)
les marges négatives feront l'affaire
Puisque mon exigence est de remplacer le textView existant à partir de findViewById(getResources().getIdentifier("xxx", "id", "Android"));
, je ne peux donc pas simplement essayer onDraw()
d’une autre réponse.
Mais je viens de comprendre les étapes correctes pour résoudre mon problème, voici le résultat final de l'inspecteur de disposition:
Étant donné que je voulais simplement supprimer les espaces en haut, je n'ai donc pas à choisir une autre police pour supprimer les espaces en bas.
Voici le code critique pour le réparer:
Typeface mfont = Typeface.createFromAsset(getResources().getAssets(), "fonts/myCustomFont.otf");
myTextView.setTypeface(mfont);
myTextView.setPadding(0, 0, 0, 0);
myTextView.setIncludeFontPadding(false);
La première clé est la police personnalisée "fonts/myCustomFont.otf" qui a l'espace en bas mais pas en haut, vous pouvez facilement le savoir en ouvrant le fichier otf et en cliquant sur une police dans Android Studio:
Comme vous pouvez le constater, le curseur situé en bas a un espacement supplémentaire, mais pas en haut, il a donc résolu mon problème.
La deuxième clé est vous ne pouvez pas simplement ignorer le code , sinon cela pourrait ne pas fonctionner. C’est la raison pour laquelle certaines personnes ont fait savoir qu’une réponse fonctionnait et que d’autres ont fait remarquer que cela ne fonctionnait pas.
Illustrons ce qui se passera si j'en enlève un.
Sans setTypeface(mfont);
:
Sans setPadding(0, 0, 0, 0);
:
Sans setIncludeFontPadding(false);
:
Sans 3 d'entre eux (c'est-à-dire l'original):
Si vous définissez includeFontPadding sur false, cela vous aidera.
Android:includeFontPadding="false"
mais si vous savez que vous n'avez pas de descendeurs parce que vous définissez
Android:textAllCaps="true"
ou si vous savez qu'il n'y a pas de caractères qui ont un descendant, vous pouvez créer un TextView personnalisé et définir la hauteur sur la ligne de base.
public class ExTextView extends TextView {
public ExTextView(Context context) {
this(context, null);
}
public ExTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ExTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.Lollipop)
public ExTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas) {
setHeight(getBaseline()); // <--- Shrink size to baseline
super.onDraw(canvas);
}
}
Le code source est inclus dans mon application de test UiComponents. https://github.com/landenlabs/UiComponents
Les marges négatives feraient le travail. Vous pouvez le définir par deux méthodes -
1) by xml - définit le champ Android:Layout_marginTop="-10dp"
en négatif
2) by Java (Programmatically) - définissez le champ topMargin
de LayoutParams sur négatif.
vous devriez changer la hauteur de TextView et peut-être changer Android: gravity = "bottom"
la hauteur est comprise entre textize et la taille de textView avec Wrapcontent.
public class MyTextViewBounder extends TextView {
public MyTextViewBounder(Context context) {
super(context);
}
public MyTextViewBounder(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextViewBounder(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//test kích thước thực tế với kích thước của Textview bao quanh text của nó như thế nào
int width, height;
Paint iPaint;
Rect iRect = new Rect();
iPaint = new Paint();
iPaint.setTextSize(13);
iPaint.setTextAlign(Paint.Align.CENTER);
//call below code outsite
//this.setText("Hung");
//this.setTextSize(TypedValue.COMPLEX_UNIT_PX,13);
//this..setIncludeFontPadding(false); //height from 18px down to 15px
iPaint.getTextBounds("Hung",0,4,iRect); //width = 34px, height = 12px
width = this.getWidth(); //= 30px
height = this.getHeight(); //= 18px
width = this.getMeasuredWidth(); //=30px
height = this.getMeasuredHeight(); //= 18px
width = iRect.width(); //34px
height = iRect.height(); //12 px
}
}