在PopupWindow中正确创建一个Fragment

19

我是Android开发的新手,对于如何实现我想要做的事情感到困惑。我已经阅读了一些关于片段(Fragment)的资料,以便可以在不同屏幕大小的设计之间共享布局和代码。我创建了几个片段,并成功地使用了它们。但是,我遇到了这样一种情况:我想在手机上的常规活动中显示一个片段,但想在平板电脑上的PopupWindow(或类似的东西,如果有更好的选择)中显示该片段。

我设法找出如何在单击按钮时膨胀(inflate)片段并在PopupWindow中显示它。我的代码看起来像这样:

public void onClick(View v) {
    LayoutInflater inflater = (LayoutInflater) BrowsingActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View popupLayout = inflater.inflate(R.layout.serverconnection_fragment, null, false);
    connectionListPopup = new PopupWindow(popupLayout, 300, 470, true);
    connectionListPopup.showAtLocation(BrowsingActivity.this.findViewById(R.id.connectionListImage), Gravity.CENTER, 0, 0);
}
弹出窗口出现了,其中包含了serverconnection_fragment.xml中描述的UI。问题是通过这种方式创建它时,Fragment类ServerConnectionFragment.java从未实例化,因此我的UI中没有任何列表项、按钮监听器等等。似乎应该有一种方法可以实例化Java类,让它正常填充片段并附加事件侦听器,然后将在那里创建的视图传递到PopupWindow构造函数中,但我无法弄清楚如何做。有人能帮帮我吗?
FYI,我正在使用Android-support-v4.jar文件为Fragment类构建Android 2.1应用程序。
1个回答

20

直接填充布局不会导致其实例化片段;Android只会认为片段和活动都试图引用同一布局文件是巧合。

通常,您可以使用FragmentManager.add(int,Fragment)将片段添加到布局中。但是,指定的容器ID必须是当前 Activity 布局的一部分,而这在 PopupWindow 中并不是这种情况。相反,您必须在没有指定容器的情况下将片段添加到片段管理器中,然后稍后在片段中(例如 onStart())显示 PopupWindow。这正是 DialogFragment 的工作方式,因为它已经有了很多支持,我建议您改用 DialogFragment。

使用您的Fragment代码,只需扩展DialogFragment而不是Fragment,并使用DialogFragment.show(FragmentManager,String)来显示它。您可以通过在 onCreate 方法中调用 setStyle(DialogFragment.STYLE_NO_FRAME,getTheme())来去除默认边框。您仍然可以将此Fragment添加到布局中(如您所说,在手机上您不希望它显示为弹出窗口),并且它将按照您的期望工作。

绝对正确的答案,谢谢。此外,当我们在PopupWindow中显示列表时,它拒绝显示我们为列表指定的ContextMenu。转而使用DialogFragment让我们解决了这个问题。 - Mark Rausch
1
请问您能否解释或举例说明您最后一句话的意思,如果可能的话,将该片段添加到Popupwindow中作为初始示例?“您仍然可以将此Fragment添加到布局中(正如您所说,在手机上,您不希望它显示为弹出窗口),它将按照您的期望工作。” - JPMagalhaes
1
@JPMagalhaes,强烈建议不要在PopupWindow中使用fragment,因为这可能会引入内存泄漏问题。 - LiangWang
我们能否为DialogFragment实现像PopupWindow一样的拖放功能? - heyjii
这将如何解决使用PopupWindow提供的相对视图定位问题? - Pepster

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