首页 > 解决方案 > onMeasure 在 Android 6 的 Horizo​​ntalScrollView 中返回 widthMeasureSpec = 0

问题描述

我相信我的问题与此有关:在 Horizo​​ntalScrollView 时 widthMeasureSpec 为 0 长话短说,我正在尝试创建自定义水平滚动视图。在某些时候,我正在压倒一切

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

虽然这在 Android >= 7 中运行良好,但我在 Android <= 6 中得到的 widthMeasureSpec 值为 0。 measureChild 的代码在 API 23 和 24 之间更改:

在 API 23 中:

childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

在 API 24 中:

final int childWidthMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
                Math.max(0, MeasureSpec.getSize(parentWidthMeasureSpec) - horizontalPadding),
MeasureSpec.UNSPECIFIED);

我尝试使用 getter 从父视图获取宽度,但它没有按预期工作,因为只有一些调用获得正确的宽度。我还尝试在父级中覆盖 measureChild 并将最新的代码放在那里,但没有运气:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    measureChild(getTouchInterceptTextView(), widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void measureChild(View child, int parentWidthMeasureSpec,
                            int parentHeightMeasureSpec) {
    ViewGroup.LayoutParams lp = child.getLayoutParams();

    final int horizontalPadding = getPaddingLeft() + getPaddingRight();
    final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
            Math.max(0, MeasureSpec.getSize(parentWidthMeasureSpec) - horizontalPadding),
            MeasureSpec.UNSPECIFIED);

    final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
            getPaddingTop() + getPaddingBottom(), lp.height);
    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

我的整体文件在这里:https ://github.com/AdrienPoupa/VinylMusicPlayer/commit/ba0dfae7dd03771f3625b8393927986aad552e2a

重要的部分是:

<com.poupa.vinylmusicplayer.views.TouchInterceptHorizontalScrollView
                    android:id="@+id/title_scrollview"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <com.poupa.vinylmusicplayer.views.AutoTruncateTextView
                        android:id="@+id/title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:fontFamily="sans-serif"
                        android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />

</com.poupa.vinylmusicplayer.views.TouchInterceptHorizontalScrollView>

onMeasure 函数在 AutoTruncateTextView 中。我可以在 TouchInterceptHorizo​​ntalScrollView 中得到这些措施,但这似乎没有帮助。我尝试在 XML 中为 TouchInterceptHorizo​​ntalScrollView、AutoTruncateTextView 和两者添加 android:fillViewport="true",但它没有改变计算。

我该怎么做才能在 Android 6 及更低版本中获得正确的 widthMeasureSpec 值?

谢谢你的帮助!

标签: android

解决方案


经过多次尝试,通过将以下代码段添加到 AutoTruncateTextView 的 onMeasure 似乎可以正常工作:

if (textBoundsWidth == 0) {
            textBoundsWidth =  getTouchInterceptFrameLayout().getMeasuredWidth();
        }

基本上,获取 TouchInterceptFrameLayout 的宽度,即 XML 文件的第 2 级

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="72dp"
    android:foreground="?attr/rectSelector"
    tools:ignore="UnusedAttribute">

    <!-- for getSwipeableContainerView() -->
    <com.poupa.vinylmusicplayer.views.TouchInterceptFrameLayout
        android:id="@+id/dummy_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

并保留上面发布的代码,否则截断机制不再起作用。


推荐阅读