如果按钮文本行数不同,垂直线性布局中的加权按钮会切断文本
Weighted buttons in vertical linear layout cutting off text if button text line counts vary
TL;DR:这是我能想到的与我面临的问题相关的所有要点:[GIST LINK]
这是问题的图片
我正在尝试设置一些按钮,这些按钮将在垂直方向的 LinearLayout
容器中通过相等的权重增长到彼此相同的大小。
当这些按钮上的文本导致每个按钮的行数不同时,我面临的问题浮出水面。
假设 n
是按钮的最低行数,m
是最高行数;行数为 m
的按钮文本中的任何下行部分都将被截断。请参阅链接屏幕截图中的 "qshowing my clipping problem"
字样,其中所有下行部分都被切断。
我该如何解决这个问题?如果我将 android:lineSpacingExtra
引入按钮样式,剪辑会变得更糟。
如果相关,我的最小 API 设置为 21
我已经使用 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()
}
// ...
}
我猜,主要原因是按钮有固定大小。更重要的是,您使用 LinearLayout
通过 weight
属性在按钮之间共享可用空间。您可以看到单行按钮高度与两行按钮高度相同。所以 2 行按钮被迫剪裁文本。
根据您的 XML 文件,您希望在没有更多空间时启用垂直滚动。在这种情况下,您不需要使用 weight
属性。只是彼此下方有边距的按钮。
TL;DR:这是我能想到的与我面临的问题相关的所有要点:[GIST LINK]
这是问题的图片
我正在尝试设置一些按钮,这些按钮将在垂直方向的 LinearLayout
容器中通过相等的权重增长到彼此相同的大小。
当这些按钮上的文本导致每个按钮的行数不同时,我面临的问题浮出水面。
假设 n
是按钮的最低行数,m
是最高行数;行数为 m
的按钮文本中的任何下行部分都将被截断。请参阅链接屏幕截图中的 "qshowing my clipping problem"
字样,其中所有下行部分都被切断。
我该如何解决这个问题?如果我将 android:lineSpacingExtra
引入按钮样式,剪辑会变得更糟。
如果相关,我的最小 API 设置为 21
我已经使用 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()
}
// ...
}
我猜,主要原因是按钮有固定大小。更重要的是,您使用 LinearLayout
通过 weight
属性在按钮之间共享可用空间。您可以看到单行按钮高度与两行按钮高度相同。所以 2 行按钮被迫剪裁文本。
根据您的 XML 文件,您希望在没有更多空间时启用垂直滚动。在这种情况下,您不需要使用 weight
属性。只是彼此下方有边距的按钮。