I'm trying to create a basic "Find my nearest..." application as a learning exercise.
I have 3 activities:
I have most things working, however I have noticed a slight problem, arising the difference from the back button (at the bottom of my phone screen), and the up button (the on action bar). After researching the difference between the two, it would appear they should behave the same in this scenario. When hitting the back button, everything works as intended, and we still see the same list. However, when hitting the up button, it appears to startup / resume the list activity in a different way, and the data from the list has disappeared.
Would anyone be able to explain to me why this is happening and how to prevent it?
My code is below: (any criticisms about my Android / Java techniques are very welcome!)
MainActivity.java
public class MainActivity extends Activity {
public final static String TRACKS = "com.example.firstapp.TRACKS";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/** Called when the user clicks the 'Search' button */
public void search(View view) {
// Get Address Text
// EditText editText = (EditText) findViewById(R.id.edit_address);
// String address = editText.getText().toString();
// Get tracks near to address
Track[] trackArray = new Track[20];
for(int i=0; i < trackArray.length; i++) {
trackArray[i] = new Track("Track " + i, "Address" + i, (float) Math.random()*10);
}
// Fire intent to show results
Intent intent = new Intent(this, TrackListActivity.class);
intent.putExtra(TRACKS, trackArray);
startActivity(intent);
}
}
TrackListActivity.java
public class TrackListActivity extends ListActivity {
public final static String TRACK = "com.mycroft.runtrackdir.TRACK";
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent.hasExtra(MainActivity.TRACKS)) {
Parcelable[] tempTrackArray = intent.getParcelableArrayExtra(MainActivity.TRACKS);
// Cast Parcelable to Track
Track[] trackArray = new Track[tempTrackArray.length];
for(int i=0; i < trackArray.length; i++) {
trackArray[i] = (Track) tempTrackArray[i];
}
ArrayAdapter<Track> arrayAdapter = new ArrayAdapter<Track>(this, android.R.layout.simple_list_item_1, trackArray);
setListAdapter(arrayAdapter);
}
}
@Override
protected void onListItemClick (ListView l, View v, int position, long id) {
Track clickedTrack = (Track) l.getItemAtPosition(position);
// Fire intent to show detail
Intent intent = new Intent(this, TrackDetailActivity.class);
intent.putExtra(TRACK, clickedTrack);
startActivity(intent);
}
}
TrackDetailActivity.java
public class TrackDetailActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Track track = intent.getParcelableExtra(TrackListActivity.TRACK);
setContentView(R.layout.activity_track_detail);
TextView track_name = (TextView) findViewById(R.id.track_name);
TextView track_address = (TextView) findViewById(R.id.track_address);
TextView track_distance = (TextView) findViewById(R.id.track_distance);
track_name.setText(track.name);
track_address.setText(track.address);
track_distance.setText(track.distance.toString());
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.firstapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.firstapp.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.firstapp.TrackListActivity"
android:label="@string/title_activity_track_list"
android:parentActivityName="com.example.firstapp.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.firstapp.MainActivity" />
</activity>
<activity
android:name="com.example.firstapp.TrackDetailActivity"
android:label="@string/title_activity_track_detail"
android:parentActivityName="com.example.firstapp.TrackListActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.firstapp.TrackListActivity" />
</activity>
</application>
</manifest>
The Up button never exits your app If a user is at the app's start destination, then the Up button does not appear, because the Up button never exits the app. The Back button, however, is shown and does exit the app.
It means that Back button kills an app whereas Home button sends an app to background (Android memory manager can still choose to kill it if system runs out of memory).
Back navigation is how users move backward through the history of screens they previously visited. All Android devices provide a Back button for this type of navigation, so you should not add a Back button to your app's UI.
No, not every device comes with a back button.
I think you should modify your Manifest.xml
file and tell your Manifest file
the relationships between your activities. This should solve the problem.
For Example:
<application ... >
...
<!-- The main/home activity (has no parent activity) -->
<activity
android:name="com.example.myfirstapp.MainActivity" ...>
...
</activity>
<!-- A child of the main activity -->
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- Parent activity meta-data to support API level 7+ -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
You can also review this document.
EDIT:
You can also use Data Persistence, if you are receiving empty Intents in certain Activities.
for Data persistence in Android, you can use Shared Preferences, SQLite Database, Serialization, etc
As you are learning Android Development, you can simply put the trackArray
values in Shared Preferences of your application while starting List Activity from Main Activity and Load the data of trackArray
from Shared Preferences in List Activity in onResume
and populate it in onCreate
.
This way, your Action bar's up button will not make the data of ListView Activity disappear.
P.S: Shared pref's actual purpose is to store values that are less in size and are changed occasionally such as Setting's data of a specific Application. Therefore, please don't misuse it.
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