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

我有一个TableLayoutFragment 。 表中的数据来自SQLite数据库。 SQLite数据库从MainActivity中的AsyncTask中的REST风格的Web服务中填充。 在填充表之前, Fragment必须等待任务完成。 Fragment监听要调用的onPostExecute()方法的任务。 如果是,则调用Fragment中的onLoadAndStoreComplete()方法。 这一切工作。

我需要在片段的OnCreateView()方法之外获得TableLayout的视图。 如果我可以在onLoadAndStoreComplete中得到片段的视图,那会让我在那里。

与此处相同的代码。 我从MainActivity得到了mContext ,但没有getView()方法与之相关联。

我试过了:
– 在onCreateView()中创build一个类成员rootView并进行赋值,但在onLoadAndStoreComplete()为null。
– 在onCreateView()中创build类成员tableLayout并进行赋值,但在onLoadAndStoreComplete()为null。
– 在onLoadAndStoreComplete() ()中再次调用onLoadAndStoreComplete() ,但是它返回null。
– 在onLoadAndStoreComplete()里面调用充气机,这个工作正常,但是我不知道在.inflate()调用中容器使用什么

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

 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)); } ... } 

Solutions Collecting From Web of "如何获得OnCreateView()之外的片段的视图"

如果我正确地理解了你的代码,那么你的代码不尊重Fragment生命周期或者不同的Fragment实例失败

A.生命周期问题

Android框架期望你的Fragment在onCreateView()方法中创build它的视图。 视图框架调用这个方法之后变得可用。

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! ... } } } 

B.不同的实例失败

当您在上述片段的两个不同的实例上操作时,可能会发生这种情况。

起初,所有东西都会按顺序排列: onCreateView()onLoadAndStoreComplete()之前onLoadAndStoreComplete() 。 因此检查这些:

  • logging/debugging你的Fragment的默认构造函数调用。 您希望在创build/载入stream程中获得您的分段的一个呼叫。
  • 检查调用onCreateView()的对象是否与调用onLoadAndStoreComplete()对象完全相同,可以使用System.identityHashCode(this) ,在这两个方法中获取不同的值是一个不好的符号

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

getView()给出从onCreatedView()返回的片段的rootView。 所以如果在onCreatedView()完成之前调用onLoadAndStoreComplete() (它不能返回你的rootView),你会得到null因为还没有创build视图。


我试图调用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 } } 

从代码片段中,如果在调用onCreateView(..)之后初始化字段rootViewtableLayout ,如果两个字段在此之后没有被设置为null,那么当您调用onLoadAndStoreComplete(..)时,它们必须不为null。

说,我想你是在你的片段的不同实例中调用该方法。 检查您的活动代码,并检查您是否始终使用片段中的相同实例。

我需要在片段的OnCreateView()方法之外获得TableLayout的视图。 如果我可以在onLoadAndStoreComplete中得到片段的视图,那会让我在那里。

尝试更改onLoadAndStoreComplete的定义来获取一个视图,然后传入片段的视图。

你确定onLoadAndStoreComplete()在onCreateView()之后被调用吗? 实例variables为null的唯一原因是初始化它们的方法没有被调用。

我build议你在onAttach,onDetach,onCreate,onCreateView,onStart,onStop,onLoadAndStoreComplete中调用Log.d来查看调用的顺序。 之后,更新你的问题与日志输出,看看哪些可能是问题,可能我可以给你一个更简洁的答案。

你可以做一些修正:

如果在启动片段之前调用了asynchronous任务,那么可以在onCreateView之前调用onLoadAndStoreComplete的callback函数(并且所有的视图都没有膨胀)

您可以从onCreateView执行asyncTask,但是您必须显示一个加载程序来告诉用户应用程序正在同步

你也可以使用listview而不是tableLayout:

 public class MyFragment extends Fragment implements OnLoadAndStoreCompleteListener { private ListView listView; private View rootView; private MyAdapter adapter; private List<T> mDatas; /// This one is populated like you want, from onLoadAndStoreComplete @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mContext = this.getActivity(); rootView = inflater.inflate(R.layout.fragment_permits, container, false); // this works listView = (ListView) rootView.findViewById(R.id.main_table); // and this mDatas = new List<>(); adapter = new MyAdapter(); tableLayout.setAdapter(adapter); } @Override public void onLoadAndStoreComplete() { adapter.notifyDataSetChanged(); } private class MyAdapter extends BaseAdapter{ @Override public int getCount() { // TODO Auto-generated method stub return mDatas.size() == 0 ? 1 : mDatas.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mDatas.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (mDatas.size()==0){ // inflate new view with only a progressbar indefinite LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.row_loading, parent, false); return convertView; } else{ // list is populated LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.row_datas, parent, false); // do inflating view stuff return convertView; } } } 

你需要修改你的tableLayout到一个ListView(在RelativeLayout?内)