Unexpected NoSaveStateFrameLayout with support Fragment - android

I am in trouble when trying to get the baseView(inflated in onCreateView and returned) in fragment, because I receive unexpected NoSaveStateFrameLayout.
I don't know why, can anyone explain?
Code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LogUtil.d(TAG, "onCreateView ...");
View v = inflater.inflate(R.layout.gen_blank, container, false);
return v;
}
When I run this code in all life cycles:
LogUtil.v(TAG, "getview = "+getView());
It logs the same msg: getview = android.support.v4.app.NoSaveStateFrameLayout#41afdb70

The support library inserts an additional view into the view hierarchy. According to a comment in NoSaveStateFrameLayout.java: "Pre-Honeycomb versions of the platform don't have View.setSaveFromParentEnabled(), so instead we insert this between the view and its parent."
So you will need to either check for this with something like:
View myView = (NoSaveStateFrameLayout)getView();
if (myView != null) {
myView = myView.getChildAt(0);
}
Or keep track of the view returned by onCreateView in an instance variable.

Related

if (view == null) issues in fragment

I have updated my Sdk Oreo 8.0 When i come my current fragment to my previous fragment its crash because i am using if (view == null)
if i removed this condition it 'll work fine but have to load again view.
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.home_fragement_layout, container, false);
ButterKnife.bind(this, view);
bundle=getArguments();
registrationResponse=(RegistrationResponse)bundle.getSerializable("registerresponse");
setadapter();
hitUserFavouriteOutfitsapi();
swipeRefreshLayout.setOnRefreshListener(this);
}
toolBarTopChangeState =((ToolBarTopChangeState)context);
toolBarTopChangeState.stateChangeToolBarIcon(0);
toolBarTopChangeState.stateChangeToolBarText(getString(R.string.app_name));
return view;
}
Use this code:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.home_fragement_layout, container, false);
ButterKnife.bind(this, view);
bundle=getArguments();
registrationResponse=(RegistrationResponse)bundle.getSerializable("registerresponse");
setadapter();
hitUserFavouriteOutfitsapi();
swipeRefreshLayout.setOnRefreshListener(this);
toolBarTopChangeState =((ToolBarTopChangeState)context);
toolBarTopChangeState.stateChangeToolBarIcon(0);
toolBarTopChangeState.stateChangeToolBarText(getString(R.string.app_name));
return view;
}
On the lists is a good practice to check if the view is already created and if it's to use it further, but on the activities and fragments you should left the OS to decide when should inflate again the view. You can have a look over android lifecycle to understand better how it's works
it 'll happen because i am adding animation when fragment change and return to back.. This problem facing because of Android 8.0(Oreo) rest os working fine so I removed the animation during fragment change it 'll solved.

Display response-string in a Textview in a fragment

I´m getting stucked on a - probably - "easy" problem...
I´ve got a fragment which displays a TextView.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.fragment_rezepte_test, container, false);
TextView responseTV = (TextView) inflatedView.findViewById(R.id.tv_response);
return inflatedView;
}
Next I´ve got a private void GET-Method, whose response body I want to display in this
String responseBody = response.body().string();
responseTV.setText(responseBody);
Everytime the Fragment will open, the app crashes caused by a NPE
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Any idea? Thanks in advance
Let's try to call super.onCreateView(inflater, container, savedInstanceState)
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState)
View inflatedView = inflater.inflate(R.layout.fragment_rezepte_test, container, false);
TextView responseTV = (TextView) inflatedView.findViewById(R.id.tv_response);
return inflatedView;
}
Did you check your xml layout (fragment_rezepte_test.xml)? Make sure you have a TextView with the same id.
I am not very clear about the question and also not clear that exactly when you are trying to call this method response.body(), but please check whether your responsebody string is null or not and also use method isAdded() in case of fragments in every important method.
Edit : try to initialize that text view inside onActivityCreated and then use it.

getting a view using getResources()

I want to set text of a TextView that is inside a layout file,
I tried setContentView() but it isnt working since i am using fragments.
I tried using getResources().getLayout(R.layout.abc);
It returns null
I tried setContentView() but it isnt working since i am using
fragments
That's wrong. You have to override onCreateView and inflate and return the layout you want to show, and you can use onCreateView, and use its first parameter, View view, to call findViewById and access the widgets in your layout. You can read more here and here
inside fragment you can set view inside function onCreateView(), use below code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) {
View view = (LinearLayout) inflater.inflate(R.layout.my_layout, container, false);
return view;
}
here my_layout should be the name of layout file,
now you can get view of it inside function onviewcreated()
public void onViewCreated(View view, Bundle savedInstanceState){
// here you can get your textview and set its value
}
thumbs up, if you find my answer correct
You can inflate your layout like this:
ViewGroup group = LayouInflate.from(context).inflate(R.layout.abc,null);
TextView tv = group.findViewById(R.id.xxx);
you have to inflate the layout through the onCreateView method and then return the View.
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_layout, container, false);
TextView yourTextView = (TextView)rootView.findViewById(R.id.yourTextViewId);
return rootView;
}

Android how to recreate fragment view

I have an Android fragment. When I'm creating view I fill fields from layout with values from an model.
and at one point I want to recreate view using the same class model but with other values.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater
.inflate(R.layout.item_view, container, false);
editText = (EditText) v.findViewById(R.id.question_text);
questionText.setText(myModel.getName());
---------------
}
I have a private function which will call at on click on view
private void recreateView(MyModel model){
myModel = model;
//here I want to recall onCreateView or something like that but I don't know if that is ok, or is a more simple way to do that
}

Update the Fragment's UI dynamically after onLoadFinished from AsyncTaskLoader - Not able to obtain ViewGroup

Previously, I have a Fragment, which update its UI based on time consuming fetch data.
public class HomeMenuFragment extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Infos arg1 = performTimeConsumingDataStructureLoading();
// Add in various UI views in v, according to information in loaded
// data structure.
View v = inflater.inflate(R.layout.home_menu, container, false);
// ...
// Adding several LinearLayout and TextView into v, based on
// information from loaded data structure (arg1)
// ...
return v;
}
....
}
This is really not a good design. As sometimes, performTimeConsumingDataStructureLoading might take more than 5 seconds, and I will get ANR (Application Not Responding)
By referring http://developer.android.com/reference/android/content/AsyncTaskLoader.html, I end up with better solution. The example I encounter is, it updates its UI indirectly through an ArrayAdapter.
public class HomeMenuFragment extends SherlockFragment implements LoaderManager.LoaderCallbacks<HomeMenuFragment.Infos> {
#Override
public void onLoadFinished(Loader<Infos> arg0, Infos arg1) {
LayoutInflater inflater = this.getLayoutInflater(null);
ViewGroup container = (ViewGroup)this.getView().getParent();
// Remove previous old views, as onLoadFinished might be triggered
// by onContentChanged too.
container.removeAllViews();
View v = inflater.inflate(R.layout.home_menu, container, false);
// ...
// Adding several LinearLayout and TextView into v, based on
// information from loaded data structure (arg1)
// ...
container.addView(v);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
....
}
I do not have an ArrayAdapter as I'm not using ListFragment. What I want to do is adding few TextView into few LinearLayout. Then, I will add LinearLayout to the Fragment's container.
However, the following code gives me null pointer exception.
ViewGroup container = (ViewGroup)this.getView().getParent();
What I know what is the correct way to update Fragment UI dynamically, after onLoadFinished from AsyncTaskLoader?
However, most example I encounter is, they update their UI indirectly
through an ArrayAdapter.
Using a Loader doesn't require that you must use a ListView, you can update whatever view you target in your application.
What I know what is the correct way to update Fragment UI dynamically,
after onLoadFinished from AsyncTaskLoader?
Get a reference to the container from the Fragment's view where you'll place the extra views and add the new views.
#Override
public void onLoadFinished(Loader<Infos> arg0, Infos arg1) {
// for some reason the fragment's view isn't built yet so abort things
if (getView() == null) {
ViewGroup container = (ViewGroup) getView().findViewById(R.id.containerId);
ViewGroup container = getViewcontainer.removeAllViews();
// ...
// Adding several LinearLayout and TextView into v, based on
// information from loaded data structure (arg1)
// ...
container.addView(v);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_menu, container, false);;
}
For a while I was also trying to achieve the same. Based on the above answer, what worked for me was this:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
ViewGroup container = (ViewGroup) getView().findViewById(R.id.fragment_oam);
if (container != null) {
if (adapter.getCount() == 0) {
Log.v(TAG, "Count is: " + adapter.getCount());
container.setBackgroundColor(Color.BLUE);
} else {
Log.v(TAG, "Count is: " + adapter.getCount());
container.setBackgroundColor(Color.WHITE);
}
} else {
Log.v(TAG, "Container is null");
}
}
And my Layout xml is as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/background"
android:background="#FFF">
<fragment
android:name="com.myapp.OAMCursorLoader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_oam">
</fragment>
Now when ContentResolver updates the cursor and onLoadFinished checks if the cursor is empty or has some content in it, based on this background of the visible screen, i.e. ListFragment is changed.
You can play around with background settings, use a drawable image instead of colors, it is up to you.

Categories

Resources