I am developing an android application in which I am using one base adapter and displaying data in list form.Now what happened If I remove any object from list and if I call notifyDataSetChanged, its not working as expected. I tried this in following manner.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
shareDataList = getData();
shareListAdapter = new SharedHistoryListAdapter(this, shareDataList);
sharedList.setAdapter(shareListAdapter);
}
#Override
protected void onResume()
{
super.onResume();
// after deleting data it is coming inside onresume ...
shareDataList = getData();
shareListAdapter.notifyDataSetChanged();
}
I checked data size inside my activity and inside adapter as well. So in activity it is showing count as expected but inside adapter it is not showing updated count. Am I missing something? Need some help.
You cannot change the reference of the list after setting the list to the adapter. so remove the line
shareDataList = getData();
and replace with
shareDataList.clear();
shareDataList.addAll(getData());
and now invoke the shareListAdapter.notifyDataSetChanged();
I think, in getData() method gets every time new ArrayList object.
You should simply call
shareListAdapter.notifyDataSetChanged();
it will work perfectly
Related
In my OnCreate method I am making a network call and populating a listview with the results. I am saving the result in an ArrayList and using the ArrayList to populate the listview. If the user presses the back button and reenters the activity I would like to store the ArrayLists in a SavedInstanceState Bundle and populate the ListView with the stored ArrayLists instead of making the network call a second time. The following is my OnCreate code:
if (savedInstanceState != null) {
largeImage = savedInstanceState.getParcelableArrayList("Image");
flowercode = savedInstanceState.getStringArrayList("Code");
flowerprice = savedInstanceState.getStringArrayList("Price");
flowerdimensions = savedInstanceState.getStringArrayList("Dimension");
largeImageText = savedInstanceState.getStringArrayList("Imagetext");
ListView listView = (ListView) findViewById(R.id.LowRomance);
FlowerShopAdapter listAdapter = new FlowerShopAdapter(this, flowercode, flowerName, flowerprice, largeImage, flowerdimensions);
listView.setAdapter(listAdapter);
} else if(savedInstanceState == null) {
makesoapcall();
}
}
This is my OnSaveInstanceState code
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList("Image", largeImage);
savedInstanceState.putStringArrayList("Code", flowercode);
savedInstanceState.putStringArrayList("Price", flowerprice);
savedInstanceState.putStringArrayList("Dimension", flowerdimensions);
super.onSaveInstanceState(savedInstanceState);
}
Currently my App is making the network call every single time. Is their something else I need to implement in order to get this to work or is their an error in the current way I am trying to implement this? The ArrayList's are definitely not null when I put them into savedInstanceState.
onSaveInstanceState() is not supposed to be called when the back button is pressed on an Activity. It's called when Android decides to destroy the Activity.
e.g. When orientation changes.
What you need here is SharedPreferences. Store the ArrayLists using SharedPreferences in onStop(). And get it in onStart(). Here is how to store ArrayList in SharedPreferences.
in my project I need to refresh the listview after some changes.
I use the following code:
#Override
protected void onResume(){
super.onResume();
this.onCreate(null);
}
When I run the project, the logcat returns this error:
java.lang.RuntimeException: Performing pause of activity that is not resumed: {it.xxx.yyy/it.xxx.yyy.TabsActivity}
Any idea?
You can not call onCreate method in onPause. Its affect to Android lifecycle.
You must to do:
adapter.notifyDataSetChanged();
To force an update (where adapter must be tour adapter variable)
If the requirement is just to refresh the List View, you can just call the below adapter method in. This would refresh the list view and of course you need to update the List with the changed values before calling this.
#Override
protected void onResume(){
super.onResume();
cursorAdapter.notifyDataSetChanged()
}
I want to call a listview adapter from another activies after insert record to sqllite db.
I cant call the adapter.notifyDataSetChanged() method. What is the best way to do it.
public void onClick(View v) {
TextView item_name;
item_name=(TextView) findViewById(R.id.eItemName);
Log.d("Insert: ", "Inserting ..");
db.add_item(new Item(item_name.getText().toString()), getApplicationContext());
// I want to call the method HERE!!!!
finish();
}
Just
After finish() Current Activity, Call adapter.notifyDataSetChanged() from onActivityResult()in previous Activity (As I assumes your Listview in this previous Activity).
Also start your Current Activity from Previous Activity using startActivityForResult();
Or if you have reference of List Adapter in this Activity, then using that reference call adapter.notifyDataSetChanged(). (But I think its not a good practice)
The better option would be re-loading your ListView with new data inside onResume() of your Activity where you have ListView. There is no need to call notifyDataSetChanged() from another class as you don't have your List visible in your another Activity.
#Override
protected void onResume() {
super.onResume();
//fill your Collection with new data
// setAdapter or notify your adapter
}
new to droid programming. im having a small problem that im sure is simply fixed but ive done some searching and a bunch of tutorials but cant seem to find just what i need so i figured id ask. My app has 2 activites, the first activity is just a simple form where a user enters course information(class title, professor..etc.)
the first activity passes the data which is supposed to be stored in a list in the second activity. problem is that only the first course gets stored in the list, after the first time nothing new gets added to the second activity. Can someone point me in the right direction please? thanks in advance
First Activity
public class CourseDetail extends Activity {
//Course c = new Course();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button save=(Button)findViewById(R.id.save);
save.setOnClickListener(onSave);
}
private View.OnClickListener onSave=new View.OnClickListener() {
public void onClick(View v) {
EditText course=(EditText)findViewById(R.id.course);
EditText professor=(EditText)findViewById(R.id.professor);
EditText location=(EditText)findViewById(R.id.location);
EditText officehrs=(EditText)findViewById(R.id.officehrs);
Intent i=new Intent(CourseDetail.this, CourseList.class);
i.putExtra("myCourse", course.getText().toString());
i.putExtra("myProfessor", professor.getText().toString());
i.putExtra("myLocation", location.getText().toString());
i.putExtra("myOfficehrs", officehrs.getText().toString());
startActivity(i);
}
};
}
Second Activity
public class CourseList extends Activity {
Button btnCourse;
List<Course> model = new ArrayList<Course>();
CourseAdapter adapter=null;
private String dCourse="";
private String dProfessor="";
private String dLocation="";
private String dOfficehrs="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clist);
ListView list =(ListView)findViewById(R.id.courses);
adapter=new CourseAdapter();
list.setAdapter(adapter);
Course c = new Course();
Bundle extras = getIntent().getExtras();
dCourse = extras !=null ? extras.getString("myCourse") :"no value entered";
dProfessor = extras !=null ? extras.getString("myProfessor") :"no value entered";
dLocation = extras !=null ? extras.getString("myLocation") :"no value entered";
dOfficehrs = extras !=null ? extras.getString("myOfficehrs") :"no value entered";
c.setCourse(dCourse);
c.setProfessor(dProfessor);
c.setLocation(dLocation);
c.setOfficeHrs(dOfficehrs);
btnCourse =(Button)findViewById(R.id.btnCourse);
btnCourse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
You are just getting the user entered value in CourseDetail activity and displaying the received value inside the CourseList activity, that means you are not storing these values permanently.
Go through this Android - Data Storage document.
When you move to 2nd activity i.e. CourseList activity, at that time fetch the data from the SQLite table and display the same. whenever you get new values from previous activity, at that time just update the list by adding the new data in ArrayList and make a call on adapter.notifyDataSetChanged()
Some suggestions:
Have your CourseList extend ListActivity instead of just Activity - check out some tutorials on that which should help you set things up correctly.
There seems to be a bit of confusion with how you're handling your lists - you have your model variable but don't seem to be doing anything with it. Again, have a look at a ListView tutorial (just google "android listview tutorial").
You seem to have figured out that you can use "intents" to pass information from one activity to another, but since you're only doing this in the onCreate() method, it's only happening once. Try doing this in your ListActivity's adapter once for each item.
Don't give up on Android, keep trying :-)
Some suggestion:
You have to add your object to the adapter: adapter.add(c); after you get the data.
Call adapter.notifyDataSetChanged() to notify the system that your data for the listView has been changed. Call list.invalidate() to refresh it.
I noticed that you set the button with the finish() method. Hmm, if you do so, the next time you get to CourseList Activity from CourseDetail, the adapter will be null again. No previously received data will be available. Is this what you really want?
The problem is you are not adding the newly added items to the List.So before setting adapter you have to add all your objects like
list.add(c);
I have a activity that extends listactivity, extended in this class i have a class that extends baseadapter.
now in my listactivity i have this onCreate
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new BuildingAdapter(this));
final ProgressDialog loading = new ProgressDialog(this);
loading.setProgressStyle(ProgressDialog.STYLE_SPINNER);
loading.setTitle("Laddar");
loading.setMessage("Hämtar data från servern");
loading.show();
new AsyncTask<Void, Void, DataPacket.Data>()
{
#Override
protected DataPacket.Data doInBackground(Void... params){
return ServerConnection.getBuildings();
}
#Override
protected void onPostExecute(DataPacket.Data param) {
((MainenanceApplication)getApplication()).setDataStructure(param);
loading.dismiss();
//((BuildingAdapter)getListAdapter()).notifyDataSetChanged();
setListAdapter(new BuildingAdapter(BuildingSelectionActivity.this));
}
}.execute();
}
This works as it's supposed to, but my question is in onPostExecute I update the datastructure that the list adapter uses.
Why cant I just call notifyDataSetChanged ??
If I have that line the view does not update itself, but if I use the line under where I do setListAdapter, it all works.
If the adapter is already set, setting it again will not refresh the listview. Instead first check if the listview has a adapter and then call the appropriate method.
I think its not a very good idea to create a new instance of the adapter while setting the list view. Instead, create an object.
BuildingAdapter adapter = new BuildingAdapter(context);
if(getListView().getAdapter() == null){ //Adapter not set yet.
setListAdapter(adapter);
}
else{ //Already has an adapter
adapter.notifyDataSetChanged();
}
Have you tried using an AsyncTaskLoader instead of an AsyncTask for this. It's this kind of stuff that Loaders were exactly designed for. Note that even though Loaders weren't available until API-10 you can still easily access them via the android Support Pacakge from API-4 and up.
The only place you can update the UI is in onProgressUpdate(...);. From your doInBackground(...), call publishProgress(...).