Взвешенные кнопки в вертикальной линейной разметке обрезают текст, если количество строк в кнопке варьируется - PullRequest
0 голосов
/ 18 мая 2019

TL; DR: Вот суть всего, что я могу придумать, который имеет отношение к проблеме, с которой я сталкиваюсь: [GIST LINK]

И вот картина проблемы

Text cutting off problem: illustrated

Я пытаюсь настроить количество кнопок, которые будут расти до одинакового размера друг с другом при одинаковом весе в вертикально ориентированнойLinearLayout контейнер.

Проблема, с которой я сталкиваюсь на поверхностях, когда текст на этих кнопках вызывает различное количество строк на кнопку.

Скажем, n - это наименьшее число строк длякнопки и m - наибольшее количество строк;любые спуски в тексте кнопок с количеством строк m обрезаются.Обратитесь к словам "qshowing my clipping problem" в связанном скриншоте, где все спуски обрезаны.

Как я могу исправить это?Отсечение становится намного хуже, если я добавлю android:lineSpacingExtra к стилю кнопки.

Если это уместно, мой минимальный API установлен на 21

Ответы [ 2 ]

0 голосов
/ 18 мая 2019

Полагаю, основная причина в том, что кнопки имеют фиксированный размер. Более того, вы используете LinearLayout, чтобы разделить доступное пространство между кнопками с помощью атрибута weight. Вы можете видеть, что высота кнопки в одну строку совпадает с высотой кнопки в 2 строки. Поэтому 2-строчные кнопки вынуждены обрезать текст.

В соответствии с вашим XML-файлом вы хотите включить вертикальную прокрутку, когда места больше нет. В этом случае вам не нужно использовать атрибут weight. Просто кнопки друг под другом с полями.

0 голосов
/ 18 мая 2019

Я исправил это, используя RxJava, чтобы программно установить высоту на правильный максимум, чтобы не происходило отсечение.Если есть лучшее решение, я буду рад его видеть, но сейчас это работает для меня:

class MyActivity {

    // ...

    private val compositeDisposable = CompositeDisposable()

    override fun onCreate(savedInstanceState: Bundle?) {
        setContentView(R.layout.my_activity)
        // ...

        val container: LinearLayout = findViewById(R.id.container)

        val numBtns = getNumBtnsToAdd()
        val btnList: MutableList<Button> = mutableListOf()
        val margin10 = dpToPx(10f).toInt()

        val countDown = CountDownLatch(numBtns)
        val desiredLp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0).apply {
            gravity = Gravity.CENTER
            setMargins(margin10, margin10, margin10, margin10)
        }

        // Completable will be run once per subscriber and emit a success or error
        val layoutCompletable = Completable.fromAction {
            countDown.await()
            for (btn in btnList) btn.layoutParams = desiredLp
        }.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())

        compositeDisposable.add(
            layoutCompletable.subscribe({
                Log.d("MyActivity", "Set LayoutParams on all buttons.")
            }, Throwable::printStackTrace)
        )

        for (i in 0 until numBtns) {
            val btn = Button(this, null, 0, R.style.button_style).apply {
                layoutParams = LinearLayout.LayoutParams(desiredLp).apply { height = LinearLayout.LayoutParams.WRAP_CONTENTS }
                text = if (i == 0) "Button${i+1} with short text"
                              else "Button${i+1} with text that will span multiple lines showing my clipping problem"
                setOnClickListener { doSomething() }
            }

            val listener = object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    countDown.countDown()
                    val height = btn.height
                    if (height > desiredLp.height) desiredLp.height = height
                    btn.viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            }
            btn.viewTreeObserver.addOnGlobalLayoutListener(listener)
            btnList.add(btn)
            container.addView(btn)
        }

        // ...
    }

    override fun finish() {
        compositeDisposable.clear()
        super.finish()
    }

    // ...

}
...