I've been for the most part following the highest highest voted answer
Here and a little from some other answers on SO. I'm trying to handle a configuration change or anything that would call onSaveInstanceState() / onRestoreInstanceState().
So far I'm able to get TextViews restored (properly?), but I'm having issues with dynamically added ui elements like ImageButtons, in my example the buttons are not being restored. It's probably something stupid, but I've avoided asking for help long enough. I had seen somewhere mention of saving Objects to bundle.... but this seemed more straight forward.
Grateful for any suggestions.
oh also I've only been testing on emulator, rotating between landscape/portrait
EDIT: updated with a working example and suggestion from #18446744073709551615. Thanks everyone for the help, looks like saving entire objects might be a better approach for more complex code.
basic xml layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="set"
android:text="Button" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="add"
android:text="Button" />
</LinearLayout>
This is just a slightly modified blank activity:
package com.example.savestate;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
int btnId = 0;
int myBtns;
LinearLayout panel;
TextView textView;
String myString;
ImageButton[] btnArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "begin of creation, myString is " + myString);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView1);
Log.d(TAG, "end of creation, myString is: " + myString);
}
#Override
protected void onResume() {
super.onResume();
textView.setText(myString);
restoreBtns();
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("MyString", "Welcome back");
savedInstanceState.putInt("MyBtns", btnId);
Log.d(TAG, "on save, myString is: " + myString);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
myString = savedInstanceState.getString("MyString");
myBtns = savedInstanceState.getInt("MyBtns");
Log.d(TAG, "on restore, myBtns is: " + myBtns);
Log.d(TAG, "on restore, myString is: " + myString);
}
public void restoreBtns() {
if(myBtns > 0) {
panel = (LinearLayout) findViewById(R.id.LinearLayout1);
btnArray = new ImageButton[myBtns];
for (int i = 0; i < myBtns; i++){
btnId++;
btnArray[i] = new ImageButton(this);
btnArray[i].setImageResource(R.drawable.ic_launcher);
btnArray[i].setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
btnArray[i].setId(btnId);
panel.addView(btnArray[i]);
}
}
}
public void add(View view) {
btnId++;
panel = (LinearLayout) findViewById(R.id.LinearLayout1);
ImageButton imgBtn = new ImageButton(this);
imgBtn.setImageResource(R.drawable.ic_launcher);
imgBtn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
imgBtn.setId(btnId);
panel.addView(imgBtn);
}
public void set(View view) {
textView.setText("Goodbye");
Log.d(TAG, "on set(), myString is " + myString);
}
}
When onCreate() executes, myBtns is 0. Due to the if statement, restoreBtns() is a no-op. Then, onStart() is called, and after that, onRestoreInstanceState() is called: This method is called after onStart(). So myBtns is initialized only after it is used.
Suggestion: move the button stuff to onResume().
Try this way
<activity
android:name="com.yourpackage.YourActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
Related
I have a weather app that requires you to take the text from a edit text field and display it in a text view, I'm trying to make it so when I enter a place it will generate random weather for them along with displaying their input.
I haven't tried much apart from examples online as I recently started learning android development.
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.w3c.dom.Text;
/**
* Implementation for the main activity
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// member variable for the user provided location
private String location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get the Get Forecast button
Button btnGetForecast = (Button) findViewById(R.id.btnGetForecast);
// set the click listener to the btnGetForecast Button
btnGetForecast.setOnClickListener(this);
EditText loc = findViewById(R.id.etLocationInput);
location = loc.getText().toString();
}
#Override
public void onClick(View view) {
// view is the View (Button, ExitText, TextView, etc) that was clicked
// if it was the btnGetForecast
if (view.getId() == R.id.btnGetForecast){
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="#+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/tvTitle" />
<TextView
android:id="#+id/tvInstructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter a location below for the forecast" />
<EditText
android:id="#+id/etLocationInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName" />
<Button
android:id="#+id/btnGetForecast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Get Forecast" />
<TextView
android:id="#+id/tvLocationDisplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="The weather in " />
</LinearLayout>
I expect the app to show input from user and display it in text view
This line in your onCreate: 'location = loc.getText().toString()' will only get the current text in loc, which at onCreate will be an empty string.
You should look into TextWatcher: https://developer.android.com/reference/android/text/TextWatcher. This will allow you to get a callback when the text of loc changes and you can then carry out your weather generation.
Well, all you need to do is to add this code in onClick method:
#Override
public void onClick(View view) {
// view is the View (Button, ExitText, TextView, etc) that was clicked
// if it was the btnGetForecast
if (view.getId() == R.id.btnGetForecast){
String text = loc.getText().toString();
yourTextView.setText(text);
}
}
And don't forget to make view variables global, so you could access them outside onCreate method, without using findViewById() again.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView yourTextView;
private EditText loc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get the Get Forecast button
Button btnGetForecast = (Button) findViewById(R.id.btnGetForecast);
// set the click listener to the btnGetForecast Button
btnGetForecast.setOnClickListener(this);
loc = findViewById(R.id.etLocationInput);
yourTextView = findViewById(R.id.tvLocationDisplay);
}
...
}
This is the code I am using
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
showVoiceText.setText("I am working");
}
However it seems not to be called... It never displays "I am working"
This is my xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.phoenix.coreai.HomeActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Core A.I."
android:id="#+id/showVoiceOutput"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enable voice control"
tools:layout_editor_absoluteX="88dp"
tools:layout_editor_absoluteY="167dp" />
</android.support.constraint.ConstraintLayout>
This is not my main activity, my main activity is just an intro playing a small mp4 file
This is the main activity code
package com.example.phoenix.coreai;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.VideoView;
public class MainActivity extends AppCompatActivity {
VideoView view;
private static int SPLASH_TIME_OUT = 2700;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = (VideoView) findViewById(R.id.videoView);
videoPlay(view);
new Handler().postDelayed(new Runnable(){
#Override
public void run(){
Intent homeIntent = new Intent(MainActivity.this, HomeActivity.class);
startActivity(homeIntent);
finish();
}
},SPLASH_TIME_OUT);
}
public void videoPlay(View v){
String videoPath = "android.resource://com.example.phoenix.coreai/" + R.raw.spashscreen;
Uri uri = Uri.parse(videoPath);
view.setVideoURI(uri);
view.start();
}
}
and this is the xml of the main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
tools:context="com.example.phoenix.coreai.MainActivity">
<VideoView
android:id="#+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginTop="-27dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp">
</VideoView>
</LinearLayout>
I cannot debug the application through my mobile it has a custom rom and android studio wont recognize it
Let's assume that I would like to call this void from onCreate
private void musicScan(){
File f = new File(path);
File file[] = f.listFiles();
fileArray = new String[file.length];
for (int i = 0; i < file.length; ++i){
fileArray[i] = file[i].getName();
}
}
It does not seem to execute the void that I am calling
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
TextView showVoiceText = (TextView) findViewById(R.id.showVoiceOutput);
showVoiceText.setText("I am working");
}
[maybe you need to remove the first "TextView" if it is already declared in another place, but since we don't have the whole code...]
But still will be good to know how your main activity start/call this activity
I think the problem is that you declared a global TextView and called it showVoiceText but you never initialise it
the solution is to initialise it after the setContentView like the following:
showVoiceText=(TextView) findViewById(R.id.showVoiceOutput);
java & Two.java)
into each fragments there's editext:
One : editText_One
Two : editText_Two
How to save and resotre editText_One (and editText_Two), when i switch between fragments?
I've tried several things after reading tutos, but nothing working well ;(
One.xml
<?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:orientation="vertical" >
<TextView
android:id="#+id/tv_one"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="one" />
<EditText
android:layout_width="237dp"
android:layout_height="wrap_content"
android:inputType="date"
android:ems="10"
android:id="#+id/editText_One"
android:text="blabla"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Two.xml :
<?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:orientation="vertical" >
<TextView
android:id="#+id/tv_one"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="TWO" />
<EditText
android:layout_width="237dp"
android:layout_height="wrap_content"
android:inputT`enter code here`ype="date"
android:ems="10"
android:id="#+id/editText_Two"
android:layout_gravity="center_horizontal" />
One.java :
/**
*
*/
package com.example.navigationsubmenu;
/**
* #author info-medios
*
*/
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import java.util.Calendar;
public class One extends Fragment {
// public static final String EXTRA_URL_nommatiere = "url";
EditText editText_one;
// String valeur;
private final String PERSISTENT_VARIABLE_BUNDLE_KEY = "persistentVariable";
public One() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Bundle bundle = new Bundle();
/* Bundle bundle = getActivity().getIntent().getExtras();
Bundle mySavedInstanceState = getArguments();
if (bundle!= null) {// to avoid the NullPointerException
// editText_one.setText("premiere");
String persistentVariable = mySavedInstanceState.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
editText_one.setText(persistentVariable);
}*/
Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
String persistentVariable = extras.getString(PERSISTENT_VARIABLE_BUNDLE_KEY);
editText_one.setText(persistentVariable);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.one, container, false);
//Instancier vos composants graphique ici (faƮtes vos findViewById)
editText_one = (EditText) view.findViewById(R.id.editText_One); //getview marche aussi
/* Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
valeur = extras.getString(EXTRA_URL_nommatiere); //Affiche le nom matiere
}
else
{
}
editText_one.setText(valeur );*/
return view;
}
#Override
public void onPause() {
super.onPause();
String persistentVariable = editText_one.getText().toString();
Intent intent = new Intent(getActivity(), One.class);
intent.putExtra(persistentVariable, PERSISTENT_VARIABLE_BUNDLE_KEY);
//startActivity(intent);
getArguments().putString(persistentVariable, PERSISTENT_VARIABLE_BUNDLE_KEY);
}
/* #Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle extras = getActivity().getIntent().getExtras();
if (savedInstanceState != null) {
// Restore last state for checked position.
valeur = extras.getString(EXTRA_URL_nommatiere);
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("TEXT", valeur);
}*/
/* #Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.v(TAG, "Inside of onRestoreInstanceState");
valeur = extras.getString(EXTRA_URL_nommatiere);
}*/
}
Can someone can help me please,
many thnaks
First you need to attach the fragments to activity then you can simply define two strings String one ,String two in the activity containing the fragments and assign the value of each editText to diffrent one
i.e
String one=editTextOne.getText.toString();
String two=editTextTwo.getText.toString();
When you have to switch between either activities or fragments, you can use Shared Preferences to store a small amount of datas and retrieve them.
Shared Prefs are small sets of key/value pairs.
Write
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();
Read
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
You can write and read any primitive data types such as Strings using put[Type] and get[Type] methods.
Source codes above come from the official android developer training and belongs to Android.
"is there a way with saveInstanceState ?"
I think this bundle is usefull when one activity is destroyed and created by Screen rotation or resumed after a call, but not when switching between activities and fragments.
But you can try it. I know that views like EditText with id have a built-in saveInstanceState so you do not have to handle it manually.
To switch between fragments you can use activity class scoped properties. You will need to add interfaces to your fragments to allow them to communicate with the activity.
EXAMPLE
The following example shows how to switch between fragments and keep EditText values.
The MainActivity contains a FrameLayout and two buttons. The fragment transaction is done on button click events.
Fragments include an interface to communicate with the activity. Each time the EditText value is changed, the activity's property is updated.
The activity communicates with the fragment to set EditText value right after the transaction.
First of all, here are xml layouts files for the MainActivity, the FragmentA and the FragmentB classes :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="100"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="morbak.stackoverflow.fragmentcommunication.MainActivity">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:orientation="horizontal"
android:weightSum="100">
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="Fragment A" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="Fragment B" />
</LinearLayout>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/etOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Fragment A content"/>
</LinearLayout>
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/etTwo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Fragment B content"/>
</LinearLayout>
fragment_b.xml
Then, here are Fragments A and B classes. Source code is self explanatory.
package morbak.stackoverflow.fragmentcommunication;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class FragmentA extends Fragment {
//Views
EditText etOne;
//Fields
String value;
//Listeners
OnFragmentASelectedListener mCallback;
//Context
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate views and layouts
View rootView = inflater.inflate(R.layout.fragment_a, container, false);
etOne = (EditText) rootView.findViewById(R.id.etOne);
//Events
etOne.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//Execute the interface's abstract method
mCallback.onFragmentASelected(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
etOne.setText(value);
return rootView;
}
//Set the fragment's field value
public void setEditText(String newValue) {
value = newValue;
}
//Interface
public interface OnFragmentASelectedListener {
public void onFragmentASelected(String value);
}
//Throws an exception if the activity implements FragmentA.OnFragmentASelectedListener, but not the abstract method
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity;
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (OnFragmentASelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentASelectedListener");
}
}
}
FragmentA.java
The same work should be done with FragmentB, but you obviously have to search and replace FragmentA to FragmentB and etOne to etTwo.
Finally, here is the MainActivity who handles fragment transactions and uses fragments' listeners :
package morbak.stackoverflow.fragmentcommunication;
import android.content.Context;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements FragmentA.OnFragmentASelectedListener, FragmentB.OnFragmentBSelectedListener {
Button button1;
Button button2;
FragmentTransaction transaction;
FragmentA fragmentA;
FragmentB fragmentB;
String editTextOne;
String editTextTwo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
editTextOne = "";
editTextTwo = "";
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
transaction = getSupportFragmentManager().beginTransaction();
fragmentA = new FragmentA();
transaction.replace(R.id.fragment_container, fragmentA);
transaction.addToBackStack(null);
transaction.commit();
fragmentA.setEditText(editTextOne);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
transaction = getSupportFragmentManager().beginTransaction();
fragmentB = new FragmentB();
transaction.replace(R.id.fragment_container, fragmentB);
transaction.addToBackStack(null);
transaction.commit();
fragmentB.setEditText(editTextTwo);
}
});
}
public void onFragmentASelected(String value) {
editTextOne = value;
}
public void onFragmentBSelected(String value) {
editTextTwo = value;
}
}
MainActivity.java
Right ive now got my button counter working and it will increment when clicked but my problem now is it wont save so when it reopens it will start fresh again.... ill put my code below but any help adding the save function to it would be greatly appreciated!
package com.example.counter;
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView;
public class MainActivity extends Activity {
// Private member field to keep track of the count
private int mCount = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView countTextView = (TextView) findViewById(R.id.TextViewCount);
final Button countButton = (Button) findViewById(R.id.ButtonCount);
countButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mCount++;
countTextView.setText("Count: " + mCount);
}
});
}
}
xml layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="#+id/TextViewCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/hello_world" />
<Button
android:id="#+id/ButtonCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/ButtonCount"
android:layout_alignRight="#+id/ButtonCount"
android:layout_marginBottom="61dp"
android:text="Count" />
</RelativeLayout>
This link will help you. its the easiest way to store data
http://developer.android.com/guide/topics/data/data-storage.html#pref
You would read the counter data at onCreate and save it at onPause so it restores nicely when your user opens the app again. More details at http://developer.android.com/reference/android/app/Activity.html
Dont save the counter each time your button is clicked, it will incur in excessive I/O for your simple task, draining battery.
Overload the onPause method and save the variable using the SharedPreferences Class. You will also need to overload the onResume method to re-load that value into mCount.
Please Read: http://developer.android.com/training/basics/activity-lifecycle/pausing.html
public static final String PREFS_NAME = "com.example.myApp.mCount";
private SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
private SharedPreferences.Editor editor = settings.edit();
#Override
public void onPause() {
super.onPause(); // Always call the superclass method first
mCount = settings.getInt("mCount", 0);
}
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
editor.putInt("mCount", mCount);
editor.commit();
}
I'm trying to move the position of the seekbar using a button. Basically I have a seekbar from 0 to 100. and I have button presents set up at arbitrary values (40,50,60 etc). When I try to set the progress on the seekbar via button, I get a fault.. I've already initialized the seekBar in the onCreate() method.
SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar1);
currentProgress = 40;
seekBar.setMax(100);
seekBar.setProgress(currentProgress);
button40.setOnClickListener(button40Listener);
But when use the below, it crashes.
private OnClickListener button40Listener = new OnClickListener() {
public void onClick(View v) {
currentProgress = 40;
seekBar.setProgress(currentProgress);
}
}
This seems straight-forward. Any ideas?
You shouldn't need to put up another Seekbar. The initial one should be fine. Without the exception message and stack trace I'm not sure what is causing the crash. However, I just coded an example and works as you would expect. Perhaps by looking at my example you can identify your issue.
SeekbarTest.java:
package com.example.seekbartest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
public class SeekbarTest extends Activity {
/** Called when the activity is first created. */
private SeekBar seekBar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
seekBar = (SeekBar)findViewById(R.id.seekBar1);
Button fortyPctButton = (Button)findViewById(R.id.buttonFortyPct);
fortyPctButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
seekBar.setProgress(40);
}
});
Button sixtyPctButton = (Button)findViewById(R.id.buttonSixtyPct);
sixtyPctButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
seekBar.setProgress(60);
}
});
Button eightyPctButton = (Button)findViewById(R.id.buttonEightyPct);
eightyPctButton.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
seekBar.setProgress(80);
}
});
}
}
And here is the main.xml it is referencing for the layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:text="#string/hello"
android:id="#+id/textView1"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/seekBar1"
android:layout_below="#+id/textView1"
android:layout_alignLeft="#+id/textView1"
android:layout_alignRight="#+id/textView1"/>
<Button
android:layout_width="wrap_content"
android:text="40%"
android:id="#+id/buttonFortyPct"
android:layout_height="wrap_content"
android:layout_below="#+id/seekBar1"
android:layout_alignLeft="#+id/seekBar1"/>
<Button
android:layout_width="wrap_content"
android:text="60%"
android:id="#+id/buttonSixtyPct"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/buttonFortyPct"
android:layout_alignTop="#+id/buttonFortyPct"
android:layout_alignBottom="#+id/buttonFortyPct"/>
<Button
android:layout_width="wrap_content"
android:text="80%"
android:id="#+id/buttonEightyPct"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/buttonSixtyPct"
android:layout_alignTop="#+id/buttonSixtyPct"
android:layout_alignBottom="#+id/buttonSixtyPct"/>
</RelativeLayout>
Just create a new android app and replace the generated code + layout with the example above. It should work for you.
Good luck,
Craig