Existe alguma maneira no Android de ajustar o tamanho do texto em uma visualização de texto para caber no espaço que ocupa?
Por exemplo, estou usando a TableLayout
e adicionando vários TextView
s a cada linha. Como não quero que os TextView
s envolvam o texto, vejo que diminui o tamanho da fonte do conteúdo.
Alguma ideia?
Eu tentei measureText
, mas como não sei o tamanho da coluna, parece problemático de usar. Este é o código em que desejo alterar o tamanho da fonte para algo que se encaixe
TableRow row = new TableRow(this);
for (int i=0; i < ColumnNames.length; i++) {
TextView textColumn = new TextView(this);
textColumn.setText(ColumnNames[i]);
textColumn.setPadding(0, 0, 1, 0);
textColumn.setTextColor(getResources().getColor(R.drawable.text_default));
row.addView(textColumn, new TableRow.LayoutParams());
}
table.addView(row, new TableLayout.LayoutParams());
Respostas:
A solução abaixo incorpora todas as sugestões aqui. Começa com o que foi originalmente publicado por Dunni. Ele usa uma pesquisa binária como a do gjpc, mas é um pouco mais legível. Ele também inclui as correções de erros do gregm e uma correção de erro própria.
fonte
<com.example.zengame1.FontFitTextView android:paddingTop="5dip" android:id="@+id/childs_name" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:layout_gravity="center" android:textSize="@dimen/text_size"/>
float hi = this.getHeight() - this.getPaddingBottom() - this.getPaddingTop();
Eu escrevi uma classe que estende o TextView e faz isso. Ele apenas usa o measureText como você sugere. Basicamente, ele possui um tamanho máximo de texto e um tamanho mínimo de texto (que podem ser alterados) e apenas percorre os tamanhos entre eles em decréscimos de 1 até encontrar o maior que cabe. Não é particularmente elegante, mas não conheço outra maneira.
Aqui está o código:
fonte
É do speedplane
FontFitTextView
, mas apenas diminui o tamanho da fonte, se necessário, para ajustar o texto e mantém o tamanho da fonte caso contrário. Não aumenta o tamanho da fonte para caber na altura.Aqui está um exemplo de como ele pode ser usado no xml:
Isso manteria o tamanho da fonte em 60sp, contanto que o texto caiba na largura. Se o texto for mais longo, diminuirá o tamanho da fonte. Nesse caso, a
TextView
altura s também mudará por causa deheight=wrap_content
.Se você encontrar algum erro, fique à vontade para editar.
fonte
this.setMeasuredDimension(parentWidth, height);
match_parent
ewrap_content
.text.isEmpty()
seria"".equals(text)
.Aqui está minha solução que funciona em emulador e telefones, mas não muito bem no editor de layout Eclipse. Ele é inspirado no código de kilaka, mas o tamanho do texto não é obtido no Paint, mas na medição da própria chamada do TextView
measure(0, 0)
.A classe Java:
O arquivo de atributo XML:
Verifique no meu github a versão mais recente desta classe. Espero que possa ser útil para alguém. Se um bug for encontrado ou se o código precisar de explicação, fique à vontade para abrir um problema no Github.
fonte
Muito obrigado a https://stackoverflow.com/users/234270/speedplane . Ótima resposta!
Aqui está uma versão aprimorada de sua resposta que também cuida da altura e vem com um atributo maxFontSize para limitar o tamanho da fonte (foi útil no meu caso, então eu queria compartilhá-la):
Arquivo /res/values/attr.xml correspondente:
Exemplo:
Para usar o novo
maxFontSize
atributo, não se esqueça de adicionarxmlns:res-auto="http://schemas.android.com/apk/res-auto"
como mostra o exemplo.fonte
Eu tive o mesmo problema e escrevi uma aula que parece funcionar para mim. Basicamente, usei um layout estático para desenhar o texto em uma tela separada e medir até encontrar um tamanho de fonte adequado. Você pode ver a turma postada no tópico abaixo. Espero que ajude.
Dimensionar texto automaticamente o TextView para caber dentro dos limites
fonte
Agora você pode fazer isso sem uma biblioteca de terceiros ou um widget. Ele foi incorporado ao TextView no nível 26 da API. Adicione
android:autoSizeTextType="uniform"
ao seuTextView
e defina a altura para ele. Isso é tudo.https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html
Você também pode usar
TextViewCompat
para compatibilidade.fonte
Ligeira modificação para onMeasure:
E pesquisa binária no refitText:
fonte
trySize *= availableWidth / measured_width
(então fixado no minTextSize).Eu encontrei o seguinte para trabalhar bem para mim. Ele não faz loop e é responsável por altura e largura. Observe que é importante especificar a unidade PX ao chamar setTextSize na exibição. Graças à dica em um post anterior para isso!
Aqui está a rotina que eu uso, passando o getPaint () da exibição. Uma cadeia de 10 caracteres com um caractere 'largo' é usada para estimar a largura independentemente da cadeia real.
fonte
Funciona com modificação
Você precisa definir o tamanho da exibição de texto como este, pois, caso contrário, setTextSize assume que o valor está em unidades SP:
E você precisava adicionar explicitamente esse código.
fonte
Use
app:autoSizeTextType="uniform"
para compatibilidade com versões anteriores, porqueandroid:autoSizeTextType="uniform"
funciona apenas na API nível 26 e superior.fonte
Eu usei uma variação da solução Dunni acima, mas esse código específico não funcionou para mim. Em particular, ao tentar usar o objeto Paint definido para ter as características do objeto Paint da exibição e depois chamar measureText (), ele não retorna o mesmo valor que chamar diretamente o objeto Paint da exibição. Talvez haja algumas diferenças na maneira como minhas opiniões são configuradas que tornam o comportamento diferente.
Minha solução foi usar diretamente o Paint da exibição, embora possa haver algumas penalidades de desempenho ao alterar o tamanho da fonte da exibição várias vezes.
fonte
Eu tenho trabalhado para melhorar a excelente solução do speedplane e criei isso. Ele gerencia a altura, incluindo a configuração da margem para que o texto seja centralizado corretamente na vertical.
Isso usa a mesma função para obter a largura, pois parece funcionar melhor, mas usa uma função diferente para obter a altura, pois a altura não é fornecida em nenhum lugar. Existem algumas correções que precisam ser feitas, mas descobri uma maneira de fazer isso, parecendo agradável aos olhos.
fonte
O Google já criou esse recurso.
https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html
fonte
Eu tive essa dor nos meus projetos por muuuuito tempo até encontrar esta biblioteca:
Você só precisa adicionar o xml de acordo com suas necessidades e pronto. Por exemplo:
fonte
Inspirado nos pôsteres anteriores, eu queria compartilhar minha solução. Ele funciona com um fator de escala que é aplicado ao tamanho da fonte anterior para ajustá-lo ao espaço disponível. Além de impedir o comportamento inesperado do método TextViews onDraw, ele simplesmente desenha o texto por conta própria.
fonte
fonte
Essa deve ser uma solução simples:
fonte
Estenda o TextView e substitua onDraw pelo código abaixo. Ele manterá a proporção do texto, mas será dimensionada para preencher o espaço. Você pode modificar facilmente o código para esticar, se necessário.
fonte
Eu escrevi uma classe auxiliar curta que faz com que uma visualização de texto caiba dentro de uma certa largura e adicione reticências "..." no final se o tamanho mínimo de texto não puder ser alcançado.
Lembre-se de que ele só reduz o texto até que caiba ou até que o tamanho mínimo seja atingido. Para testar com tamanhos grandes, defina o tamanho do texto como um número grande antes de chamar o método de ajuda.
São necessários Pixels; portanto, se você estiver usando valores de dimen, poderá chamá-lo assim:
Esta é a classe que eu uso:
fonte
Se uma transformação como allCaps for definida, a abordagem do avião de velocidade é incorreta. Corrigi-o, resultando no seguinte código (desculpe, minha reputação não me permite adicionar isso como um comentário à solução do speedplane):
fonte
Eu não sabia que esta é a maneira correta ou não está funcionando ... veja sua opinião e verifique OnGlobalLayoutListener () e obtenha a contagem de linhas de textview e defina textSize.
É um código de linha muito simples.
fonte