Android Activity onResume() and onActivityResult() conflict - android

Have a problem. In my main Activity I have a ListView. And I need to refresh it any time I returned to this Activity. I use onResume() method for this:
#Override
protected void onResume() {
super.onResume();
refreshCategoriesList();
}
private void refreshCategoriesList() {
// ...
categoriesListAdapter = new CategoryListItemAdapter(
this, R.layout.category_item,
categories
);
categoriesListView.setAdapter(categoriesListAdapter);
}
As you can see I use refreshing adapter extended from ArrayAdapter for changing data in ListView.
But in some cases I need scroll this list to the end, for ex. when I add new item to it. And I use onActivityResult(...) method for this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// ...
refreshCategoriesList();
categoriesListView.setSelection(categoriesListAdapter.getCount() - 1);
}
But I have one problem. When I add new item to my list both this methods executed in order onActivityResult(...) and after that onResume(). And I have:
List data refreshed to times with refreshCategoriesList() (But it's not main problem);
After executing of onResume() scrolled to end list restored to first item position :( It's a problem. Because when I add new item I want scroll list to the end.
How can I resolve this problem. Can I in some cases call only onActivityResult(...) method (when I need to scroll list) and in other onResume() method (when I simply want to refresh list data)?

You can use notifyDataSetChanged() method from ArrayAdapter instead of recreating adapter every time.
private void refreshCategoriesList() {
categoriesListAdapter.notifyDataSetChanged();
}

Related

Correct way to refresh a ListView adapter in Android

I have a list of items. I have a button that sends you to another activity in order to create a new item. When the new item is saved an intent sends you back to the activity with the list where the new item should be added. The adapter extends from BaseAdapter without filtering, it just sets the data to the views.
My code is this:
onCreate(){
ListView listView = findItemById......
listView.setListeners.......
}
onResume(){
data = getData();
adapter = new ListAdapter(context,data);
listView.setAdapter(adapter);
}
It works but is this correct?
Can I use creation of adapter and setAdapter in onCreate and use notifyDataSetChanged() only in onResume somehow?
I think the correct way to do it is a use
startActivityForResult(...)
method to launch your Second activity (where your new items is added).
And in your second activity use
setResults(RESULT_OK or RESULT_CANCELLED)
(diffrent result when new items is added or user just back to prev screen).
Then in your ListAdapter class add method
public void updateData(List data) {
this.data = new ArrayList<>(data);
notifyDataSetChanged();
}
And call it in your onActivityResults(...)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == YOUR_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
adapter.updateData(...your data from result Intent, or from anywhere else...);
}
}
Also i strongly recommend you to use RecyclerView instead of ListView
UPD: to answer your question - i think that biggest mistake in your code, is to create new instance of ListAdapter object in onResume() method, when it's not necessary
Add this method to your adapter and then call it with new data using adapter.udpateData(data):
public void updateData(List data) {
this.data = data;
notifyDataSetChanged();
}
Also, you can use notifyItemRangeInserted(0, data.size())
Hi OnActivityResult read all data create the new object and add to the list and call notifyDatasetChanged() , i will automatically refresh ui

ListView with CursorAdapter is not refreshing even if I use swapCursor or changeCursor methods in Android

I have two activities an initial with a Listview and a FAB and a second one with editText, Save and Clear Buttons.
I call the second one the activity for result I enter my values and click Save Button. My list is not refreshed its displaying only the first element and I did
the following
in the first activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
// check if the request code is same as what is passed here it is 2
if(requestCode==3)
{
player = mHelper.getPlayersByTeam(new_id);
if(player!=null && player.getCount()>0)
{
playerdataAdapter = new PlayerAdapter(this, player);
// Assign adapter to ListView
listPlayers.setAdapter(playerdataAdapter);
playerdataAdapter.notifyDataSetChanged();
playerdataAdapter.swapCursor(mHelper.getPlayersByTeam(new_id));
}
}
What I am doing wrong here? why listview not displaying the refreshed data
Check your database if you retrieve the proper records

Updating list in one class after action in another

I have a problem where by I have two activities, activity 1 and activity 2. Activity 1 contains a listview of contents in my SQLite database, activity 2 contains a button that when pressed preforms a query on the database. This query when run will alter the information in activity 1's list.
When I press the button the query works fine but the listview in activity 1 does not get updated. I know I have to use notifyDataSetChanged on the listview in order to have the list information updated.
My problem is how do I call this method on the list in activity 1 from the button listener in activity 2?
Listview and adapter in activity 1
String[] columns = new String[] {adapter.KEY_CONTENTS_NAME, adapter.KEY_CONTENTS_MEASUREMENT, adapter.KEY_CONTENTS_UNIT};
int[] to = new int[] {R.id.ingredientName, R.id.ingredientMeasurement, R.id.ingredientUnit};
SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter(this,R.layout.row2, cursor, columns, to, 0);
ListView ingredientList = (ListView) findViewById(R.id.ingredientList);
ingredientList.setAdapter(myCursorAdapter);
Button in activity 2
Button cookButton = (Button) findViewById(R.id.cookButton);
cookButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//simple SQL query
//call to activity 2 to update the list
}
});
You can use startActivityForResult to achieve this.
In your first activity when you want to start the second activity like this using startActivityForResult.
Intent myIntent = new Intent(FirstActivity.this, SecondActivity.class);
int FIRST_ACTIVITY_CODE = 100
startActivityForResult(intent, FIRST_ACTIVITY_CODE);
In your second activity when doing the click you want to setResult okay and then quit the activity to return to the first activity.
Button cookButton = (Button) findViewById(R.id.cookButton);
cookButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//simple SQL query
setResult(RESULT_OK);
finish();
}
});
In your first activity you have to override onActivityResult and then update your list.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FIRST_ACTIVITY_CODE) {
myCursorAdapter.notifyDataSetChanged();
}
}
So you can communicate with activities by using onActivityResult. If you want to pass the data you got back from your SQL query in the second activity to your first activity you can use setResult(int resultCode, Intent data)
Then write this function in your list activity:
#onResume
public void onResume(){
super.onResume();
myCursorAdapter.notifyDataSetChanged();
}
As you go back to that activity, this function will be called and you can notify about the changes here by calling notifyDataSetChanged.
You could start activity using startActivityForResult. Here is the documentation and an example: http://developer.android.com/training/basics/intents/result.html
On the first activity you should have something like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// load data from db
// add data to the list view (create a new adapter or clear the items from the old one and add the new items)
// notifyDataSetChanged on adapter
}
}
}
Before calling notifyDataSetChanged. Load again info from db (and check if it was updated) and add it to the list view. Then call notifyDataSetChanged

dynamically adding item to listview with the result given by the child activity

i am stuck while developing my program.
i am not able to find the solution
what i am doing is, from one activity (A) i am calling other activity (B) for result.
now in activity A i have a list view.
for that listview i have an ArrayAdapter
the code for that purpose is :
String []name_list = myarraylist.toArray(new String[myarraylist.size()]);
ArrayAdapter<String> adapter = new ArrayAdapter <String>(this, R.layout.textview,name_list);
setListAdapter(adapter);
Activity A is ListActivity.
now , i have a menu option, clicking on which takes me to another activity, an returns with a result string.
up till this point , everything works fine. the string is also returned by the activity B.
now i want to add the string (the returned one) to the listview.....
how should i do that?
i tried doing it in onActivityResult() itself and also in onResume()
but i couldnt make it working.
help!
EDIT:
code for onActivityResult is :
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
Bundle mybundle = data.getExtras();
String pro_name= mybundle.getString("profile_name");
myarraylist.add(pro_name);
getAdapter().notifyDataSetChanged();
}
Use Arrayadapter add method http://developer.android.com/reference/android/widget/ArrayAdapter.html#add(T) in onactivityResult and call notifyDatasetchanged http://developer.android.com/reference/android/widget/ArrayAdapter.html#notifyDataSetChanged()

Notifying an ArrayAdapter of changes when closing a PreferenceActivity

I have a ListView that has some minor visual preferences that are set in a PreferenceScreen. These preferences are simple booleans to show or not to show some specific TextViews on each item in my ListView. Anyhow, when these preferences are changed, I need to notify my ArrayAdapter that the data has changed in order to get the list redrawn. However, doing this via an OnSharedPreferenceChangeListener wouldn't really be optimal because there are several preferences that you can change, that would cause an unnecessary amount of updates to the ArrayAdapter. So, to the question: How can I identify when my ListActivity has occurred on the screen after closing my PreferenceActivity, which I then could use to check for changes in the preferences, and only then notify the ArrayAdapter.
Edit: The ArrayAdapter being an inner class of my ListActivity, which is set as a ListAdapter.
There are several ways of doing it. As you noticed, the good way is to update your ListActivity when it becomes visible again.
To achieve that you can:
simply override onResume() method from your ListActivity. Method will be invoked when your activity comes to the foreground.
Another good solution would be to start your PreferenceActivity in such way:
//class member of your list activity
private static final int CODE_PREFERENCES = 1;
...
//running your preferences from list activity
Intent preferencesIntent = new Intent().setClass(this, YourPreferences.class);
startActivityForResult(preferencesIntent, CODE_PREFERENCES);
You also have to implement onActivityResult() in your list activity. This method will be invoked when preferences activity has been closed.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CODE_PREFERENCES) {
// notify your adapter that data has changed
}
}
PreferenceActivity extends Activity, so you can override onStop and there do those checks and notifications.

Categories

Resources