如何动态地将片段添加到listview标题?

时间:2013-06-19 21:45:07

标签: android

我想在listview的标题中添加一个片段,可以通过xml完成​​,如下所示:

How to embed view of Fragment in the header of a ListFragment

但我想将参数传递给这个片段,据我所知,这只能动态完成(例如getFragmentManager().beginTransaction().add().commit()

所以我在招徕:

getActivity().getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.my_fragment_container, fragment)
                .commit();

my_fragment_container在标题中,但我得到了:

No view found for id 0x7f0a0089 (com.twitter.android:id/my_fragment_container) for fragment MyFragment {423d3320 #4 id=0x7f0a0089}

是否可以动态地将标题添加到标题中?或者,如果我只能通过xml来实现,是否有办法将参数传递给它(如setArguments())?

1 个答案:

答案 0 :(得分:5)

事件ListView会在onResume()之后的某个时刻附加标题视图。

因此,在标题视图添加到视图层次结构后,您必须仅添加片段。此外,您需要从FragmentManager中的onPause()中删除片段,否则,在返回此片段时,FragmentManager仍会知道之前添加的片段,并尝试查找id已指定。如果ListView再次附加标题视图,则无法使用。

还有一个问题。如果你:

  1. 向下滚动列表
  2. 点击某个项目
  3. 转到其他屏幕/活动
  4. 按HW返回
  5. 现在,ListView的位置与在(3)中离开屏幕之前的位置相同。但是,HeaderFragment尚未附加。然后,如果向上滚动直到标题视图变为可见,它将被附加。然后我们将HeaderFragment添加到标题视图和标题视图的高度更改中。然后,ListView发生了奇怪的事情。我还没有解决这个问题。

    如果您的HeaderFragment具有固定高度,则可以将标题视图设置为高,并完全避免此问题。

    假设您在ListView中显示Fragment,我的解决方法如下:

    public class MyListFragment extends Fragment {
    
        private Fragment headerFragment;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            headerFragment = HeaderFragment.newInstance();
        }
    
        @Override
        public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.list_layout, container, false);
    
            ListView list = (ListView) v.findViewById(R.id.list);
            View headerContainer = inflater.inflate(R.layout.list_header_container);
            list.addHeaderView(headerContainer);
    
            headerContainer.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                @Override public void onViewDetachedFromWindow(View v) {}
                @Override public void onViewAttachedToWindow(View v) {
                    getChildFragmentManager()
                        .beginTransaction()
                        .add(R.id.list_header_container, headerFragment)
                        .commit();
                }
            });
    
            // Set adapter etc
    
            return v;
        }
    
        @Override
        public void onPause() {
            super.onPause();
            getChildFragmentManager()
                .beginTransaction()
                .remove(headerFragment)
                .commit();
        }
    }
    

    list_header_container.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/list_header_container"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"/>