Latar Belakang
Sering kali kita perlu menyesuaikan font TextView secara otomatis dengan batasan yang diberikan padanya.
Masalah
Sedihnya, meskipun ada banyak utas dan pos (dan solusi yang disarankan) membicarakan masalah ini (contoh di sini , di sini dan di sini ), tidak satu pun dari mereka yang benar-benar berfungsi dengan baik.
Itu sebabnya, saya memutuskan untuk menguji masing-masing sampai saya menemukan real deal.
Saya pikir persyaratan dari textView tersebut harus:
Harus memungkinkan penggunaan font, jenis huruf, gaya, dan serangkaian karakter apa pun.
Harus menangani lebar dan tinggi
Tidak ada pemotongan kecuali teks tidak dapat ditampung karena batasan, kami berikan padanya (contoh: teks terlalu panjang, ukuran terlalu kecil yang tersedia). Namun, kami dapat meminta bilah gulir horizontal / vertikal jika diinginkan, hanya untuk kasus-kasus tersebut.
Harus memungkinkan multi-line atau single-line. Dalam hal multi-line, izinkan jalur maks & min.
Seharusnya tidak lambat dalam perhitungan. Menggunakan loop untuk menemukan ukuran terbaik? Setidaknya optimalkan dan jangan tambahkan sampel Anda sebanyak 1 kali setiap kali.
Dalam kasus multi-line, harus memungkinkan untuk lebih suka mengubah ukuran atau menggunakan lebih banyak baris, dan / atau memungkinkan untuk memilih sendiri garis dengan menggunakan karakter "\ n".
Apa yang saya coba
Saya sudah mencoba begitu banyak sampel (termasuk yang ada di tautan, saya sudah menulis), dan saya juga mencoba memodifikasinya untuk menangani kasus-kasus, saya sudah bicarakan, tetapi tidak ada yang benar-benar berfungsi.
Saya telah membuat proyek sampel yang memungkinkan saya untuk melihat apakah TextView secara otomatis cocok dengan benar.
Saat ini, proyek sampel saya hanya mengacak teks (alfabet Inggris plus digit) dan ukuran textView, dan membiarkannya tetap dengan satu baris, tetapi bahkan ini tidak bekerja dengan baik pada sampel yang saya coba.
Berikut kodenya (juga tersedia di sini ):
Mengajukan res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity">
<Button android:id="@+id/button1" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" android:text="Button" />
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_above="@+id/button1"
android:layout_alignParentLeft="true" android:background="#ffff0000"
android:layout_alignParentRight="true" android:id="@+id/container"
android:layout_alignParentTop="true" />
</RelativeLayout>
Mengajukan src/.../MainActivity.java
public class MainActivity extends Activity
{
private final Random _random =new Random();
private static final String ALLOWED_CHARACTERS ="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ViewGroup container=(ViewGroup)findViewById(R.id.container);
findViewById(R.id.button1).setOnClickListener(new OnClickListener()
{
@Override
public void onClick(final View v)
{
container.removeAllViews();
final int maxWidth=container.getWidth();
final int maxHeight=container.getHeight();
final FontFitTextView fontFitTextView=new FontFitTextView(MainActivity.this);
final int width=_random.nextInt(maxWidth)+1;
final int height=_random.nextInt(maxHeight)+1;
fontFitTextView.setLayoutParams(new LayoutParams(width,height));
fontFitTextView.setSingleLine();
fontFitTextView.setBackgroundColor(0xff00ff00);
final String text=getRandomText();
fontFitTextView.setText(text);
container.addView(fontFitTextView);
Log.d("DEBUG","width:"+width+" height:"+height+" text:"+text);
}
});
}
private String getRandomText()
{
final int textLength=_random.nextInt(20)+1;
final StringBuilder builder=new StringBuilder();
for(int i=0;i<textLength;++i)
builder.append(ALLOWED_CHARACTERS.charAt(_random.nextInt(ALLOWED_CHARACTERS.length())));
return builder.toString();
}
}
Pertanyaan
Apakah ada yang tahu solusi untuk masalah umum ini yang benar-benar berfungsi?
Bahkan solusi yang memiliki fitur jauh lebih sedikit dari apa yang saya tulis, misalnya yang hanya memiliki jumlah baris teks yang konstan, dan menyesuaikan fontnya sesuai dengan ukurannya, namun tidak pernah memiliki gangguan aneh dan membuat teks terlalu besar / kecil dibandingkan dengan ruang yang tersedia.
Proyek GitHub
Karena ini adalah TextView yang sangat penting, saya memutuskan untuk menerbitkan perpustakaan, sehingga semua orang dapat dengan mudah menggunakannya, dan berkontribusi di sini .
sumber
Jawaban:
Berkat MartinH ini memperbaiki sederhana di sini , kode ini juga mengurus
android:drawableLeft
,android:drawableRight
,android:drawableTop
danandroid:drawableBottom
tag.Jawaban saya di sini seharusnya membuat Anda senang Text Scale TextView Text agar Sesuai dalam Batas
Saya telah memodifikasi test case Anda:
Saya memposting kode di sini sesuai permintaan pengembang android :
Efek akhir:
File Tata Letak Sampel:
Dan kode Java:
Peringatan:
Waspadalah terhadap bug yang diselesaikan ini di Android 3.1 (Honeycomb).
sumber
Saya telah memodifikasi jawaban M-WaJeEh sedikit untuk memperhitungkan drawable akun.
The
getCompoundPaddingXXXX()
metode kembalipadding of the view + drawable space
. Lihat misalnya: TextView.getCompoundPaddingLeft ()Masalah: Ini memperbaiki pengukuran lebar dan tinggi ruang TextView yang tersedia untuk teks. Jika kami tidak memperhitungkan ukuran yang dapat ditarik, itu diabaikan dan teks akan berakhir tumpang tindih dengan yang dapat ditarik.
Segmen yang diperbarui
adjustTextSize(String)
:sumber
Ok Saya telah menggunakan pekan lalu secara besar-besaran menulis ulang kode saya untuk tepat sesuai dengan tes Anda. Anda sekarang dapat menyalin 1: 1 ini dan itu akan segera berfungsi - termasuk
setSingleLine()
. Harap diingat untuk menyesuaikanMIN_TEXT_SIZE
danMAX_TEXT_SIZE
jika Anda menggunakan nilai ekstrem.Algoritma konvergen terlihat seperti ini:
Dan seluruh kelas dapat ditemukan di sini.
Hasilnya sangat fleksibel sekarang. Ini berfungsi sama dinyatakan dalam xml seperti:
... serta dibangun secara terprogram seperti dalam pengujian Anda.
Saya sangat berharap Anda dapat menggunakan ini sekarang. Anda dapat menelepon
setText(CharSequence text)
sekarang untuk menggunakannya. Kelas menangani pengecualian luar biasa langka dan harus solid. Satu-satunya hal yang belum didukung oleh algoritma adalah:setMaxLines(x)
tempatx >= 2
Tetapi saya telah menambahkan komentar luas untuk membantu Anda membangun ini jika Anda mau!
Tolong dicatat:
Jika Anda hanya menggunakan ini secara normal tanpa membatasinya menjadi satu baris saja maka mungkin ada pemecahan kata seperti yang Anda sebutkan sebelumnya. Ini adalah fitur Android , bukan kesalahan
AutoFitText
. Android akan selalu memecahkan kata-kata yang terlalu panjang untuk TextView dan itu sebenarnya cukup nyaman. Jika Anda ingin campur tangan di sini daripada silakan lihat komentar dan kode saya mulai dari baris 203. Saya sudah menulis pemisahan yang memadai dan pengakuan untuk Anda, yang perlu Anda lakukan selanjutnya adalah membagi kata-kata dan kemudian memodifikasi sesuai keinginan .Kesimpulannya: Anda harus mempertimbangkan untuk menulis ulang tes Anda untuk mendukung ruang angkasa, seperti:
Ini akan menghasilkan hasil yang sangat indah (dan lebih realistis).
Anda akan menemukan komentar untuk memulai Anda dalam masalah ini juga.
Semoga sukses dan salam
sumber
Persyaratan saya adalah untuk
Saya merujuk tautan: Skala Otomatis TextView Teks agar Sesuai dengan Batas (termasuk komentar) dan juga DialogTitle.java
Saya menemukan bahwa solusi yang diberikan bagus dan sederhana tetapi tidak secara dinamis mengubah ukuran kotak teks. Ini bekerja dengan baik ketika panjang teks yang dipilih dari tampilan daftar lebih besar dalam ukuran daripada panjang teks yang ada di
ScalableTextView
. Ketika memilih teks yang memiliki panjang lebih kecil dari teks yang ada diScalableTextView
, itu tidak menambah ukuran teks, menunjukkan teks dalam ukuran lebih kecil.Saya memodifikasi ScalableTextView.java untuk menyesuaikan kembali ukuran teks berdasarkan panjang teks. Ini milik saya
ScalableTextView.java
Selamat Coding ....
sumber
Saya akan menjelaskan cara kerja atribut ini versi Android yang lebih rendah selangkah demi selangkah:
1- Impor pustaka dukungan android 26.xx pada file gradle proyek Anda. Jika tidak ada perpustakaan dukungan di IDE, mereka akan mengunduh secara otomatis.
2- Buka file XML tata letak Anda dan refactor seperti ini tag TextView Anda. Skenario ini adalah: ketika ukuran font bertambah pada sistem, sesuaikan teks dengan lebar yang tersedia, bukan bungkus kata.
sumber
Peringatan, bug di Android 3 (Honeycomb) dan Android 4.0 (Ice Cream Sandwich)
Versi Android: 3.1 - 4.04 memiliki bug, yang setTextSize () di dalam TextView hanya berfungsi untuk pertama kalinya (doa pertama).
Bug ini dijelaskan dalam Edisi 22493: Bug ketinggian TextView di Android 4.0 dan Edisi 17343: tinggi dan teks tombol tidak kembali ke kondisi semula setelah menambah dan mengurangi ukuran teks pada HoneyComb .
Solusinya adalah menambahkan karakter baris baru ke teks yang ditetapkan ke TextView sebelum mengubah ukuran:
Saya menggunakannya dalam kode saya sebagai berikut:
Saya menambahkan karakter "\ u3000" ini di kiri dan kanan teks saya, agar tetap terpusat. Jika Anda telah menyelaraskan ke kiri lalu tambahkan ke kanan saja. Tentu saja dapat juga tertanam dengan widget AutoResizeTextView, tetapi saya ingin tetap memperbaiki kode di luar.
sumber
Sekarang ada solusi resmi untuk masalah ini. Autosizing TextViews yang diperkenalkan dengan Android O tersedia di Perpustakaan Dukungan 26 dan kompatibel sepenuhnya hingga Android 4.0.
https://developer.android.com/preview/features/autosizing-textview.html
Saya tidak yakin mengapa https://stackoverflow.com/a/42940171/47680 yang juga termasuk informasi ini dihapus oleh admin.
sumber
Dari Juni 2018 Android secara resmi mendukung fitur ini untuk Android 4.0 (API level 14) dan lebih tinggi.
Dengan Android 8.0 (API level 26) dan lebih tinggi:
Versi Android sebelum Android 8.0 (API level 26):
Lihat jawaban detail saya .
sumber
Konversi tampilan teks menjadi gambar, dan skala gambar dalam batas-batas.
Berikut ini contoh cara mengonversi tampilan ke Gambar: Mengonversi tampilan ke Bitmap tanpa menampilkannya di Android?
Masalahnya adalah, teks Anda tidak akan dapat dipilih, tetapi harus melakukan trik. Saya belum mencobanya, jadi saya tidak yakin bagaimana tampilannya (karena penskalaan).
sumber
Di bawah ini adalah avalancha TextView dengan fungsionalitas tambahan untuk Font kustom.
Pemakaian:
Jangan lupa untuk menambahkan: xmlns: foo = "http://schemas.android.com/apk/res-auto". Font harus dalam firectory aset
bug yang diketahui: Tidak bekerja dengan Android 4.03 - fonta tidak terlihat atau sangat kecil (avalancha asli tidak berfungsi juga) di bawah ini adalah solusi untuk bug itu: https://stackoverflow.com/a/21851239/2075875
sumber
Coba ini
sumber
Jika Anda mencari sesuatu yang lebih mudah:
sumber
Perbaikan cepat untuk masalah yang dijelaskan oleh @Malachiasz
Saya telah memperbaiki masalah dengan menambahkan dukungan khusus untuk ini di kelas ubah ukuran otomatis:
Panggil saja
yourView.setTextCompat(newTextValue)
alih-alihyourView.setText(newTextValue)
sumber
Coba tambahkan
LayoutParams
danMaxWidth
danMaxHeight
keTextView
. Ini akan memaksa tata letak untuk menghormati wadah induk dan tidak meluap.sumber
Karena Android O, dimungkinkan untuk mengubah ukuran teks secara otomatis dalam xml:
https://developer.android.com/preview/features/autosizing-textview.html
sumber
Setelah saya mencoba Android resmi Autosizing TextView , saya menemukan jika versi Android Anda sebelum Android 8.0 (API level 26), Anda perlu menggunakan
android.support.v7.widget.AppCompatTextView
, dan pastikan versi perpustakaan dukungan Anda di atas 26.0.0. Contoh:perbarui :
Menurut balasan @ android-developer, saya memeriksa
AppCompatActivity
kode sumber, dan menemukan dua baris ini dionCreate
final AppCompatDelegate delegate = getDelegate(); delegate.installViewFactory();
dan di
AppCompatDelegateImpl
'screateView
itu menggunakan
AppCompatViewInflater
tampilan inflater, ketikaAppCompatViewInflater
createView itu akan menggunakan AppCompatTextView untuk "TextView".Dalam proyek saya, saya tidak menggunakan
AppCompatActivity
, jadi saya perlu menggunakan<android.support.v7.widget.AppCompatTextView>
dalam xml.sumber
AppCompatActivity
. AppCompatActivity menggunakan tata letak inflater inflater AppCompatViewInflater.