【问题标题】:Add a fragment as ListView header添加一个片段作为 ListView 标头
【发布时间】:2012-09-27 21:51:47
【问题描述】:

我的目标是 API 15 和最低 8 的 Android 应用程序。所以我使用支持库来管理片段。我有一组片段,我在应用程序的几个部分中使用它们。

现在,在一个活动中,我的布局中有一个 ListView:

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/listOfEvents"
    android:layout_width="match_parent" android:layout_height="match_parent">
</ListView>

我想在 ListView 标题中添加我的一个片段。我试过这个:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.event_open);

    listOfEvents = (ListView) findViewById(R.id.listOfEvents);

            Fragment fragment = new SortingStandardFragment();
            getSupportFragmentManager()
              .beginTransaction()
                  .add(fragment, null)
              .commit();

            View fragmentView = fragment.getView(); // problem: fragment is null!
            listOfEvents.addHeaderView(fragmentView);
    }

但我得到一个错误,因为 fragment.getView() 返回 null(api 参考文档说我必须在 add 调用中放置一个 GroupView Id,但是我应该将 GroupView 放在布局中的哪个位置? 还有其他方法可以达到目标吗?

【问题讨论】:

  • 我不确定这是否可以这样工作,但片段的想法是创建一个设置 id 的框架布局(您可以通过在资源中添加 id 名称来制作 id),添加为标题,然后制作一个用片段替换该 id 的事务

标签: android android-listview android-fragments android-support-library


【解决方案1】:

我通过在列表标题中创建一个仅包含我需要的片段的新布局来解决这个问题:

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

    <fragment
        android:id="@+id/myFragmentEmbedded"
        android:name=".SortingStandardFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

在活动代码中:

LayoutInflater inflater = getLayoutInflater();
header = inflater.inflate(R.layout.myLayout, null);
listOfEvents.addHeaderView(header);

SortingStandardFragmenttitleFragment = (SortingStandardFragment) 
     getSupportFragmentManager()
          .findFragmentById(R.id.myFragmentEmbedded);

【讨论】:

    【解决方案2】:

    我想要一个版本,而不必求助于另一个 xml 文件,所以就这样吧:

    Fragment fragment = ...
    FrameLayout v = new FrameLayout(getActivity());
    v.setId(42);
    listView.addHeaderView(v, null, false);
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.beginTransaction().add(v.getId(), fragment).commit();
    

    【讨论】:

    • 最好在 ids.xml 文件中声明 id,以确保没有重叠 id 的风险。
    • 如果您将标头容器添加到 ListView 而不是在 onCreate 中(可能是在请求之后),您的应用程序会在 onBackPressed() 中崩溃,因为 listview 在停止后会破坏子项(您的标头容器) - fragmentmanager 不会将您的片段注入容器
    【解决方案3】:

    如果有人好奇为什么他的第一次尝试失败了:

    • 生命周期事件发布到 UI 线程
    • Fragment.onCreateView 是一个生命周期事件
    • Activity.onCreate 是一个生命周期事件
    • .getView()Fragment.onCreateView 中返回创建的视图
    • commit 发布生命周期事件

    结论:commit 的结果在 onCreate 返回之后的下一个循环中可见。

    阅读文档后,可以尝试强制 commitgetSupportFragmentManager().executePendingTransactions() 直接联系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多