34

我在列表中设置自定义标题时遇到了一些问题。

我正在使用自定义适配器创建 ListFragment。我的列表工作正常,但我试图找出在片段的生命周期中附加标题的位置。

我知道必须在设置适配器之前添加标题。

我尝试在 onActivityCreated 中添加我的标头,但是每次我的 Fragment 从后台堆栈返回时都会调用它,并且由于我还在 onActivityCreated 中设置了我的适配器,所以它失败了。

我尝试在 onCreate 中添加它,但视图层次结构在生命周期的那个阶段不可用。

我尝试将它添加到 onCreateView 中,但我无法将从 inflate 返回的视图转换为 ListView。所以我无法将我的标题添加到香草视图中。

有什么想法吗?

4

7 回答 7

34

我不知道你是否解决了你的问题,但这里有一个对我有用的解决方案:

不要调用ListFragment.setListAdapter()你的ListFragment.onCreate(). 确保您有一个可以保存标题视图的字段变量,例如:

View mheaderView;

然后在你的ListFragment.onCreateView(),膨胀标题 View 并将其分配给你的变量,如下所示:

View list_root = inflater.inflate(R.layout.fragment_list, null);
// Get the list header - to be added later in the lifecycle
// during onActivityCreated()
mheaderView = inflater.inflate(R.layout.list_header, null);
return list_root;

最后,在你的ListFragment.onActivityCreated() 你现在可以调用ListFragment.getListView().addHeaderView(). 基本上是这样的:

super.onActivityCreated(savedInstanceState);
if (mheaderView != null)  this.getListView().addHeaderView(headerView);
// Don't forget to now call setListAdapter()
this.setListAdapter(listAdapter);
于 2011-06-01T18:30:12.957 回答
32

此解决方案适用于屏幕翻转:

在 onActivityCreated() 中:

getListView().addHeaderView(mHeaderView);
if (mMyAdapter == null) {
    mMyAdapter = new MyAdapter(getActivity(), null);
}
setListAdapter(mMyAdapter);

在 onDestroyView()

setListAdapter(null);
于 2011-11-15T18:53:41.437 回答
18

我的解决方案:

public void onActivityCreated(Bundle savedInstanceState) {
    setListAdapter(null);
    getListView().addHeaderView(mHeader);
    setListAdapter(mAdapter);
}
于 2012-04-06T17:08:36.483 回答
2

这是我在列表视图中处理页脚/页眉的解决方案。我在保留片段中使用它。适配器在 renderView() 方法中初始化。这个方法可以被调用多少次你需要(例如刷新视图中的数据)并且页脚/页眉工作正常。我在 Android 2、3、4 上测试了这段代码。

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

    ...

    renderView();
}


@Override
public void onDestroyView()
{
    super.onDestroyView();

    // free adapter
    setListAdapter(null);
}


private void renderView()
{
    // reference
    ListView listView = getListView();

    // adapter
    if(getListAdapter()==null)
    {
        // init adapter
        mAdapter = new MyAdapter(...);
    }
    else
    {
        // refill adapter
        // this method assign array list object to adapter and call notifyDataSetChanged()
        mAdapter.refill(...);
    }

    // add footer
    setListAdapter(null);
    if(listView.getFooterViewsCount()==0)
    {
        mFooterView = getActivity().getLayoutInflater().inflate(R.layout.my_footer, null);
        listView.addFooterView(mFooterView);
    }

    // set adapter
    setListAdapter(mAdapter);
}
于 2012-10-20T19:51:02.350 回答
2

作为对我有用的简短解决方案:

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

    View headerView = getActivity().getLayoutInflater().inflate(R.layout.header, null);
    getListView().addHeaderView(headerView);

    ArrayAdapter<XY> mAdapter = createAdapter(); // create here your own adapter
    setListAdapter(mAdapter);
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    setListAdapter(null);
}
于 2013-03-02T14:19:46.050 回答
0

我目前在我的类扩展中使用以下解决方案ListFragment

1)你,在你的类中onActivityCreated检查你的适配器(这是一个类变量)是否为空,然后实例化它。然后,膨胀页脚,例如:

View footerView = View.inflate
    (getActivity(), R.layout.list_footer_loader_view, null);

你只需要这样做一次!footerView 和适配器只需要创建一次。我在我的onActivityCreated

现在到“困难的部分”,在 onCreate 中设置你的片段,如下所示:

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

我喜欢这样做,onCreate因为它与活动无关。现在,setRetainInstance(true)在活动被销毁后,您的片段将不会重新创建,例如屏幕方向之类的事件。

现在在这些行之后添加如下页脚:

getListView().addFooterView(footerView);

然后将适配器连接到列表:

setListAdapter(adapter);

每次活动结束时都应该这样做,在onActivityCreated.

当涉及到片段时,您通常应该考虑的其他重要事情之一是,您不会在每次onCreate调用活动时都创建片段。

例如这样做(如果您使用支持包):

MyFragment myFragment  = (MyFragment)
    getFragmentManager().findFragmentByTag(tag);
if (myFragment == null) {
    myFragment = MyFragment.newInstance();
    getFragmentManager().beginTransaction().
            add(myFragment, tag).commit();
}

如果标签对于该片段是唯一的,这只会创建一次片段。

于 2013-02-15T19:07:45.760 回答
0

我在标题布局高度方面遇到了一些问题,所以我遵循了这个解决方案

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setListAdapter(null);//avoid problems with orientation changes
    header = getActivity().getLayoutInflater().inflate(R.layout.row_diario_header,getListView(),false);
    getListView().addHeaderView(header);
    ArrayList<Notificacao> nots = new ArrayList<>();

    nots.add(new Notificacao("16/04/2015", "Test", "Erro"));
    setListAdapter(new DiarioAdapter(getActivity(), R.layout.listview_diario, nots));
}

Header 是 View 的一个实例,而 DiarioAdapter 是一个自定义的 ArrayAdapter。

更新 1

如果您遇到重复列表片段的问题,只需将 FragmentTransaction ADD 更改为 REPLACE。

于 2015-04-17T19:22:41.313 回答