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
}
}
Related
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();
}
I'm new in this world of Android and I'm learning making an app, so I got a problem.
Working on
I created a fragment and inside I have a radio group containing 3 radio buttons
Goal
Clear all the radio buttons inside the fragment when the user returns to this screen
Problem
I don't know how to achieve that
Question
How to clear all checks of the radio buttons?
Steps done
I tried the following:
Uncheck all RadioButton in a RadioButtonGroup
But it seems I can't do it
Code
This piece of code doesn't work for me (from the post above)
protected void onResume()
{
RadioGroup rg=(RadioGroup)findViewById(R.id.RG);
rg.clearCheck();
super.onResume();
}
But I have the following:
public class Operations extends Fragment
{
RadioButton surfArea, rad, diam;
RadioGroup radG;
Button openSelect;
public Operations()
{
// Required empty public constructor
}
public static Operations newInstance()
{
return new Operations();
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_operations_sphere, container, false);
surfArea = (RadioButton) rootView.findViewById(R.id.RB_surfArea);
rad = (RadioButton) rootView.findViewById(R.id.RB_Rad);
diam = (RadioButton) rootView.findViewById(R.id.RB_Diam);
openSelect = (Button) rootView.findViewById(R.id.btn_open_select);
//This piece is for testing purposes
openSelect.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (surfArea.isChecked())
{
Intent sa = new Intent(getContext(), OperSphere.class);
startActivity(sa);
}
}
});
return rootView;
}
//Here is where I'm stuck
#Override
public void onResume()
{
super.onResume();
}
}
I'm interested in place the code inside onResume()
I know there is docs about fragments (https://developer.android.com/guide/components/fragments.html) but those can't answer my questions
Thanks in advance
1) Initialize your RadioGroup in onCreateView method as
private RadioGroup rg;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_operations_sphere, container, false);
// initialize your radiogroup here
rg = (RadioGroup) rootView.findViewById(R.id.RG);
.....
// Rest of your code
}
2) Now call the following method i.e.,clearSelection() wherever you want to UNCHECK the RadioButtons (but after above code).
private void clearSelection(){
if(rg != null) rg.clearCheck();
}
3) Example: If you want to uncheck the RadioButtons in onResume(), you can call it from there as
#Override
public void onResume(){
super.onResume();
clearSelection();
}
If you want to do it from some other method, it would work even then as
private void myMethod(){
// need to clear radio buttons
clearSelection();
// rest of my code
}
have you tried placing your call super.onResume() before what you want to achieve...
Call clearCheck() method of radioGroup in your onResume callback, something like:
#Override
protected void onResume() {
super.onResume();
rg.clearCheck();
}
For Anybody Who is facing the same problem While navigating between fragments can do this to make it work.
radioButton.setSaveEnabled(false);
Make sure you do that for all the radio buttons in the group and not the radioGroup itself
NOTE: This flag can only disable the saving of this view; any child views may still have their state saved.
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.
I have a Login screen which consists of 2 EditTexts for Username and Password. My requirement is that on orientation change , input data(if any) in EditText should remain as it is and a new layout should also be drawn. I have 2 layout xml files- one in layout folder and other in layout-land folder. I am trying to implement following 2 approaches but none of them is perfect:
(1) configChanges:keyboardHidden - In this approach, I don't provide "orientation" in configChanges in manifest file. So I call setContentView() method in both onCreate() and onConfigurationChanged() methods. It fulfills both my requirements. Layout is changed and input data in EditTexts also remains as it is. But it has a big problem :
When user clicks on Login button, a ProgressDialog shows until server-response is received. Now if user rotates the device while ProgressDialog is running, app crashes. It shows an Exception saying "View cannot be attached to Window." I have tried to handle it using onSaveInstanceState (which DOES get called on orientation change) but app still crashes.
(2) configChanges:orientation|keyboardHidden - In this approach, I provide "orientation" in manifest. So now I have 2 scenarios:
(a) If I call setContentView() method in both onCreate() and onConfigurationChanged(), Layout is changed accordingly but EditText data is lost.
(b) If I call setContentView() method in onCreate() , but not in onConfigurationChanged(), then EditText data is not lost but layout also not changes accordingly.
And in this approach, onSaveInstanceState() is not even called.
So I am in a really intimidating situation. Is there any solution to this problem? Please help. Thanx in advance.
By default, Edittext save their own instance when changing orientation.
Be sure that the 2 Edittexts have unique IDs and have the same IDs in both Layouts.
That way, their state should be saved and you can let Android handle the orientation change.
If you are using a fragment, be sure it has a unique ID also and you dont recreate it when recreating the Activity.
A better approach is to let android handle the orientation change. Android will automatically fetch the layout from the correct folder and display it on the screen. All you need to do is to save the input values of the edit texts in the onSaveInsanceState() method and use these saved values to initialize the edit texts in the onCreate() method.
Here is how you can achieve this:
#Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.login_screen);
...
...
String userName, password;
if(savedInstanceState!=null)
{
userName = savedInstanceState.getString("user_name");
password= savedInstanceState.getString("password");
}
if(userName != null)
userNameEdtTxt.setText(userName);
if(password != null)
passEdtTxt.setText(password);
}
>
#Override
protected void onSaveInstanceState (Bundle outState)
{
outState.putString("user_name", userNameEdtTxt.getText().toString());
outState.putString("password", passEdtTxt.getText().toString());
}
Give the element an id and Android will manage it for you.
android:id="#id/anything"
in onConfigurationChanged method, first get the data of both the edit texts in global variables and then call setContentView method. Now set the saved data again into the edit texts.
There are many ways to do this. The simplest is 2(b) in your question. Mention android:configChanges="orientation|keyboardHidden|screenSize" in your manifest so that Activity doesn't get destroyed on Orientation changes.
Call setContentView() in onConfigChange(). but before calling setContentView() get the EditText data into a string and set it back after calling setContentView()
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mEditTextData = mEditText.getText().tostring();//mEditTextData is a String
//member variable
setContentView(R.layout.myLayout);
initializeViews();
}
private void initializeViews(){
mEditText = (EditText)findViewById(R.id.edittext1);
mEdiText.setText(mEditTextData);
}
The following should work and is standard to the activities and fragments
#Override
public void onSaveInstanceState (Bundle outState)
{
outState.putString("editTextData1", editText1.getText().toString());
outState.putString("editTextData2", editText2.getText().toString());
super.onSaveInstanceState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate();
... find references to editText1, editText2
if (savedInstanceState != null)
{
editText1.setText(savedInstanceState.getString("editTextData1");
editText2.setText(savedInstanceState.getString("editTextData2");
}
}
Im restoring instance to restore values and it works fine for me :)
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.addtask2);
if(savedInstanceState!=null)
onRestoreInstanceState(savedInstanceState);
}
Remove android:configChanges attribute from the menifest file and let android handle the orientation change your data in edittext will automatically remain.
Now The problem you mentioned is with the progress dialog force close this is because when the orientation is changed the thread running in backgroud is trying to update the older dialog component whihc was visible. You can handle it by closing the dialog on savedinstancestate method and recalling the proceess you want to perform onRestoreInstanceState method.
Below is a sample hope it helps solving your problem:-
public class MyActivity extends Activity {
private static final String TAG = "com.example.handledataorientationchange.MainActivity";
private static ProgressDialog progressDialog;
private static Thread thread;
private static boolean isTaskRunnig;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new EditText.OnClickListener() {
#Override
public void onClick(View v) {
perform();
isTaskRunnig = true;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void perform() {
Log.d(TAG, "perform");
progressDialog = android.app.ProgressDialog.show(this, null,
"Working, please wait...");
progressDialog
.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
//isTaskRunnig = false;
}
});
thread = new Thread() {
public void run() {
Log.d(TAG, "run");
int result = 0;
try {
// Thread.sleep(5000);
for (int i = 0; i < 20000000; i++) {
}
result = 1;
isTaskRunnig = false;
} catch (Exception e) {
e.printStackTrace();
result = 0;
}
Message msg = new Message();
msg.what = result;
handler.sendMessage(msg);
};
};
thread.start();
}
// handler to update the progress dialgo while the background task is in
// progress
private static Handler handler = new Handler() {
public void handleMessage(Message msg) {
Log.d(TAG, "handleMessage");
int result = msg.what;
if (result == 1) {// if the task is completed successfully
Log.d(TAG, "Task complete");
try {
progressDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
isTaskRunnig = true;
}
}
}
};
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.d(TAG, "onRestoreInstanceState" + isTaskRunnig);
if (isTaskRunnig) {
perform();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "onSaveInstanceState");
if (thread.isAlive()) {
thread.interrupt();
Log.d(TAG, thread.isAlive() + "");
progressDialog.dismiss();
}
}
As pointed out by Yalla T it is important to not recreate the fragment. The EditText will not lose its content if the existing fragment is reused.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_frame);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Display the fragment as the main content.
// Do not do this. It will recreate the fragment on orientation change!
// getSupportFragmentManager().beginTransaction().replace(android.R.id.content, new Fragment_Places()).commit();
// Instead do this
String fragTag = "fragUniqueName";
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = (Fragment) fm.findFragmentByTag(fragTag);
if (fragment == null)
fragment = new Fragment_XXX(); // Here your fragment
FragmentTransaction ft = fm.beginTransaction();
// ft.setCustomAnimations(R.xml.anim_slide_in_from_right, R.xml.anim_slide_out_left,
// R.xml.anim_slide_in_from_left, R.xml.anim_slide_out_right);
ft.replace(android.R.id.content, fragment, fragTag);
// ft.addToBackStack(null); // Depends on what you want to do with your back button
ft.commit();
}
Saving state = Saving (Fragment State + Activity State)
When it comes to saving the state of a Fragment during orientation change, I usually do this way.
1) Fragment State:
Save and Restore EditText value
// Saving State
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("USER_NAME", username.getText().toString());
outState.putString("PASSWORD", password.getText().toString());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.user_name_fragment, parent, false);
username = (EditText) view.findViewById(R.id.username);
password = (EditText) view.findViewById(R.id.password);
// Retriving value
if (savedInstanceState != null) {
username.setText(savedInstanceState.getString("USER_NAME"));
password.setText(savedInstanceState.getString("PASSWORD"));
}
return view;
}
2) Activity State::
Create a new Instance when the activity launches for the first time
else find the old fragment using a TAG and the FragmentManager
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
fragmentManager = getSupportFragmentManager();
if(savedInstanceState==null) {
userFragment = UserNameFragment.newInstance();
fragmentManager.beginTransaction().add(R.id.profile, userFragment, "TAG").commit();
}
else {
userFragment = fragmentManager.findFragmentByTag("TAG");
}
}
You can see the the full working code HERE
Below code is work for me. Need to care two things.
Each Input Field (Edit Text or TextInputEditText) assign unique id.
Manifest activity declaration should have on configuration change attribute with below values.
android:configChanges="orientation|keyboardHidden|screenSize"
Sample activity declaration in manifest.
<activity
android:name=".screens.register.RegisterActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true"
android:label="Registration"
android:theme="#style/AppTheme.NoActionBar" />
Sample declaration of
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/inputLayout"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxCornerRadiusBottomEnd="#dimen/boxCornerRadiusDP"
app:boxCornerRadiusBottomStart="#dimen/boxCornerRadiusDP"
app:boxCornerRadiusTopEnd="#dimen/boxCornerRadiusDP"
app:boxCornerRadiusTopStart="#dimen/boxCornerRadiusDP">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/inputEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:fontFamily="#font/proxima_nova_semi_bold"
android:inputType="textCapWords"
android:lines="1"
android:textColor="#color/colorInputText"
android:textColorHint="#color/colorInputText" />
</com.google.android.material.textfield.TextInputLayout>
this may help you
if your android:targetSdkVersion="12" or less
android:configChanges="orientation|keyboardHidden">
if your android:targetSdkVersion="13" or more
android:configChanges="orientation|keyboardHidden|screenSize">
I've some database that i update with a service, and i want to update my listView on resume, or refresh it from time to time with the new data in it, but it's not working.
Here is my code (the code in comment is not working and sometimes make the app crash)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
taskLiteApplication = ((TaskLiteApplication)getApplicationContext());
listGroupTask = taskLiteApplication.getCtrlGroupTask().getListGroupTaskToDoAndToReview(taskLiteApplication.getUser());
Log.d(TAG, "nbtask to do an to review from DB :"+listGroupTask.size());
if(listGroupTask.size() > 0) {
setContentView(R.layout.to_do_layout);
ListView lv = (ListView) findViewById(R.id.ListViewGroupTaskToDoToDo);
//set adapter
groupTaskToDoBaseAdapter = new GroupTaskToDoBaseAdapter(this, listGroupTask);
lv.setAdapter(groupTaskToDoBaseAdapter);
} else {
TextView textView = new TextView(this);
textView.setText("No tasks to do found!");
setContentView(textView);
}
}
public void onResume() {
super.onResume();
//listGroupTask = taskLiteApplication.getCtrlGroupTask().getListGroupTaskToDoAndToReview(taskLiteApplication.getUser());
//groupTaskToDoBaseAdapter.notifyDataSetChanged();
Log.d(TAG, "on resume");
}
What exactly are your trying here:
listGroupTask = taskLiteApplication.getCtrlGroupTask().getListGroupTaskToDoAndToReview(taskLiteApplication.getUser());
Do you want a completely new set of data for your ListView. If so then implement some methods in your Adapter like add/remove/delete/replaceData and so on and after that call the
groupTaskToDoBaseAdapter.notifyDataSetChanged();