ListView item gets destroyed while moving to other activity - android

My first activity contains a listview with textviews in each cell and uses a custom adapter. So if you click on any of the items, it will open up a form activity containing textfields. The user can fill up the details and once they press the save form button the details appear on the listview. Now I am trying to add items to the list dynamically. I have created a button which when clicked adds a new instance item so that more users can register the same way. I have been able to implement these functions. However, my problem now is when i click on the newly added item and go to the form activity and click save, i am not able to see the newly added entry after i come back to the listview activity.All I see is the first entry alone. So i am guessing it gets destroyed as soon as i leave the activity. How to ensure all newly added items are not destroyed when i keep moving between these two activities.
Here is my code of the ListView Activity:
public class FormTableActivity extends Activity {
private PassengerListAdapter adapter;
Button add_passenger;
String mrzdata,ic_data,name_data;
SharedPreferences nPref;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.final_display_listview);
nPref = PreferenceManager.getDefaultSharedPreferences(this);
mrzdata = nPref.getString("MRZ", "");
name_data = nPref.getString("resultData", "");
ic_data = nPref.getString("icdata", "");
final ListView lv1 = (ListView) findViewById(R.id.custom_list);
adapter = new PassengerListAdapter(this);
adapter.add(new CustomerDetails(ic_data, name_data, mrzdata));
add_passenger = (Button) findViewById(R.id.add_user);
add_passenger.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// mrzdata = "";
// name_data = "";
// ic_data = "";
adapter.add(new CustomerDetails(ic_data, name_data, mrzdata));
}
});
lv1.setAdapter(adapter);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Intent intent = new Intent(v.getContext(), FirstActivity.class);
startActivity(intent);
}
});
}

The easiest way to pass data between Intent is
Intent intent = new Intent(getBaseContext(), your_list_view_activity.class);
intent.putExtra("String_Key", data1);
//data1 could be an array of string where you have hold the values previously
startActivity(intent);
now on your list_view_activity
Bundle extras = getIntent().getExtras();
if (extras != null) {
String [] value = extras.getString("String_Key");
}
This way you won't get any exception but you get to populate your listView if there is data.
Another way to get data is via SharedPreference but I won't recommend it as it increases the size of the app.

You have to save these newly added items somewhere , e.g. to a SQLite database and retrieve them on create to populate the listview
You can see here if You want, the code is commented ,
here I have a listview with custom adapter with two items
the feed's name and it's url
i add URL and name using a text input dialog (with two edit text), save to DB, and retrieve them on create to populate the listview
https://github.com/enricocid/iven-feed-reader/blob/master-as/project/app/src/main/java/com/iven/lfflfeedreader/mainact/ListActivity.java

Related

Saving an activity state when I press up button in action bar

I'm developing an android Wallpaper app consists of 2 activity, main activity displays the images from the internet in ListView and the second activity displays the preview of that image.
my problem is when I press the back button in preview activity to go back to the main activity, the main activity displays the images from the beginning and I would like to display the images from the last I clicked on.
The following code in onCreate() method in Main Activity:
// Find a reference to the {#link ListView} in the layout
ListView gameListView = findViewById(R.id.list);
mEmptyStateTextView = findViewById(R.id.empty_view);
gameListView.setEmptyView(mEmptyStateTextView);
// Create a new adapter that takes an empty list of games as input
mAdapter = new GamesAdapter(this, new ArrayList<Games>());
// Set the adapter on the {#link ListView}
// so the list can be populated in the user interface
gameListView.setAdapter(mAdapter);
// Set an item click listener on the ListView, which sends an intent to a web browser
// to open a website with more information about the selected game.
gameListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Find the current game that was clicked on
Games currentGame = mAdapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri gameUri = Uri.parse(currentGame.getUrl());
String name = currentGame.getName();
// Create a new intent to view the game URI
Intent i = new Intent(GamesActivity.this, PreviewActivity.class);
i.setData(gameUri);
i.putExtra("name", name);
startActivity(i);
}
});
The following code in onCreate() method in Preview Activity:
final Uri i = getIntent().getData();
String profile = getIntent().getStringExtra("name");
photographer.setText(profile);
Picasso.with(this).load(i).into(img);
saveImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
downloadFile(i);
}
});
I think what your are looking for is the method onSaveInstanceState(Bundle outState) here you can save your values in the outState and get them in onCreate() at the savedInstanceState
here is a very good example how to use it.
I think you want to preserve the scroll distance. For that what you need to do is you can preserve using Bundle object. But you can also clear current activity then you will get the same results.
Add this outside the onCreate() method(this is java):
#Override
public void onBackPressed() {
this.finish(); //important
}
finish() clears activity from back stack.

New arraylist item overwrites previous listview item

Currently I'm trying to send intent data from user input to display onto my custom adapter. The intent data from user input from the detailspage.java class will be sent to the listview page with custom Arrayadapter. However each time i add a new item it overwrites my previous entries. Hope some kind souls can help someone new to android.
Below are snippets of my code.
// Set a click listener on that button
btnAddData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveExercise(exerciseName);
}
});
}
private void saveExercise(String name) {
// Read from input fields
// Use trim to eliminate leading or trailing white space
String setString = mSetEditText.getText().toString().trim();
String repString = mRepEditText.getText().toString().trim();
String nameString = name;
Intent intent = new Intent(ExerciseDetailActivity.this, WorkoutSetActivity.class);
intent.putExtra("name", nameString);
intent.putExtra("set", setString);
intent.putExtra("rep", repString);
startActivity(intent);
}
The intent data will be sent to the activity page to initiate the custom ArrayAdapter.
public class WorkoutSetActivity extends AppCompatActivity {
ArrayList<WorkoutSet> workout = new ArrayList<WorkoutSet>();
/** Adapter for the ListView */
WorkoutSetAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exercise_list);
adapter = new WorkoutSetAdapter(this, workout);
ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
Intent intent = this.getIntent();
String name = intent.getExtras().getString("name");
String set = intent.getExtras().getString("set");
String rep = intent.getExtras().getString("rep");
adapter.add(new WorkoutSet(name,set,rep));
Toast.makeText(WorkoutSetActivity.this, "Workout added.", Toast.LENGTH_SHORT).show();
adapter.notifyDataSetChanged();
}
}
Lastly the custom ArrayAdapter code. This is where I set the custom listview.
public class WorkoutSetAdapter extends ArrayAdapter<WorkoutSet> {
public WorkoutSetAdapter(Activity context, ArrayList<WorkoutSet> workout) {
super(context, 0, workout);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if the existing view is being reused, otherwise inflate the view
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.activity_workout_set, parent, false);
}
WorkoutSet currentWorkout = getItem(position);
// Find individual views that we want to modify in the list item layout
TextView nameTextView = (TextView) listItemView.findViewById(R.id.workout_name);
TextView setTextView = (TextView) listItemView.findViewById(R.id.workout_set);
TextView repTextView = (TextView) listItemView.findViewById(R.id.workout_rep);
nameTextView.setText(currentWorkout.getName());
setTextView.setText("Sets: "+ currentWorkout.getSet());
repTextView.setText("Reps: "+ currentWorkout.getRep());
return listItemView;
}
}
each time i add a new item it overwrites my previous entries
There are no "previous entries". startActivity loads an empty adapter each time and you only add one element.
What you want is a SQLite database (or any persistent storage layer, but SQLite is provided without more libraries).
On the plus side, your Intent and Adapter code look fine.
Every time,you call startActivity (), you open a new WorkoutSetActivity, it's a new WorkoutSetActivity object instance, so the arrayAdapter is also new one, it will only display the data you send this time.
If you want to display all the data, you must save the previous data to database or file. At WorkoutSetActivity onCreate (), you should get the previous data, put them and current data to the adapter.

Transfer two listview data on click of one listview

In my activity I have two listviews with some data. On first listview selected row will be highlighted on click and on click on 2nd listview new activity starts.
I want to send the highlighted row data of first listview and clicked row of 2nd listview data on next activity. How can Iachieve that?
supposing your lists are named list1 & list2, add to your list2 onItemClickListener that should looks something like this :
public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
String highlightedItem = (String)list1.getSelectedItem();
String clickedItem = (String)list2.getItemAtPosition(position);
Intent intent = new Intent(FirstAcivity.this, SecondActivity.class);
intent.putExtra("highlightedItem", highlightedItem);
intent.putExtra("clickedItem", clickedItem);
startActivity(intent);
}
and then in your Second Activity you can receive the items like this :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
if (intent != null){
String highlightedItem = intent.getStringExtra("highlightedItem");
String clickedItem = intent.getStringExtra("clickedItem");
}
}
I have assumed your list items are of type String but you can apply the same logic for any other type.
In case your want to send object not just primitives you need to make your objects implements Serializable or Parcelable interface.

Passing ListView to hint

I am trying to make an edit feature for my todo list app. What I want to do is to tap an item on the list and then I would be sent to the new page where I can edit the item on my list. I am currently getting a warning :
This text field does not specify an inputType or a hint
Issue: Looks for text fields missing inputType or hint settings
Id: TextFields
I was wondering how can I pass the text in my ListView to my second activity as the first thing to be edited in my EditText?
This is what I have so far:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_do);
etNewItem = (EditText) findViewById(R.id.etNewItem);
lvItems = (ListView) findViewById(R.id.lvItems); // now we have access to ListView
readItems(); // read items from file
todoAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems); //create adapter
lvItems.setAdapter(todoAdapter); // populate listview using the adapter
setupListViewListener();
setupEditItemListener();
}
private void launchEditItem() {
Intent i = new Intent(this, EditItemActivity.class);
startActivity(i);
}
private void setupEditItemListener() { // on click, run this function to display edit page
lvItems.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
launchEditItem();
}
});
}
I can't tell from what you have posted what exactly you are trying to pass. However, there are several things you can do.
(1) You can put a reference to your ListView in a subclass of Application. Application is a good place to put application-scope global variables.
(2) Similar to (1), put a reference to the adapter in your Application subclass.
(3) You can pass the query or other list setup parameters to the edit activity and let it requery.
(4) You can pass the index or other key info from the selected list item using putExtra() to the intent. You can pass updated info back to the main activity by passing back an intent. The main activity will receive the returned intent if it uses StartActivityWithResult().

ListView items not getting populated when activity is launched

Here is my scenario:
I have a MainActivity and a CustomListViewActivity. In my MainActivity, I have 1 button and 1 spinner. On click of the button, I pass the selected spinner value to the CustomListViewActivity via Bundle and using Intents.
Now, in my CustomListViewActivity, I have a ListView that uses ArrayAdapter for populating it. I send a ArrayList from MainActivity, say for example
items = [abc]
In my CustomListViewActivity, I receive the same and use it to populate my ListView. The first time I do this, my value gets populated. The second time I do the same, the value existing is now replaced with the new one and the ListView shows one item instead of showing two.
So basically the problem is that the ListView is not updating and not showing both the items. Instead it shows me a single item always.
Here are snippets of my code
MainActivity.java
//code inside button click
..
{
items.add(spinner1.getSelectedItem().toString());
Bundle bundle =new Bundle();
bundle.putStringArrayList("data",items);
Intent i = new Intent(MainActivity.this,MyListViewActivity.class);
i.putExtras(bundle);
startActivity(i);
finish();
}
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
Log.i("App","onSave");
icicle.putStringArrayList("data",items);
}
#Override
protected void onRestoreInstanceState(Bundle icicle2) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(icicle2);
Log.i("App","onRestore");
icicle2.putStringArrayList("data",items);
}
MyListViewActivity.java
private ArrayList<String> myItems;
private static String[] titles;
CustomListViewAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
listView = (ListView) findViewById(R.id.list1);
rowItems = new ArrayList<RowItem>();
adapter = new CustomListViewAdapter(this,R.layout.list_item, rowItems);
listView.setAdapter(adapter);
b=getIntent().getExtras();
if(b!=null)
{
myItems=b.getStringArrayList("data");
titles= new String[myItems.size()];
titles = myItems.toArray(myItems);
}
...
int i=0;
while(i<titles.length) {
item = new RowItem(titles[i]);
//rowItems.add(item);
Log.i("ROW", ""+rowItems.size());
i++;
adapter.add(item);
listView.setAdapter(adapter);
}
adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();
}
}
How to make the ListView maintain the current data as well reflect the added data?
Thanks in advance
EDIT : Forgot to mention one more thing. In my MyListViewActivity class I have a button above the ListView that on clicked takes me to my MainActivity so that I can add a new Item again. So when I go back to MainActivity and try and add a new Item , it's the new Item that get displayed rather than showing both the previous and the new one
You need to persist and restore your items list in MainActivity's onSaveInstanceState and onRestoreInstanceState methods.
You also probably don't need to close the MainActivity by calling finish() every time you start the ListView activity but that depends on your application.
Basically, the problem you are having is that items is being recreated with each new instance of MainActivity. Since you finish MainActivity, a new instance is used every time you access that activity (and I assume you thought that items would just keep getting items added to it).

Categories

Resources