Updating list in one class after action in another - android

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

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

Coming back from intent, do something

I have an android application which is using listView. After clicking on any item on the list it shows you AlertDialog where you can chose either edit or delete. After clicking edit it starts a new intent sending some extra strings to fill up the form for editing. I would like to refresh the list after I click on button save in that EditActivity.
I have read about notifyDataSetChanged() and I think it could work I just would like to know if there is any method which is in MainClass (listView class) and it is executed right after I came back from intent, right after clicking save button in EditActivity.
Or may I just add notifyDataSetChanged() method after I start an activity in the MainActivity?
public class yourClass extends ListActivity {
//define a class variable here.
private ArrayAdapter<Friend> adapter;
#Override
public void onCreate(Bundle savedInstanceState){
//Change this line setListAdapter(new ArrayAdapter<Friend>(this, android.R.layout.simple_list_item_1, db.getAllFriends()));
to
adapter = new ArrayAdapter<Friend>(this, android.R.layout.simple_list_item_1, db.getAllFriends());
setListAdapter(adapter);
}
#Override
public void onResume(){
super.onResume();
adapter.notifyDataSetChanged();
}
}
You can add listView.notifyDataSetChanged() in your activity onResume() function.
#Override
public void onResume(){
super.onResume();
yourListView.notifyDataSetChanged();
}
Use the method startActivityForResult() when opening your EditActivity then implement onActivityResult method in your main class. There you will be able to use notifyDataSetChanged
Read this from the doc
use startActivityForResult to call your EditActivity (this isn't simplest way to do what you want but is good way to do), by using this you can find out what is the result of your edit
Intent i = new Intent(this, EditActivity.class);
startActivityForResult(i, 1);
In your EActivity set the data which you want to return back to MainActivity
Intent returnIntent = new Intent();
returnIntent.putExtra("result",YOUR_RESULT); // skip if you do not want to return special result
setResult(RESULT_OK,returnIntent);
finish();
if you want to send cancel action (in your case fail edit) use this
Intent returnIntent = new Intent();
setResult(RESULT_CANCELED, returnIntent);
finish();
Now in your MainActivity class write following code for onActivityResult() method
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
String result=data.getStringExtra("result"); // result sent from EditActivity
listViewAdapter. notifyDataSetChanged();
}
if (resultCode == RESULT_CANCELED) {
//Write your code if there's no result
}
}
}//onActivityResult

How to get access to back button in android?

Can you please clarify me, what's the best practice for this example:
Activity1 does INSERTS on SQLite and starts Activity2.
On Activity2, the user clicks on Back button and goes back to Activity1.
But instead of making INSERT, I want to make UPDATE to the data on SQLite.
How do I control, that user "came" back?
What's the best practice?
Assume on button click you starting Activity 2
public static final int YOURCONSTANTNUMBER = 77;
//Button Value
Button second = (Button)findViewById(R.id.firstButton);
second.setOnClickListner(this);
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.btnSecondActivity:
//Code for inserting data into database
Intent secondactivity = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(secondactivity);
break;
}
}
In your second activity
To take control over the back button use the below code
#Override
public void onBackPressed()
{
//Code for update
}
EDIT
Call your second activity with startActivityForResult() method which will let you know the result.
In First Activity
Intent secondactivity = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(secondactivity,YOURCONSTANTNUMBER);
Getting Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode)
{
case YOURCONSTANTNUMBER:
// It will execute if you returning from second activity
//Update you database here
}
}
In Your Second Activity
Call this method were appropriate setResult(YOURCONSTANTNUMBER);
Hope it helps
Assuming you want to do both DB operations in Activity1, consider startActivityForResult() here:
http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int)

restart activity in android

I have one activity A, that has one button and one list view which shows names of books . on click of the button, activity B starts, there user fill the book form and save it . when he press back button , user comes to activity A. Here the book name should be updated in listview. I think I have to write some code in onResume() . Can u please tell me what to write. I am using customised list view.
Start activity B with startActivityForResult() and use method onActivityResult() to restart or process the new data
For example, to start Activity B:
String callingActivity = context.getLocalClassName();
Intent newActivity = new Intent(getApplicationContext(),ActivityB.class);
newActivity.setData(Uri.parse(callingActivity));
startActivityForResult(newActivity, 0);
Then somewhere in your Activity A class:
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == 0){
// do processing here
}
}
The other answers should suffice, but onResume() can be called in cases where the activity is resumed by other means.
To simply restart Activity A when user presses back button from Activity B, then put the following inside the onActivityResult:
if(requestCode == 0){
finish();
startActivity(starterintent);
}
And in the onCreate of Activity A, add starterintent = getIntent();
Just remember to initiate the variable with Intent starterintent; somewhere before your onCreate is called.
e.g.
public class ActivityA extends ListActivity {
Intent starterintent;
public void onCreate(Bundle b){
starterintent = getIntent();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == 0){
finish();
startActivity(starterintent);
}
}
private void startActivityB(){
String callingActivity = context.getLocalClassName();
Intent newActivity = new Intent(getApplicationContext(),ActivityB.class);
newActivity.setData(Uri.parse(callingActivity));
startActivityForResult(newActivity, 0);
}
}
Then just call startActivityB() from a button click or whatever
YES you are right. Write code in onResume.
When you updated date just call notifyDataSetChanged(); for your ListView adapter
Hope, it help you!
You can either start the activity when user press on Save, and it will fix it for you.
Or if you want to press back:
#Override
public void onResume(){
super.onResume();
list.clear();
list.addAll(getBooks());
adapter.notifyDataSetChanged();
}

Categories

Resources