2

在我的应用程序中,我有一个带有 TextView 的叠加层,它具有动态的文本大小和内容,并且可以使用触摸来移动。目标是使叠加层与文本大小相同。将 WRAP_CONTENT 用于覆盖,不会将包含文本的 LinearLayout 扩展到文本的全宽。

该示例加载与 Activity 的内容视图和叠加层相同的布局。使用 MATCH_PARENT,可以在 Overlay 中显示完整的 TextView,但这会使覆盖不能用于触摸事件,因为可以触摸整个宽度。如果没有 LinearLayout,它也不会扩展到整个宽度。当向文本添加更多行时,对于小于此最大宽度的宽度,wrap_content 按预期工作,而对于高度,wrap_content 按预期工作于整个设备高度。

如何在不使 TextView 或 LinearLayout 比文本更宽的情况下将 TextView 扩展到文本的全宽?

示例如下所示: 演示代码的结果

MainActivity.kt:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val view = LayoutInflater.from(this).inflate(R.layout.activity_main, null)

        val params = WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            0,
            PixelFormat.TRANSLUCENT
        )
        params.gravity = Gravity.START

        (getSystemService(WINDOW_SERVICE) as WindowManager).addView(view, params)
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#f66">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is a long test text. This is a long test text. This is a long test text. This is a long test text. This is a long test text. This is a long test text. "
        android:maxLines="1"
        android:background="#6f6" />
</LinearLayout>

(在 AndroidManifest.xml<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>中是必需的)

4

2 回答 2

1

等到TextView的布局之后添加您的叠加层。然后你可以强制你需要的宽度 - 像这样:

findViewById<TextView>(R.id.textView).doOnNextLayout { textView ->
    val view = LayoutInflater.from(this).inflate(R.layout.activity_main, null)
    val params = WindowManager.LayoutParams(
        textView.width,
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
        0,
        PixelFormat.TRANSLUCENT
    )
    params.gravity = Gravity.START

    val wm = getSystemService(WINDOW_SERVICE) as WindowManager
    wm.addView(view, params)
}

目前尚不清楚为什么添加的LinearLayout及其TextView的宽度受到限制。

于 2021-09-03T18:51:53.937 回答
0

在阅读了 Cheticamps 的答案后,我进行了更多搜索并找到了一个解决方案,该解决方案仅适用于视图的一个实例,并且会自动调整大小。

扩展TextView(或AppCompatTextView)覆盖onMeasure

class UnlimWidthTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : AppCompatTextView(context, attrs) {

    val unlimitedWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(unlimitedWidth, heightMeasureSpec)
    }
}

请注意这一点,因为它完全消除了对文本最大宽度的限制。

原件widthMeasureSpec的宽度始终为 420px,模式为MeasureSpec.AT_MOST,这解释了问题中显示的行为。我没有找到这个 420px 限制的来源。

高度具有屏幕高度 - 导航栏和 的预期值MeasureSpec.AT_MOST,因此它的行为与预期相同。

于 2021-09-04T12:12:30.373 回答