【问题标题】:Get view height when part of the view is off screen?当部分视图不在屏幕上时获取视图高度?
【发布时间】:2019-03-11 14:13:19
【问题描述】:

假设我有一个类似的视图结构

<ConstraintLayout>
    <CustomViewLayout>
        ...
        ...
    </CustomViewLayout>
</ConstraintLayout>

这是简化的,但我在底部工作表中使用上述内容,有时我会根据 CustomViewLayout 的高度更改 ConstraintLayout 的高度和底部工作表的窥视高度。我的问题是,如果CustomViewLayout 的一部分被切断,也就是说 - 它有点在屏幕之外,因为ConstraintLayout 不够高 - 我不再能够获得正确的“全高”它。在这种情况下,我似乎总是只能在视图的屏幕上看到可见部分。

那么我怎样才能获得部分不在屏幕上的视图的完整高度呢?

谢谢!

编辑:

我应该补充一点,我尝试过的是globalLayoutListener,以及customViewLayout.post {}(当然还有通常的customViewLayout.height)。但是当视图的一部分在屏幕之外时,这些都不能测量整个高度。

【问题讨论】:

  • 试试 view.getMeasuredHeight()/Width()
  • @ZaidMirza 很有趣,但我不明白为什么会这样 :) ?

标签: java android kotlin android-view


【解决方案1】:

为了检查我之前的答案,我开发了一个测试项目来检查确切的情况。当布局的某些部分在屏幕之外时测量布局高度是成功的(布局高度测量4231px,屏幕高度为1920px)。如果视图足够长而无法完全显示在屏幕上,则应将其置于可滚动视图中。因此,我将customViewLayout 放入NestedScrollView 以在底部表格展开后消耗剩余的滚动量。这是代码和结果:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:showIn="@layout/activity_main"
    tools:context=".MainActivity">

    <android.support.constraint.ConstraintLayout
        android:id="@+id/layoutBottomSheet"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:id="@+id/customViewLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:background="@color/colorAccent">

                <TextView
                    android:id="@+id/stateTextView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#FFFFFF"
                    android:layout_marginTop="16dp"
                    android:gravity="center_horizontal"/>

                <TextView
                    android:id="@+id/sizeTextView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#FFFFFF"
                    android:padding="24dp"
                    android:gravity="center_horizontal"/>

                <TextView
                    android:id="@+id/contentTextView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#FFFFFF"
                    android:padding="24dp"
                    android:text="@string/lorem"
                    android:gravity="center_horizontal"/>

            </LinearLayout>

        </android.support.v4.widget.NestedScrollView>

    </android.support.constraint.ConstraintLayout>

</android.support.design.widget.CoordinatorLayout>

MainActivity:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        customViewLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                customViewLayout.viewTreeObserver.removeGlobalOnLayoutListener(this)
                val height = customViewLayout.measuredHeight
                val width = customViewLayout.measuredWidth
                sizeTextView.text = "Height: $height px                Width: $width px"
            }
        })

        val sheetBehavior = BottomSheetBehavior.from(layoutBottomSheet)
        sheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            override fun onSlide(bottomSheet: View, offset: Float) {
            }

            override fun onStateChanged(bottomSheet: View, newState: Int) {
                when (newState) {
                    BottomSheetBehavior.STATE_HIDDEN -> stateTextView.text = "State: Hidden"
                    BottomSheetBehavior.STATE_EXPANDED -> stateTextView.text = "State: Expanded"
                    BottomSheetBehavior.STATE_COLLAPSED -> stateTextView.text = "State: Collapsed"
                    BottomSheetBehavior.STATE_DRAGGING -> stateTextView.text = "State: Dragging"
                    BottomSheetBehavior.STATE_SETTLING -> stateTextView.text = "State: Settling"
                }
            }
        })
    }

}

屏幕:

【讨论】:

  • 您可能走在了正确的轨道上,必须将视图放在ListView 中,这太棒了!我会在下周尝试,如果它有效,我会确保回复你。但我确实相信它应该有效:)。在此感谢!
【解决方案2】:

如果你正在寻找视图的宽度和高度,试试这个:

mCustomViewLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mCustomViewLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            int height = mCustomViewLayout.getMeasuredHeight()
            int width = mCustomViewLayout.getMeasuredWidth()
        }
    });

【讨论】:

  • 感谢您的回答,但这无济于事。这只是确保我们在布局视图时进行测量,但如果部分视图在外部,它仍然测量“错误”屏幕。我可能应该补充一下我已经尝试过的问题:)
猜你喜欢
  • 1970-01-01
  • 2020-05-18
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多