【问题标题】:Unable to scroll a Fragment added dynamically (Java)无法滚动动态添加的片段 (Java)
【发布时间】:2021-07-18 00:08:47
【问题描述】:

我正在开发一个应用程序,我需要在一个活动中使用 2 个片段。根据对第一个片段所做的选择,将显示第二个片段。问题是第二个片段没有向下滚动,在屏幕末尾被切断。

这里是包含“固定”和动态插入片段的活动的 XML (activity_inspection.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
    tools:context=".activities.InspectionActivity"
    android:padding="@dimen/margins">

    <fragment
        android:id="@+id/chooseItemMemorial"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.xxxx.xxxxx.fragments.InspectionMemorial"/>

    <FrameLayout
        android:id="@+id/show_fragment_selected"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/chooseItemMemorial"
        android:layout_marginTop="@dimen/top_margins"/>

</androidx.constraintlayout.widget.ConstraintLayout>

这是我想动态插入到我的活动中的片段之一的 sn-p:(fragment_external_access.xml)

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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="wrap_content"
    android:scrollbars="vertical"
    tools:context=".fragments.ExternalAccessFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
/** here goes the rest of the code**/

编辑:我想要实现的是通过&lt;fragment&gt; 标签添加的第一个片段保持固定在屏幕上,而通过代码动态添加的第二个片段能够在必要时滚动。

我尝试使用 ScrollViewNestedScrollView 没有成功。但这可能是一些愚蠢的错误,比如忘记添加标签。由于我是 android 编程新手,我们将不胜感激。

为了结束这个(因为它可能是相关的),这是我用来添加这个片段的 java 代码:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_external_access, container, false);
    }

【问题讨论】:

    标签: java android android-layout android-fragments android-constraintlayout


    【解决方案1】:

    问题是顶部的fragment(First Fragment)可能很贪心,以至于它可以占据整个屏幕,原因是它的高度是wrap_content,所以它可以尽可能多地占用它所缺少的底部约束。

    在这种情况下,底部片段可以部分显示甚至隐藏在屏幕下方。

    如果底部片段有更大的内容,同样适用,顶部片段将部分/完全隐藏,因为底部片段的wrap_content

    所以你需要限制两个片段的高度不使用wrap_content

    这里我将使用app:layout_constraintHeight_max 属性作为顶部片段,但你必须处理它的内容是否可以大于该值; ScrollView 是您在底部片段(第二片段)中所做的可能选项之一。

    并设置两个片段的高度以匹配约束。

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
        android:padding="@dimen/margins"
        tools:context=".activities.InspectionActivity">
    
        <fragment
            android:id="@+id/chooseItemMemorial"
            class="com.xxxx.xxxxx.fragments.InspectionMemorial"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_max="100dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <FrameLayout
            android:id="@+id/show_fragment_selected"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginTop="@dimen/top_margins"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/chooseItemMemorial" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    【讨论】:

    • 那么我需要对&lt;FrameLayout&gt; 做的是为它定义一个高度,对吧?它确实有效,所以非常感谢你!我只是认为在具有不同屏幕尺寸的不同设备上使用时这可能是一个问题。有什么方法可以在不“硬编码”大小的情况下使 ScrollView 滚动?
    • 你需要限制高度..你已经用wrap_content定义了一个高度..但是在这种情况下高度是根据内容变化的..所以如果内容很长,那么它两个片段可以重叠,并且可能一个片段可以被踢出屏幕..你可以像我一样用约束来限制高度
    • @CorMatt 你也可以把两个片段共享整个高度,这样每个片段可以占一半;甚至每个人都可以占一个百分比..所有这些都受到限制...如果这有意义,请接受答案
    • 啊,所以我可以为每个片段定义一个屏幕百分比吗?我不知道,我花了几乎一整天的时间寻找它。非常感谢!
    【解决方案2】:

    发生这种情况是因为您的滚动视图 layout_height 设置为 wrap_content 从而扩展以适应其所有内容。您应该将其设置为 match_parent,

    编辑:根据新信息,您可以构建如下布局

    活动

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
        android:padding="@dimen/margins"
        tools:context=".activities.InspectionActivity">
    
        <fragment
            android:id="@+id/chooseItemMemorial"
            class="com.xxxx.xxxxx.fragments.InspectionMemorial"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHeight_max="100dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <ScrollView 
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="@dimen/top_margins"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/chooseItemMemorial" 
            android:scrollbars="vertical">
    
            <FrameLayout
                android:id="@+id/show_fragment_selected"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </ScrollView>
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    片段

    <androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
        tools:context=".fragments.ExternalAccessFragment">
    
    /** here goes the rest of the code**/
    

    这样顶部片段占用了它需要的空间(最多 100dp,正如您使用 app:layout_constraintHeight_max 指定的那样),下面的滚动视图占用所有剩余空间,其中包含另一个片段,其中包含 wrap_content 高度。

    【讨论】:

    • 嗯,它确实允许创建滚动...但是发生的是第二个片段占据了整个屏幕,被绘制在“静态”插入的片段上,就像这里的图片:@ 987654321@
    • 那么,您想要实现的是 2 个片段相互堆叠并滚动整个页面,还是一个填充固定区域而第二个片段的内容滚动?
    • 啊,我应该指定的更好,不是吗?我希望第一个片段(由&lt;fragment&gt; 标签创建的片段固定在屏幕上,同时能够上下滚动第二个片段的内容。
    猜你喜欢
    • 2020-01-31
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多