I have a Fragment
with a TableLayout
. The data in the table is from a SQLite db. The SQLite db is populated from a RESTful webservice in an AsyncTask
in the MainActivity
. The Fragment
must wait for the task to complete before populating the table. The Fragment
listens for the task onPostExecute()
method to be called. When it is, the method onLoadAndStoreComplete()
in the Fragment
is called. This all works.
I need to get a view of a TableLayout
outside the OnCreateView()
method of a Fragment. If I could get the View of the fragment in onLoadAndStoreComplete
that would get me there.
Same code as here.
I've got mContext
from the MainActivity, but that has no getView()
method associated with it.
I've tried:
- making a class member rootView and assigning in onCreateView(), but in onLoadAndStoreComplete()
, it is null.
- making a class member tableLayout and assigning in onCreateView(), but in onLoadAndStoreComplete()
, it is null.
- calling this.getView() again in onLoadAndStoreComplete()
, but it returns null.
- calling the inflator inside onLoadAndStoreComplete()
, which works, but then I don't know what to use for container in the .inflate()
call
I don't understand why the class member values of rootView 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));
}
...
}
onCreate(Bundle) called to do initial creation of the fragment. onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment. onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity. onCreate() .
onCreate() is called to do initial creation of the fragment. onCreateView() is called by Android once the Fragment should inflate a view. onViewCreated() is called after onCreateView() and ensures that the fragment's root view is non-null .
The onActivityCreated() method is called after onCreateView() and before onViewStateRestored() . onDestroyView() : Called when the View previously created by onCreateView() has been detached from the Fragment . This call can occur if the host Activity has stopped, or the Activity has removed the Fragment .
The onCreate() is called first, for doing any non-graphical initialisations. Next, you can assign and declare any View variables you want to use in onCreateView() .
If I understand your code correctly, there is something wrong either with your code not respecting Fragment lifecycle or a different Fragment instance failure.
A. Lifecycle problem
Android framework expects your Fragment to create its view inside onCreateView()
method. View becomes available after framework calls this method.
It is possible that your code called onLoadAndStoreComplete()
before onCreateView()
, and this has caused the problem.
You need to extract method for populating actual views with data, as it can have 2 entry points. Please 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. Different instance failure
This may occur when you're operating on 2 different instances of before mentioned fragment.
At first everything will look in order: onCreateView()
called before onLoadAndStoreComplete()
. Therefore check these:
onCreateView()
is the exact same object that called onLoadAndStoreComplete()
, you can use System.identityHashCode(this)
, getting different values within this two methods is a bad signIf this is what happens, cause is probably hidden a bit deeper, and without code I cannot give you accurate advice on this. How do you create your fragment? Via XML or manually then adding via FragmentManager or via ViewPager?
getView()
gives rootView of Fragment which is returned from onCreatedView()
. So if onLoadAndStoreComplete()
gets called before onCreatedView()
is finished (which it can't return your rootView), you get null
since there is not view created yet.
I have 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
}
}
From your code fragment, if fields rootView
and tableLayout
are initialized after calling onCreateView(..)
, if both fields are not setted to null after that then they must be not null when you call onLoadAndStoreComplete(..)
.
Said that, I think you are calling that method in a different instance of your fragment. Review your activity code and check that you are using the same instance from the fragment all the time.
I need to get a view of a TableLayout outside the OnCreateView() method of a Fragment. If I could get the View of the fragment in onLoadAndStoreComplete that would get me there.
Try changing the definition of onLoadAndStoreComplete to take a View and then passing in a view of the fragment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With