Android: TextView: remover espaçamento e preenchimento na parte superior e inferior

208

Quando eu tenho um TextViewcom a \nno texto ,, à direita, tenho dois singleLine TextViews, um abaixo do outro sem espaçamento entre eles. Eu defini o seguinte para todos os três TextViews.

android:lineSpacingMultiplier="1" 
android:lineSpacingExtra="0pt" 
android:paddingTop="0pt" 
android:paddingBottom="0pt"

A primeira linha da esquerda se TextViewalinha perfeitamente com a parte superior direita TextView.

A segunda linha da esquerda TextViewé um pouco maior que a segunda linha do canto inferior direito TextView.

Parece que há algum tipo de preenchimento oculto na parte superior e inferior do TextViews. Como posso remover isso?

Bryan Field
fonte
tentar gravidade conjunto deste textview para center_vertical
Dawid Hyzy
Olá, George Bailey, você tem solução depois de tanto tempo? Eu também encontro esse problema agora. Você pode me dar sua solução? obrigado.
mmm2006
1
@ mmm2006, Faz tanto tempo que não sei o que acabei fazendo. Experimente as soluções nas respostas. Se isso não funcionar, faça uma nova pergunta.
Bryan Campo
Isto não funcionou para mim
Marty Miller
qualquer uma das respostas abaixo não funcionou para mim, você pode ajudar
Richa 17/01

Respostas:

521
setIncludeFontPadding (boolean includepad)

ou XMLseria:

android:includeFontPadding="false"

Defina se TextViewinclui estofamento superior e inferior para dar espaço a detalhes que vão acima da subida e descida normais. O padrão é verdadeiro.

user634545
fonte
3
Mas parece que sempre tem um 1dptop preenchimento / fundo, estou errado (eu uso? Developer options -> Show layout bounds)
Autobots
94
includeFontPadding="false"remove parte do espaço, mas não todo. muito estranho.
theblang
7
Esta pode ser uma faca de dois gumes. includeFontPaddingé excelente para remover qualquer preenchimento adicional da própria fonte, mas pode causar problemas em idiomas com subidas e descidas. Eu garantiria que, se você fizer isso, testasse idiomas como espanhol e tailandês, se os apoiar.
Elliott
3
Depois de definir o tempo de execução, ele não leva o preenchimento superior, mas o inferior ainda está lá, mesmo o esquerdo e o direito? alguma sugestão?
CoDe 23/04
5
Isso não funcionou para mim. Eu não entendo o que estou perdendo. Eu ainda tenho espaço indesejado na parte inferior da minha TextView
Marty Miller
41

Eu sinto sua dor. Eu tentei todas as respostas acima, incluindo a setIncludeFontPaddingto false, o que não fez nada para mim.

Minha solução? layout_marginBottom="-3dp"no TextViewdá uma solução para o fundo, BAM!

Embora -3dp em layout_marginTopfalha .... ugh.

hunterp
fonte
6
Isso pode levar a parte inferior do texto potencialmente sendo cortadas
Jason Robinson
2
Realmente péssima idéia de usar margem negativa. Melhor considerar uma exibição personalizada e desenhar o texto exatamente como você deseja.
Flynn81 31/05
Se o patch for assim, você deve calcular também a proporção do tamanho da fonte.
phnghue 02/09
37

Procurei muitas respostas adequadas, mas não encontrei uma resposta que pudesse remover exatamente todo o preenchimento do TextView, mas finalmente, depois de ler o documento oficial, consegui uma solução para textos de linha única

android:includeFontPadding="false"
android:lineSpacingExtra="0dp"

Adicionar essas duas linhas ao TextViewxml fará o trabalho.
O primeiro atributo remove o preenchimento reservado para acentos e o segundo atributo remove o espaçamento reservado para manter o espaço adequado entre duas linhas de texto.

Certifique-se de não adicionar o lineSpacingExtra="0dp"TextView com várias linhas, pois isso pode tornar a aparência desajeitada

Mohammed Atif
fonte
11
Adicionando estes dois linha não está funcionando para mim e também não há nenhuma mudança no estofamento
kushwah Sunil
@sunilkushwah, definitivamente funcionará se você estiver fazendo isso corretamente. Ficaríamos felizes em ajudar se você puder fornecer mais detalhes sobre o seu problema.
Mohammed Atif 23/03
@sunilkushwah Você provavelmente pode empurrá-lo no github e compartilhar o link
Mohammed Atif
@sunilkushwah vejo que você está usando Brandon Font (Custom Font). Você pode tentar remover o fontPathatributo?
Mohammed Atif 23/03
Eu tentei isso, mas não o seu trabalho, Nota: eu não quero qualquer preenchimento padrão em TextView
sunil kushwah
14

Se você usar AppCompatTextView(ou em API 28diante), poderá usar a combinação desses 2 atributos para remover o espaçamento na primeira linha:

XML

android:firstBaselineToTopHeight="0dp"
android:includeFontPadding="false"

Kotlin

text.firstBaselineToTopHeight = 0
text.includeFontPadding = false
Mario Lenci
fonte
11

Isso também me incomodou, e a resposta que encontrei foi que, na verdade, há espaço adicional na própria fonte, não no TextView. É bastante irritante, proveniente de um histórico de publicação de documentos, a quantidade limitada de controle que você tem com o Android sobre elementos tipográficos. Eu recomendo o uso de um tipo de letra personalizado (como o Bitstream Vera Sans, licenciado para redistribuição) que pode não ter esse problema. Eu não tenho certeza especificamente se isso ocorre ou não.

Kevin Coppock
fonte
você tem alguma fonte livre para me indicar? Não preciso ter margem no topo sem atribuir margens negativas! Obrigado!
abóbada
11

Você pode tentar usar este atributo (ConstraintLayout):layout_constraintBaseline_toBaselineOf

Como isso:

app: layout_constraintBaseline_toBaselineOf = "@ + id / textView"

insira a descrição da imagem aqui

insira a descrição da imagem aqui

vento
fonte
10

Eu removo o espaçamento na minha exibição personalizada - NoPaddingTextView.

https://github.com/SenhLinsh/NoPaddingTextView

insira a descrição da imagem aqui

package com.linsh.nopaddingtextview;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.TextView;

/**
 * Created by Senh Linsh on 17/3/27.
 */

public class NoPaddingTextView extends TextView {

    private int mAdditionalPadding;

    public NoPaddingTextView(Context context) {
        super(context);
        init();
    }


    public NoPaddingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        setIncludeFontPadding(false);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int yOff = -mAdditionalPadding / 6;
        canvas.translate(0, yOff);
        super.onDraw(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        getAdditionalPadding();

        int mode = MeasureSpec.getMode(heightMeasureSpec);
        if (mode != MeasureSpec.EXACTLY) {
            int measureHeight = measureHeight(getText().toString(), widthMeasureSpec);

            int height = measureHeight - mAdditionalPadding;
            height += getPaddingTop() + getPaddingBottom();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private int measureHeight(String text, int widthMeasureSpec) {
        float textSize = getTextSize();

        TextView textView = new TextView(getContext());
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        textView.setText(text);
        textView.measure(widthMeasureSpec, 0);
        return textView.getMeasuredHeight();
    }

    private int getAdditionalPadding() {
        float textSize = getTextSize();

        TextView textView = new TextView(getContext());
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        textView.setLines(1);
        textView.measure(0, 0);
        int measuredHeight = textView.getMeasuredHeight();
        if (measuredHeight - textSize > 0) {
            mAdditionalPadding = (int) (measuredHeight - textSize);
            Log.v("NoPaddingTextView", "onMeasure: height=" + measuredHeight + " textSize=" + textSize + " mAdditionalPadding=" + mAdditionalPadding);
        }
        return mAdditionalPadding;
    }
}
Linsh
fonte
Esta pergunta ou resposta é?
Tushar #
@Tushar É uma resposta.
Linsh 03/03
Está bem. Você pode adicionar alguma explicação com o código aqui.
Tushar #
@ Tushar Claro, mas é um pouco mais.
Linsh
3
Embora esse código possa resolver a questão, incluir uma explicação de como e por que isso resolve o problema realmente ajudaria a melhorar a qualidade da sua postagem (e obter votos positivos). Lembre-se de que você está respondendo à pergunta dos leitores no futuro, não apenas à pessoa que está perguntando agora! Edite sua resposta para adicionar uma explicação e forneça uma indicação de quais limitações e suposições se aplicam.
Makyen
3
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/baselineImage"
        android:includeFontPadding="false" />

    <ImageView
        android:id="@+id/baselineImage"
        android:layout_width="1dp"
        android:layout_height="1dp"
        android:baselineAlignBottom="true"
        android:layout_alignParentBottom="true" />

    <!-- This view will be exactly 10dp below the baseline of textView -->
    <View
        android:id="@+id/view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_below="@+id/baselineImage" />

</RelativeLayout>

Com um ImageView extra, podemos definir o TextView para ser alinhado à linha de base com o ImageView e definir o android:baselineAlignBottom o ImageView como true, o que fará com que a linha de base do ImageView seja inferior. Outras visualizações podem se alinhar usando a parte inferior do ImageView, que é igual à linha de base do TextView.

No entanto, isso apenas fixa a parte inferior do estofamento e não a parte superior.

Viven
fonte
perfeito para a minha situação, muito melhor do que remover o preenchimento de fonte. +1
Bawa
3

Eu acho que esse problema pode ser resolvido desta maneira:

 <TextView
        android:id="@+id/leftText"
        android:includeFontPadding="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30dp"
        android:text="Hello World!\nhello world" />

 <TextView
        android:id="@+id/rightUpperText"
        android:includeFontPadding="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/leftText"
        android:layout_alignTop="@+id/leftText"
        android:textSize="30dp"
        android:text="Hello World!" />

 <TextView
        android:id="@+id/rightLowerText"
        android:includeFontPadding="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/leftText"
        android:layout_below="@+id/rightUpperText"
        android:textSize="30dp"
        android:text="hello world" />

Esses são os resultados:

ScreenShot-1

ScreenShot-3

Embora a linha de caracteres especiais no rightLowerText pareça um pouco maior que a segunda linha do leftText, suas linhas de base ainda estão alinhadas.

Wei Wei
fonte
includeFontPadding = "false" era exatamente o que eu precisava! Obrigado.
18718
3

Como meu requisito é substituir o textView existente findViewById(getResources().getIdentifier("xxx", "id", "android"));, não posso simplesmente tentar onDraw()outra resposta.

Mas acabei de descobrir as etapas corretas para corrigir meu problema. Aqui está o resultado final do Layout Inspector:

insira a descrição da imagem aqui

Como o que eu queria era apenas remover os espaços superiores, não preciso escolher outra fonte para remover os espaços inferiores.

Aqui está o código crítico para corrigi-lo:

Typeface mfont = Typeface.createFromAsset(getResources().getAssets(), "fonts/myCustomFont.otf");
myTextView.setTypeface(mfont);

myTextView.setPadding(0, 0, 0, 0);

myTextView.setIncludeFontPadding(false);

A primeira chave é definir a fonte personalizada "fonts / myCustomFont.otf", que tem o espaço na parte inferior, mas não na parte superior. Você pode descobrir isso facilmente, abra o arquivo otf e clique em qualquer fonte no Android Studio:

insira a descrição da imagem aqui

Como você pode ver, o cursor na parte inferior tem espaçamento extra, mas não na parte superior, por isso resolveu o meu problema.

A segunda chave é que você não pode simplesmente pular nenhum código , caso contrário ele pode não funcionar. Essa é a razão pela qual você pode encontrar algumas pessoas que comentam que uma resposta está funcionando e outras que não estão funcionando.

Vamos ilustrar o que acontecerá se eu remover um deles.

Sem setTypeface(mfont);:

insira a descrição da imagem aqui

Sem setPadding(0, 0, 0, 0);:

insira a descrição da imagem aqui

Sem setIncludeFontPadding(false);:

insira a descrição da imagem aqui

Sem três deles (ou seja, o original):

insira a descrição da imagem aqui

Fruta
fonte
3

A única coisa que funcionou é

android:lineSpacingExtra="-8dp"
Antonis Radz
fonte
3

XML atualizado

android:fontFamily="monospace"
android:includeFontPadding="false"
SJJ
fonte
Olá, bem-vindo ao Stack Overflow! Ao responder a uma pergunta, você deve incluir algum tipo de explicação, como o que o autor fez de errado e o que você fez para corrigi-lo. Estou lhe dizendo isso porque sua resposta foi sinalizada como de baixa qualidade e está sendo revisada no momento. Você pode editar sua resposta clicando no botão "Editar".
Federico Grandi
Na verdade, alterar o android: fontFamily não é necessário se você já tiver a fonte correta. Basicamente android: includeFontPadding é a única coisa necessária e foi mencionado nas respostas anteriores do tópico.
Darek Deoniziak
@DarekDeoniziak Algumas fontes têm espaços
SJJ
2

Método simples trabalhado:

setSingleLine();
setIncludeFontPadding(false);

Se não funcionou, tente adicionar isso acima desse código:

setLineSpacing(0f,0f);
// and set padding and margin to 0

Se você precisar de várias linhas, talvez seja necessário calcular exatamente a altura do preenchimento superior e inferior através do TextView de linha única temporária (antes e depois de remover o preenchimento) e, em seguida, aplique o resultado da diminuição da altura com preenchimento negativo ou algum layout do Ghost com tradução Y. Ri muito

phnghue
fonte
0

Convém tentar alinhar a parte inferior da visualização de texto esquerda com a parte inferior da 2ª visualização de texto direita.

Jems
fonte
Mas então a linha superior não se alinharia. E, na verdade, eu não ligo para eles alinharem tanto quanto gostaria realmente de remover o espaçamento.
Bryan Campo
0

Que eu saiba, isso é inerente à maioria dos widgets e a quantidade de "preenchimento" difere entre os fabricantes de telefones. Esse preenchimento é realmente um espaço em branco entre a borda da imagem e a imagem no arquivo de 9 imagens de correção.

Por exemplo, no meu Droid X, os widgets giratórios ganham espaço em branco extra que os botões, o que torna estranho quando você tem um girador embutido com um botão, mas no telefone da minha esposa o mesmo aplicativo não tem o mesmo problema e parece ótimo!

A única sugestão que eu teria é criar seus próprios 9 arquivos de patch e usá-los em seu aplicativo.

Ahhh as dores que são Android.

Editado: esclarecer preenchimento x espaço em branco.

user432209
fonte
0

Este truque funcionou para mim (para min-sdk> = 18 ).

Eu usei android:includeFontPadding="false"e uma margem negativa como android:layout_marginTop="-11dp"e colocar meu TextViewdentro de um FrameLayout( ou qualquer ViewGroup ... )

insira a descrição da imagem aqui

e finalmente exemplos de códigos:

<LinearLayout
    android:layout_width="60dp"
    android:layout_height="wrap_content"
    >

    <TextView
        style="@style/MyTextViews.Bold"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/yellow"
        android:textSize="48sp"
        android:layout_marginTop="-11dp"
        android:includeFontPadding="false"
        tools:text="1"/>
</LinearLayout>
Richi
fonte
1
Esse truque pode não funcionar para fontes, tamanhos ou layouts diferentes.
Adil Soomro 25/04
-1

Veja isso:

Alinhar o ImageView com o EditText horizontalmente

Parece que a imagem de fundo do EditText possui alguns pixels transparentes que também adicionam preenchimento.

Uma solução é alterar o plano de fundo padrão do EditText para outra coisa (ou nada, mas nenhum plano de fundo para um EditText provavelmente não é aceitável). Isso pode ser feito configurando o atributo XML android: background.

android:background="@drawable/myEditBackground"
Ixx
fonte
-2

Basta usar

android:padding="0dp"
Juan Bernal
fonte
-5

Use isso no seu ImageView xml

android: AdjustViewBounds = "true"

Anshul Rawat
fonte
Por favor, adicione alguma explicação sobre isso
Nico Haase
Eu pensei que isso deveria ser entendido. Só posso ser usado em xml.
Anshul Rawat