如何获取OnCreateView()之外的片段视图

Al *_*ath 9 android android-fragments

我有Fragment一个TableLayout.表中的数据来自SQLite数据库.SQLite数据库是从一个RESTful Web服务中填充AsyncTaskMainActivity.将Fragment必须等待任务填充表之前完成.在Fragment为任务监听onPostExecute()方法被调用.当是时,该方法onLoadAndStoreComplete()Fragment被调用.这一切都有效.

我需要在片段TableLayoutOnCreateView()方法之外看到一个视图.如果我可以获得片段的视图,onLoadAndStoreComplete那将会让我在那里.

与此处相同的代码.mContext从MainActivity获得,但没有getView()与之相关的方法.

我已经尝试过:
- 创建一个类成员rootView并在onCreateView()中进行分配,但是在onLoadAndStoreComplete()它中,它是null.
- 创建一个类成员tableLayout并在onCreateView()中分配,但在onLoadAndStoreComplete(),它是null.
- 再次调用this.getView()onLoadAndStoreComplete(),但它返回null.
- 调用内部的充气机 onLoadAndStoreComplete(),这是有效的,但后来我不知道在.inflate()呼叫中 使用什么容器

我不明白为什么rootView和tableLayout的类成员值为null onLoadAndStoreComplete()

public class MyFragment extends Fragment implements OnLoadAndStoreCompleteListener {

private TableLayout tableLayout;
private View rootView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
        mContext = this.getActivity();
        rootView = inflater.inflate(R.layout.fragment_permits, container, false); // this works
        tableLayout = (TableLayout) rootView.findViewById(R.id.main_table); // and this
        ...
    }

    @Override
    public void onLoadAndStoreComplete() {

       // rootView is null, ie not remembered from OnCreateView

        View view =  getView(); // null

        LayoutInflater inflater = LayoutInflater.from(getActivity());
      rootView = inflater.inflate(R.layout.fragment_permits, container, false); // container? don't know what it should be

        // tableLayout is null
        tableLayout.addView(tableRow, new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

jsk*_*rbi 7

如果我正确理解您的代码,那么您的代码不遵守Fragment生命周期不同的Fragment实例失败就会出现问题.

A.生命周期问题

Android框架希望您的Fragment在onCreateView()方法内创建其视图.框架调用此方法后,视图变为可用.

您的代码可能onLoadAndStoreComplete()之前调用过onCreateView(),这导致了问题.

您需要提取用数据填充实际视图的方法,因为它可以有2个入口点.请参阅以下代码:

public class MyFragment extends Fragment implements OnLoadAndStoreCompleteListener {
    private TableLayout tableLayout;
    private View rootView;
    private SomeDataClass loadedData;

    @Override
    public View onCreateView(LayoutInflater inflater, 
                             ViewGroup container,
                             Bundle savedInstanceState) {
        mContext = this.getActivity();
        rootView = inflater.inflate(R.layout.fragment_permits, container, false); 
        tableLayout = (TableLayout) rootView.findViewById(R.id.main_table);

        updateUi(); // If onLoadAndStoreComplete() was already called
                    // this will plug newly created view to returned data
    }

    @Override
    public void onLoadAndStoreComplete() {
        loadedData = ...; // Save loaded data here
        updateUi(); // If onCreateView() was already called
                    // this will plug loaded data to the view
    }


    private void updateUi() {
        if (rootView == null) { // Check if view is already inflated
            return; 
        }

        if (loadedData != null) {
            // View is already inflated and data is ready - update the view!
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

B.不同的实例失败

当您在前面提到的片段的2个不同实例上操作时,可能会发生这种情况.

首先,一切都将按顺序查看:onCreateView()之前调用onLoadAndStoreComplete().请检查以下内容:

  • 记录/调试Fragment的默认构造函数调用.您期望在创建/加载流程期间为您的片段调用一次.
  • 检查被调用的对象是否是被调用onCreateView()的完全相同的对象,onLoadAndStoreComplete()可以使用System.identityHashCode(this),在这两种方法中获取不同的值是一个不好的标志

如果这是发生的事情,原因可能隐藏得更深一些,没有代码我就不能给你准确的建议.你如何创建你的片段?通过XML或手动然后通过FragmentManager或ViewPager添加?


Jem*_*rov 6

getView()给出从中返回的片段的rootView onCreatedView().因此,如果onLoadAndStoreComplete()onCreatedView()完成之前调用(它无法返回rootView),则会得到,null因为尚未创建视图.


我试过调用getView()里面onViewCreated()的非null:

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        View viewer=getView();
        if(viewer==null){
            Itu.showToast("null",getActivity(), Toast.LENGTH_LONG);
        }else{
            Itu.showToast(viewer.toString(),getActivity(), Toast.LENGTH_LONG);//This is called
        }
    }
Run Code Online (Sandbox Code Playgroud)