ScrollView > LinearLayout > PreferenceFragment 高度为零

7

我有一个包含ScrollView的活动,其中包含一个垂直LinearLayout,该LinearLayout具有两个PreferenceFragment实例作为以下布局文件中所示:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="wrap_content"
android:layout_width="match_parent"
>

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.foo.app.SettingsActivity">

    <fragment
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:name="com.foo.app.SettingsFragment"
        android:id="@+id/fragment_settings"/>

    <fragment
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:name="com.foo.app.NotificationSettingsFragment"
        android:id="@+id/fragment_notification_settings"/>

</LinearLayout>

问题是,两个片段只显示它们的PreferenceCategory标题,而实际的片段UI高度为零且不可见。奇怪的是,可以单独滚动每个片段并查看缺失的片段UI。就像每个Fragment都在一个ScrollView内一样。

我期望的是,两个片段被调整大小以适应其内容,并有一个单独的垂直滑块来滚动包含两个片段的LinearLayout。

如果相关的话,这两个片段扩展自android.preference.PreferenceFragment,并未在布局文件中定义它们的布局。相反,它们如下加载其首选项UI:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Load the preferences from an XML resource
    addPreferencesFromResource(R.xml.pref_notification);
}

感谢您的帮助。

找到了一些解决方案吗? - Ewoks
4个回答

6
问题早就存在了,但如果有人偶然遇到这个问题,我已经找到了解决办法。就像 @Ewoks 提到的那样,我也必须接受固定高度(这在不同设备dpi下并不总是运作良好)。
但是,通过这段代码的帮助,我成功地使高度动态化,从而很好地包裹内容。
在您的PreferenceFragment类中,请按以下步骤进行:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    if (getView() != null) {

        ListView listView = (ListView) getView().findViewById(android.R.id.list);
        Adapter adapter = listView.getAdapter();

        if (adapter != null) {
            int height = 0;
            //int height = listView.getPaddingTop() + listView.getPaddingBottom();

            for (int i = 0; i < adapter.getCount(); i++) {
                View item = adapter.getView(i, null, listView);

                item.measure(0, 0);
                height += item.getMeasuredHeight();
            }

            FrameLayout frame = (FrameLayout) getActivity().findViewById(R.id.content_frame); //Modify this for your fragment

            ViewGroup.LayoutParams param = frame.getLayoutParams();
            param.height = height + (listView.getDividerHeight() * adapter.getCount());
            frame.setLayoutParams(param);
        }
    }

}

希望这能帮助到某些人!

1
完美地工作了,肯定为我节省了数小时的调试时间!我使用的是动态添加的片段而不是定义好的片段,所以对于任何人来说,你可以使用 LinearLayout frame = (LinearLayout) getActivity().getFragmentManager().findFragmentByTag(getPrefTag()).getView(); 通过标签获取你的动态片段的视图,其中 #getPrefTag 是一个自定义方法,它简单地返回用于添加片段的定义标签。 - JCricket

6

移除外层的ScrollView。我遇到了同样的问题,而这个方法帮助我解决了问题。

尚未在文档中找到相关说明,但显然PreferenceFragment会在PreferenceScreen周围提供自己的ScrollView。这会导致包含第一个元素(如类别标题)的wrap_content高度刚好足够显示。


3
我有多个片段构成的自定义SettingsActivity。如果我删除外部ScrollView,则每个自定义设置片段中都会出现单独的垂直滚动条,这是不可取的,因为我只想要一个垂直滚动条。因此,上述解决方案不能满足我的需求。感谢您的帮助。 - Farrukh Najmi
2
有什么解决方案吗?我处于类似的情况,我的普通活动在其布局中有一些图片、按钮,在顶部和底部以及两个中间片段。如果这些片段的大小为0dp,建议它们不会占用太多空间,但它们是可滚动的(单独)。我想要实现的是整个屏幕同时滚动,这些片段需要占用尽可能多的空间(因此它们不会单独滚动)。目前,我只是将这些片段的高度设置为固定大小(例如300dp)。一点也不优雅;( - Ewoks
请查看我的答案:https://dev59.com/qX7aa4cB1Zd3GeqPro7L#59479279 - yonix

1

考虑到您无法移除外部的ScrollView,对我有用的方法是将其更改为android.support.v4.widget.NestedScrollView,然后在Activity的onCreate中运行以下代码:

findViewById(R.id.nested_scroll_view).setNestedScrollingEnabled(false);

1
我在一个ScrollView里有三个PreferenceFragment,将其改为NestedScrollView后运行良好。这应该是被接受的答案。 - marcinax

0

尝试在每个片段中设置android:layout_weight大约等于每个设置列表的大小。

<fragment
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.3"
    android:name="com.foo.app.SettingsFragment"
    android:id="@+id/fragment_settings"/>

<fragment
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.7"
    android:name="com.foo.app.NotificationSettingsFragment"
    android:id="@+id/fragment_notification_settings"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接