Can not display data in fragment even if savedInstanceState is not null - android

I would like to save and restore data in an fragment after that screen orentation has changed.
For that, I use "onSaveInstanceState" method to save my data.
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("date", dateTextView.getText().toString());
outState.putString("time", timeTextView.getText().toString());
outState.putString("hour", hour);
outState.putString("minute", minute);
outState.putString("topicGroup", currentTopicGroup);
outState.putString("topic", currentTopicTitle);
outState.putString("level",currentLevelName);
outState.putDouble("totalPrice", totalPrice);
outState.putString("activityTitle", getActivity().getTitle().toString());
super.onSaveInstanceState(outState);
}
But when I try to restore/display my data with the "onCreateView" method like below, nothing happens even if the "savedInstanceState" variable is not null (my logs display the right value).
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_create_new_lesson, container, false);
timeTextView = (TextView) view.findViewById(R.id.time_picker_text_view);
dateTextView = (TextView) view.findViewById(R.id.date_picker_text_view);
hourSpinner = (Spinner) view.findViewById(R.id.hour_spinner);
minuteSpinner = (Spinner) view.findViewById(R.id.minut_spinner);
topicGroupSpinner = (Spinner) view.findViewById(R.id.topic_group_spinner);
topicSpinner = (Spinner) view.findViewById(R.id.topic_spinner);
levelSpinner = (Spinner) view.findViewById(R.id.level_spinner);
totalPriceTextView = (TextView) view.findViewById(R.id.total_price_text_view);
datePickerButton = (Button) view.findViewById(R.id.date_picker_button);
timePickerButton = (Button) view.findViewById(R.id.time_picker_button);
createNewLessonButton = (Button) view.findViewById(R.id.create_new_lesson_button);
if (savedInstanceState != null) {
String time = savedInstanceState.getString("time");
Log.i("TIME", time);
getActivity().setTitle(time);
dateTextView.setText(savedInstanceState.getString("date"));
timeTextView.setText(savedInstanceState.getString("time"));
int hourPosition = getIndexByString(hourSpinner, savedInstanceState.getString("hour"));
int minutePosition = getIndexByString(minuteSpinner, savedInstanceState.getString("minute"));
int topicGroupPosition = getIndexByString(topicGroupSpinner, savedInstanceState.getString("topicGroup"));
hourSpinner.setSelection(hourPosition);
minuteSpinner.setSelection(minutePosition);
topicGroupSpinner.setSelection(topicGroupPosition);
}
return view;
}
I try many things without success. Would anyone have any advice to give me ? Thanks in advance.

The problem is in the place where you are trying to restore the state of your views.
Take a look:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
...
if (savedInstanceState != null) {
//Restore the fragment's state here
}
}
...
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's state here
}
The topic has already been commented on StackOverflow in depth.
Just take a look and you will find a lot about the savedState and restoring it. Fragment's SavedState and Restoring It

The problem is every time a new Fragment instance with empty bundle data is created and added. While adding a new Fragment in the activity do as below
In onCreate() of activity or wherever you add the fragment do as below
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.frag_container, new Frag1()).commit();
}

Related

Android Fragment filling radiogroup

For a reason no elements get changed and some do not.
A Fragment called QuestionFragment is in an Action called QuizAction.
The fragment gets replaced in the OnCreate of the Action.
In the fragment I try to add radiobuttons and change text but all fail.
All text that involves "it works" do work and do change the fragment elements.
All text tot involve "it does not work" do not change anything.
What am I doing wrong?
personally: I guess it has to do with the first fragment declared in the xml file of the activity that is actually edited but the second one does not. The one that I should see but never actually do. I also do not know how to check this.
Anyhow this is my code.
In OnCreate of the activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
if (manager == null) manager = getSupportFragmentManager();
Bundle args = new Bundle();
args.putStringArray("Possible Ansers", PossibleAnsers);
args.putSerializable("protocol", p);
fragment = new QuestionFragment();
fragment.setArguments(args);
ft= manager.beginTransaction();
ft.replace(R.id.fragment,fragment).commit();
}
In the onViewCreated of the QuestionFragment:
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
Bundle bundle = getArguments();
String[] antw = new String[0];
rg = (RadioGroup) getView().findViewById(R.id.radioGroup);
tv = (TextView) getView().findViewById(R.id.smallTekst);
tv.setText("works");
if(bundle != null) {
if( bundle.getStringArray("PossibleAnsers") != null) {
antw = bundle.getStringArray("PossibleAnsers");
}
}
for(int i = 0; i < antw.length; i++) {
addRadioButton(c, rg, "radiobutton "+i +"that doesn't work");
Toast.makeText(c, "rdm toast that works", Toast.LENGTH_LONG).show();
tv.setText("Doesn't work");
}
addRadioButton(c, rg, "working radioButton");
super.onViewCreated(view, savedInstanceState);
}
Already a big thanks.

ArrayList strange behaviour after update its values

I have a tabhost with several tabs and each tab contain a certain number of operations which are listed in a listview. To populate that listview I use an ArrayList.
First time tabs are created evertything works fine. The issue comes when I try to filter the list by year. The process of filtering works fine as I can see the filtered list in debug and it's fine.
The issue is that after filtering, i recreate the tabs in order to fill all listviews again. To open tabs I use this code. It creates as many tabs as different currencies there are in the list:
public static void openFragments(FragmentTabHost tabHost, ArrayList<Posicion> positions, Class FragmentResumen, Class FragmentDetails ) {
//==========================================================================================
// This method open as many tabs as different currencies there are in positions list
//==========================================================================================
ArrayList<String> currencies = Currency.getDifferentCurrencies(positions);
tabHost.clearAllTabs();
for (int i = 0; i < currencies.size() + 1; i++) {
String tabName = "", tabSpec = "";
Class fragmentToOpen;
Bundle arg1 = new Bundle();
//A general tab is first created
if (i == 0)
{
tabName = "All";
tabSpec = "General";
arg1.putString("moneda", tabName);
arg1.putSerializable("posiciones", positions);
fragmentToOpen = FragmentResumen;
}
//The rest of tabs for currencies are created
else
{
tabName = currencies.get(i - 1);
tabSpec = "Tab" + (i - 1);
arg1.putString("moneda", tabName);
arg1.putSerializable("posiciones", positions);
fragmentToOpen = FragmentDetails;
}
tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(tabName), fragmentToOpen, arg1);
}
}
As I told before, this works fine always.
First time I need to create tabs I call it by using:
openFragments(tabHost, positions, FragmentResumenMedio.class, FragmentDetailsMedio.class);
Then I have a button that shows a DatePicker and when user selects a year I close the dialog and redraw tabs as follows:
ArrayList<Posicion> positionsFiltered = General.makeHardCopyOfArrayListPosition(positions);
for(Posicion posicion : positionsFiltered)
{
Boolean matchFilters = filterPositionsByYear(posicion, year + "");
if(matchFilters == false){
positions.remove(posicion);
}
}
General.openFragments(tabHost, positions, FragmentResumenMedio.class, FragmentDetailsMedio.class);
When I debug this last function I can see that positions have the correct value after filtering but when I click the new tab, it shows the list without filtering and I don't know how could I solve this issue.
Thanks a lot.
EDIT
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Initialize view and tabhost
View rootView = inflater.inflate(R.layout.fragment_medio, container, false);
tabHost = (FragmentTabHost) rootView.findViewById(android.R.id.tabhost);
tabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
return tabHost;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//onCreatedView is only called the first time so we must ensure that tabhost is not null before adding tabs
if(tabHost == null) {
tabHost = (FragmentTabHost) getView().findViewById(android.R.id.tabhost);
tabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
}
FloatingActionButton floatingActionButton = (FloatingActionButton) getView().findViewById(R.id.floatingButton);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
positions = new ArrayList<>(positionsFiltered);
createDialogWithoutDateField().show();
}
});
//Check if any update has been made since the last open
SharedPreferences prefs = getActivity().getPreferences(MODE_PRIVATE);
Boolean updateMedioRequired = prefs.getBoolean(updateOperationsMedioPlazo, true);
if (updateMedioRequired != null)
{
if (updateMedioRequired == true)
{
//Update variable that indicates if changes have been made or not
SharedPreferences.Editor editor = getActivity().getPreferences(MODE_PRIVATE).edit();
editor.putBoolean(updateOperationsMedioPlazo, false);
editor.apply();
//Check if there are previously stored operations
if (operations.size() > 0)
{
//Show a progressDialog as prices have to be downloaded from internet and this can be a time consumming task
progress = ProgressDialog.show(getActivity(), "Obteniendo precios",
"Un momento por favor...", true);
//Generate positions from operations list and wait for result in "onStockPriceResult". If there are no changes, positions variable has already values
if(positions.size() == 0) {
new Thread(new Runnable() {
#Override
public void run() {
positions = MedioPlazoCalculations.generatePositions(listener, getActivity(), operations);
}
}).start();
}
}
else
{
Toast.makeText(getActivity(), "Aún no se ha introducido ninguna operación", Toast.LENGTH_LONG).show();
}
}
else
{
//If no update needed, variable coming from MainActivity has positionList. Open as many new fragments as currencies there are in positionsList
General.openFragments(tabHost, positions, FragmentResumenMedio.class, FragmentDetailsMedio.class);
}
}
}
EDIT 2:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
{
if(getActivity()!=null)
{
Bundle bundle = this.getArguments();
positions = (ArrayList<Posicion>) bundle.getSerializable("posiciones");
moneda = (String) bundle.getString("moneda");
}
}
}
Edit 3: If I place the commented instruction, filtering does not work. If I remove it, filtering works but I cant filter again because the value of the list has the filtered version not the original one
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
positions = new ArrayList<>(positionsFiltered);
createDialogWithoutDateField().show();
}
});

Using bundle for message passing in sliding tab fragments returns null

I am new at using fragments. This is how I am passing StringArrayList inside bundle in the onActivityCreated of first fragment in sliding tab
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
next_personal = (Button) getActivity().findViewById(R.id.personal_next);
next_personal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
validate();
}
});
}
private void validate() {
isValid = FormValidator.validate(this, new SimpleErrorPopupCallback(getActivity().getApplicationContext(), true));
if (isValid) {
arrayList = new ArrayList<String>();
arrayList.add(memID.getText().toString());
arrayList.add(idNumber.getText().toString());
arrayList.add(firstName.getText().toString());
arrayList.add(secondName.getText().toString());
arrayList.add(lastName.getText().toString());
arrayList.add(secondLastName.getText().toString());
Bundle bundle = new Bundle();
bundle.putStringArrayList("personal",arrayList);
Log.d("bundle",": "+bundle.toString());
FragContactInfo frag = new FragContactInfo();
frag.setArguments(bundle);
((RegisterTabActivity) getActivity()).setCurrentItem(1, true);
}
}
And then I am trying to get the ArrayList in the third fragment of sliding tab as below:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null && bundle.containsKey("personal")) {
ArrayList<String> userId = bundle.getStringArrayList("personal");
}
else{
Toast.makeText(getActivity(),"Bundle is null",Toast.LENGTH_SHORT).show();
}
}
It keeps on returning null. Did the same inside onCreateView of both fragments, same result. What am I getting wrong here?
Using bundle did not help in parsing data between fragments (Somehow)
So I simply created method to set and get data in target fragment.
public void setPdata(JSONObject obj) {
this.personalJSON = obj;
}
public JSONObject getPdata() {
return personalJSON;
}
Then I called the set method to set json in sender fragment.
FragContactInfo frag = new FragContactInfo();
frag.setPdata(json);
And then access the json by simply calling get method.
array1 = getPdata().getJSONArray("args");
If anyone has a more productive solution, please do tell. Happy Coding.

Fragment doesnt remeber EditText's content on orientation change

I'm having some trouble with my EditText's on orientation change. For some reason they dont restore whatever was typed in them.
I have 2 classes. The main activity and the fragment which goes in the activity
Main activity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(
setContentView(R.layout.
getFragmentManager().beginTransaction().replace(R.id.controlsBar, new AddItemFragment()).commit();
}
}
And the fragment:
public class AddItemFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_add_item, container, false);
EditText item = (EditText) view.findViewById(R.id.itemNameAdd);
EditText amount = (EditText) view.findViewById(R.id.itemAmount);
if (savedInstanceState != null) {
System.out.println(savedInstanceState.getString("item"));
item.setText(savedInstanceState.getString("item", ""));
amount.setText(savedInstanceState.getString("amount", ""));
}
//item.setText("SOME TEXT");
//amount.setText("SOME TEXT");
return view;
}
#Override
public void onSaveInstanceState(Bundle outState) {
EditText item = (EditText) getActivity().findViewById(R.id.itemNameAdd);
EditText amount = (EditText) getActivity().findViewById(R.id.itemAmount);
outState.putString("item", item.getText().toString());
outState.putString("amount", amount.getText().toString());
}
}
The funny thing is that the line "System.out.println(savedInstanceState.getString("item"));" prints out the correct word in the console.
And furthermore the outcommented lines where i set the text to "SOME TEXT" also works.
Its only when i set the text to savedInstanceState.getString("amount", ""), it wont work
Thank you
Try adding the line marked "<---- THIS LINE" to public void onSaveInstanceState(Bundle outState):
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); // <---- THIS LINE
EditText item = (EditText) getActivity().findViewById(R.id.itemNameAdd);
EditText amount = (EditText) getActivity().findViewById(R.id.itemAmount);
outState.putString("item", item.getText().toString());
outState.putString("amount", amount.getText().toString());
}
Also, look at using onActivityCreated, and check out the resources in my comment below.

Android ListView Change should occur on restoreInstanceState

Hey I would like a change to occur in the ListView like a textchange on the TextView in the listview. But this should not happen when on ItemClick It should happen when on restoreInstance state any help will be appreciated here is my code
#Override
public void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
View v1 = inventoryList.getChildAt(2);
if(v1 != null){
TextView tx = (TextView) v1.findViewById(R.id.txt_location);
tx.setText("why does this not work");
}
}
You need to call the adapter's notifyDataSetChanged() method after you have made changes to the ListView
#Override
public void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
View v1 = inventoryList.getChildAt(2);
if(v1 != null){
TextView tx = (TextView) v1.findViewById(R.id.txt_location);
tx.setText("why does this not work");
// You're missing this
inventoryList.getAdapter().notifyDataSetChanged();
// Or simply call
// adapter.notifyDataSetChanged(); // if you maintain a reference to the adapter
}
}

Categories

Resources