web-dev-qa-db-fra.com

Supprimer l'espace entre TextViews empilés

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:

stacked textviews

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>
23
borges

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"
43
Barak

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 TextViewViewGroup (Android:clipChildren="false" en XML).

16
Zsolt Safrany

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)
12
Kalle

les marges négatives feront l'affaire

2
Genia S.

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:

 enter image description here

É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:

 enter image description here

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);:

 enter image description here

Sans setPadding(0, 0, 0, 0);:

 enter image description here

Sans setIncludeFontPadding(false);:

 enter image description here

Sans 3 d'entre eux (c'est-à-dire l'original):

 enter image description here

1
林果皞

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

1
LanDenLabs

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.

0
vhd

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

}

}

0
HungNM2