在ListFragment中添加HeadView的最佳位置
我在列表中设置自定义标题时遇到了一些麻烦。
我正在用一个自定义适配器创build一个ListFragment。 我有清单工作正常,但我想弄清楚在一个片段的生命周期中附加标题。
我知道在设置适配器之前,必须添加标题。
我尝试在onActivityCreated中添加我的头文件,但每当我的Fragment从后台返回时都会调用它,因为我也在onActivityCreated中设置适配器,所以失败。
我试图将其添加到onCreate中,但是在生命周期的这个阶段,视图层次结构不可用。
我试图将其添加到onCreateView,但我不能将从膨胀返回到ListView的视图。 所以我不能将我的标题添加到一个香草视图。
有什么想法吗?
我不知道你是否已经解决了你的问题,但这里有一个解决scheme适用于我:
不要在ListFragment.setListAdapter()
中调用ListFragment.onCreate()
。 确保你有一个可以容纳标题视图的字段variables,例如:
View mheaderView;
然后在你的ListFragment.onCreateView()
,膨胀标题视图并将它赋值给你的variables,如下所示:
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);
此解决scheme适用于屏幕翻转:
在onActivityCreated()中:
getListView().addHeaderView(mHeaderView); if (mMyAdapter == null) { mMyAdapter = new MyAdapter(getActivity(), null); } setListAdapter(mMyAdapter);
并在onDestroyView()
setListAdapter(null);
我的解决scheme
public void onActivityCreated(Bundle savedInstanceState) { setListAdapter(null); getListView().addHeaderView(mHeader); setListAdapter(mAdapter); }
这是我在列表视图中处理页脚/页眉的解决scheme。 我用它保留片段。 适配器在renderView()方法中初始化。 这个方法可以被称为你需要多less次(例如刷新数据)和页脚/头工作正常。 我在Android 2,3,4上testing了这个代码。
@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); }
作为简短的解决scheme,为我工作:
@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); }
我正在使用我的类扩展ListFragment
下面的解决scheme:
1)你,在你的类onActivityCreated
检查你的适配器(这是一个类variables)是否为空,然后实例化它。 然后,例如像这样膨胀页脚:
View footerView = View.inflate (getActivity(), R.layout.list_footer_loader_view, null);
你只需要做一次! footerView和适配器只需要创build一次。 我在我的onActivityCreated
创build了这两个
现在到“困难的部分”,在你的onCreate中设置你的片段如下:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); }
我喜欢在onCreate
做,因为它与活动无关。 现在,使用setRetainInstance(true)
,在活动被销毁之后,您的分段将不会被重新创build,例如屏幕方向。
现在,在这些行之后添加页脚如下所示:
getListView().addFooterView(footerView);
然后将适配器连接到列表:
setListAdapter(adapter);
这应该是每当活动死亡,在onActivityCreated
做到这一点。
而其他重要的事情之一,你应该通常考虑什么时候它是碎片是你不创build片段,每当活动的onCreate
被调用。
例如,做到这一点(如果你不使用支持包):
MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentByTag(tag); if (myFragment == null) { myFragment = MyFragment.newInstance(); getFragmentManager().beginTransaction(). add(myFragment, tag).commit(); }
这只会创build片段一次,如果标签是唯一的片段当然。
我有一些头部布局高度的问题,所以我遵循这个解决scheme :
@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
如果你有重复listfragment的问题,只需更改FragmentTransaction ADD为REPLACE。