How to get an idea of ​​a fragment outside OnCreateView ()

I have a Fragment with TableLayout . The data in the table is taken from SQLite db. SQLite db populates from a RESTful web service in AsyncTask in MainActivity . Fragment must wait for the task to complete before populating the table. Fragment listens for the onPostExecute() method call. When this is the case, the onLoadAndStoreComplete() method in Fragment called. It all works.

I need to get a TableLayout outside the OnCreateView() method of the fragment. If I could get an idea of ​​the fragment in onLoadAndStoreComplete to get me there.

The same code as here. I have mContext from MainActivity, but it does not have the getView() method associated with it.

I tried:
- creating a member of the rootView class and assigning it to onCreateView (), but in onLoadAndStoreComplete() it is null.
- creating the tableLayout class and assigning it to onCreateView (), but in onLoadAndStoreComplete() it is null.
- calling this.getView () again in onLoadAndStoreComplete() , but it returns null.
- the call of the inflator inside onLoadAndStoreComplete() , which works, but then I do not know what to use for the container in the call .inflate()

I don't understand why the values ​​of the rootView class member and tableLayout are null in 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)); } ... } 
+8
android android-fragments
source share
6 answers

If I understand your code correctly, there is something that your code does not correspond to the fragment life cycle or another fragment instance .

but. Life cycle problem

The Android framework expects your fragment to create its view inside the onCreateView() method. The view becomes available after the framework calls this method.

It is possible that your code named onLoadAndStoreComplete() before onCreateView() , and this caused the problem.

You need to extract a method to fill the actual views with data, since it can have 2 entry points. See code below:

 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. Miscellaneous Instance Failure

This can happen if you work in two different instances before the mentioned fragment.

At first, everything will look fine: onCreateView() , called before onLoadAndStoreComplete() . Therefore, check the following:

  • The default logical / debug constructor for your fragment. You expect to receive one call for your fragment during the create / load stream.
  • Check if the object named onCreateView() the same object called onLoadAndStoreComplete() , you can use System.identityHashCode(this) , getting different values ​​in these two methods is a bad sign

If this is what happens, the reason is probably hidden a little deeper, and without code I cannot give you exact advice on this. How do you create your fragment? Via XML or manually, then adding via FragmentManager or via ViewPager?

+6
source share

getView() gives the rootView of Fragment, which is returned from onCreatedView() . Therefore, if onLoadAndStoreComplete() is called before onLoadAndStoreComplete() is completed (which it cannot return rootView), you get null since the view has not yet been created.


I tried calling getView() inside onViewCreated() , which is NOT 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 } } 
+5
source share

From the code snippet, if the rootView and tableLayout initialized after calling onCreateView(..) , if both fields are not set to null after that, then they must be non-zero when calling onLoadAndStoreComplete(..) .

Said that, I think, you are calling this method in another instance of your fragment. Review your activity code and make sure that you always use the same instance from the fragment.

+2
source share

I need to get an idea of ​​the TableLayout outside the OnCreateView () Fragment method. If I could get an idea of ​​the fragment in onLoadAndStoreComplete, which takes me there.

Try changing the definition of onLoadAndStoreComplete to get a view and then pass it as a fragment.

+1
source share

Are you sure that onLoadAndStoreComplete () is called after onCreateView ()? The only reason that instance variables are null is because the method that initializes them is not called.

I suggest you put the call in Log.d in onAttach, onDetach, onCreate, onCreateView, onStart, onStop, onLoadAndStoreComplete to see in which order it is called. After that, update your question using the log output to find out what problem might be the problem, and maybe I could give you a more concise answer.

+1
source share

You can make several corrections:

If the asynchronous task is called before the fragment starts, then your callback onLoadAndStoreComplete can be called before the onCreateView (and all your views are not pumped up)

You can execute asyncTask from onCreateView, but you need to display the bootloader to tell the user that the application is syncing

You can also use listview, not 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; } } } 

You need to change the Layout table in ListView (inside RelativeLayout?)

+1
source share

All Articles