I have problem with notifyDataSetChanged,i read some another post but can't help me and i have problem yet, i call that after my listview setadapter but mylist hasn't any change! this is my code, please help me, Thanks
public class PostDataAsyncTask extends AsyncTask<String, String, String> {
// this will post our text data
protected void onPreExecute() {
super.onPreExecute();
// do stuff before posting data
}
#Override
protected String doInBackground(String... strings) {
try {
postTextandGetRespons("http://demo.codeofaninja.com/tutorials/json-example-with-php/index.php");
JSONObject JsonOb = new JSONObject(responseString);
JSONArray messages = JsonOb.getJSONArray("Users");
for ( int i=0; i<= f;i++){
JSONObject c = messages.getJSONObject(i);
firstname = c.getString("firstname");
lastname = c.getString("lastname");
username = c.getString("username");
items.add(new item(firstname,lastname,username));
}
adapter.notifyDataSetChanged();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String responseStr) {
if ( setAdapter == true) {
lv = (ListView) findViewById(R.id.listView_asabani);
adapter = new adapter_common(getBaseContext(), items);
lv.setAdapter(adapter);
setAdapter = false;
}
}
}
Move adapter.notifyDataSetChanged(); to onPostExecute() that's where UI code should run.
Related
Hello guys I am doing the delete function in my project and it seems that the notifyDataSetChanged is not working. I've already done some research about this but I don't quiet understand
here is my code in onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_dropped_student);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
SharedPreferences preferences = getSharedPreferences("MyApp", MODE_PRIVATE);
subj_code = preferences.getString("code", "UNKNOWN");
subj_code_lab = preferences.getString("code_lab", "UNKNOWN");
studentList = new ArrayList<HashMap<String, String>>();
mylistView = (ListView) findViewById(R.id.list);
arrayAdapter = new StudAdapter(this, stud_List);
mylistView.setAdapter(arrayAdapter);
new LoadStudent().execute();
mylistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final String studentId = ((TextView) (view.findViewById(R.id.stud_id))).getText().toString();
final String studentName = ((TextView) (view.findViewById(R.id.studName))).getText().toString();
class AttemptGetData extends AsyncTask<String, String, String>{
String code = subj_code.toString();
String id = studentId;
String stud_name = studentName;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ViewDroppedStudent.this);
pDialog.setMessage("In Progress...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
JSONParser jsonParser = new JSONParser();
String url = null;
try {
url = "http://192.168.22.3/MobileClassRecord/undroppedStudent.php?stud_id="+ URLEncoder.encode(id, "UTF-8")+"&subj_code="+ URLEncoder.encode(subj_code, "UTF-8");
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
List<NameValuePair> mList = new ArrayList<NameValuePair>();
mList.add(new BasicNameValuePair("stud_id", id));
mList.add(new BasicNameValuePair("subj_code", code));
JSONObject jsonObject = jsonParser.makeHttpRequest(url, "POST", mList);
Log.d("Undrop Student", jsonObject.toString());
try {
verify = jsonObject.getString("Message");
return verify;
}catch (JSONException e){
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pDialog.dismiss();
if (s != null){
Toast.makeText(getApplicationContext(), verify, Toast.LENGTH_LONG).show();
}
}
}
final MaterialDialog materialDialog = new MaterialDialog(ViewDroppedStudent.this);
materialDialog.setTitle("Undrop Student");
materialDialog.setMessage("Name: " + studentName);
materialDialog.setPositiveButton("UNDROP", new View.OnClickListener() {
#Override
public void onClick(View v) {
materialDialog.dismiss();
new AttemptGetData().execute();
arrayAdapter.notifyDataSetChanged();
}
}).setNegativeButton("CANCEL", new View.OnClickListener() {
#Override
public void onClick(View v) {
materialDialog.dismiss();
}
});
materialDialog.show();
}
});
}
any help would be much appreciated :)
You need to write arrayAdapter.notifyDataSetChanged(); in onPostExecute method
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pDialog.dismiss();
if (s != null){
Toast.makeText(getApplicationContext(), verify, Toast.LENGTH_LONG).show();
}
arrayAdapter.notifyDataSetChanged();
}
Remove perticular data from your stud_List
put arrayAdapter.notifyDataSetChanged(); in onPostExecute()
It is possible that sometime notifiDatasetChanged not works with custom adapter.
you can create custom method in your adapter like below :
public void refresh(ArrayList<HashMap<String, String>> list)
{
this.list=list; //replace this.list with your adapter list variable.
notifyDataSetChanged();
}
call it in onPostExecute()
arrayAdapter.refresh(stud_List);
Your asynctask runs asyncronously so when you call execute() on asynctask it will run in a parallel thread while the execution of main thread continues. So your notifydatasetchanged() is getting called even before your asynctask() is finished. So call notifyDataSetChanged() inside onPostExecute()
In the code below, the list view does not show the text getting from RSS Feed:
public class MainActivity extends ListActivity {
ArrayList<String> values = new ArrayList<>();
ArrayList<String> tags = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
URL url = new URL("http://appline.ir/index.php/android.feed?limitstart=");
new Connect(url).execute();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class Connect extends AsyncTask <Void, String, String>
{
URL url;
ProgressDialog diao;
Connect(URL url)
{
this.url = url;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
diao.hide();
setListAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, values));
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
diao = new ProgressDialog(MainActivity.this);
diao.setMessage("connecting...");
diao.setIndeterminate(true);
diao.show();
}
#Override
protected String doInBackground(Void... params)
{
try
{
XmlPullParserFactory parser =XmlPullParserFactory.newInstance();
XmlPullParser xml = parser.newPullParser();
URL url = new URL("http://appline.ir/index.php/android.feed?limitstart=");
XmlParser p = new XmlParser(url);
tags = p.parse();
InputStream input = url.openStream();
xml.setInput(input,null);
int event;
String text = null;
try {
event = xml.getEventType();
while (event != XmlPullParser.END_DOCUMENT)
{
String name=xml.getName();
switch (event)
{
case XmlPullParser.START_TAG:
break;
case XmlPullParser.TEXT:
text = xml.getText();
break;
case XmlPullParser.END_TAG:
if(name.equals("title")){
values.add(text);
}
else if(name.equals("link")){
// link = text;
}
else if(name.equals("description")){
// description = text;
}
else{
}
break;
}
event = xml.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
catch(Exception e)
{
}
return null;
}
}
}
but when I put Xml parsing part into the MainActivity (using StrictMode), the list shows the text properly.
I cannot find the problem. How can this be fixed?
You must call notifyDataSetChanged() on your Adapter and you must call it in your UI main thread
Try assigning the adapter object to a variable and call notifyDataSetChanged()
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MyActivity.this, android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
adapter.notifyDataSetChanged();
I have a list fragment. When I run the app, I see an empty listView.
I don't know what the problem is. Maybe I should use a library?
public class MyEmployeFragment extends ListFragment {
private static final String ATTRIBUTE_ID = "p_id";
private static final String ATTRIBUTE_NAME = "p_name";
private static final String ATTRIBUTE_LAST_NAME = "p_last_name";
ArrayList<spr_item> ret_data;
MyTask task;
SimpleAdapter sAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
task = new MyTask();
task.execute();
return inflater.inflate(R.layout.my_employe, null);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ret_data = new ArrayList<spr_item>();
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(
ret_data.size());
Map<String, Object> m;
for (int i = 0; i < ret_data.size(); i++) {
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_ID, ret_data.get(i).getId());
m.put(ATTRIBUTE_NAME, ret_data.get(i).getName());
m.put(ATTRIBUTE_LAST_NAME, ret_data.get(i).getLastName());
data.add(m);
}
// массив имен атрибутов, из которых будут читаться данные
String[] from = {ATTRIBUTE_ID, ATTRIBUTE_NAME, ATTRIBUTE_LAST_NAME};
// массив ID View-компонентов, в которые будут вставлять данные
int[] to = {R.id.tw_employe_id, R.id.tw_employe_name, R.id.tw_employe_last_name};
// создаем адаптер
sAdapter = new SimpleAdapter(getActivity(), data, R.layout.list_item_employee,
from, to);
// определяем список и присваиваем ему адаптер
ListView lvSimple = (ListView) getView().findViewById(android.R.id.list);
lvSimple.setAdapter(sAdapter);
}
class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
String s = "5ACACEC6-752B-4EFF-AA50-EEBE58A52113";
// String user_guid = myPrefs.getString("guid", "");
HttpActivity _http = new HttpActivity("192.168.10.11", "80");
_http.set_addr_protocol("/WebSite/P/spr/spr.aspx/");
_http.add_param("query", "spr_employee_get");
// _http.add_param("p_guid", user_guid.toString().trim());
_http.add_param("p_guid", s);
_http.send();
List<spr_item> tempList = _http.getArrayParamValue();
for(int i = 0; i < tempList.size(); i++)
ret_data.add(tempList.get(i));
//employer_name = _http.getArrayParamValue("p_name");
//employer_id = _http.getArrayParamValue("p_id");
//employer_last_name = _http.getArrayParamValue("p_last_name");
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
sAdapter.notifyDataSetChanged();
}
}
}
With the above code apart from the Empty list you may have the null pointer exception too if the task is too quick to load. Here onCreate is called first onCreateView next and onActvityCreated next. So it is better to initialise adapter in onCreate set the adapter to listView in onCreateView and set listView listeners in onActvityCreated using getListView() method.
Apart from this if you are using local database to retrieve data you need to use cursorADapter to fetch the data
The adapter's data references (ArrayList, array, etc.), tend to get lost pretty easily. In that case the notfiyDataSetChanged() method will not work. If you are adamant on using this method I suggest you check the references to the adapter's source again. If that is not the case this is the approach I've used in my project. A small warning in advance, the formatting and the closing of brackets is poorly executed, but the approach is still clear enough.
public class MyFragment extends ListFragment {
// For populating the list view.
SomeAdapter adapter;
public MyFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] parameters = {"url for request"};
new GetRequestTask().execute(parameters);
}
// The async task to make the HTTP GET requests.
class GetRequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.e("GetRequestTask", "Client protocol exception.");
e.printStackTrace();
} catch (IOException e) {
Log.e("GetRequestTask", "IO exception.");
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Update UI with the new response.
new UpdateUITask().execute(result);
}
}
}
// The async task to update the UI.
class UpdateUITask extends AsyncTask<String, String, ArrayList<Something>>{
#Override
protected ArrayList<Something> doInBackground(String... input) {
ArrayList<Something> someArray = new ArrayList<Something>();
try{
// Do some JSON magic to parse the data.
}
catch(JSONException je){
Log.e("UpdateUITask", "JSON parsing error occured.");
je.printStackTrace();
}
return someArray;
}
#Override
protected void onPostExecute(ArrayList<Something> result) {
super.onPostExecute(result);
Log.i("UpdateUITask", "Updating UI.");
adapter = new SomeAdapter(getActivity(), R.layout.some_list_item, restOfTheParameters);
setListAdapter(adapter);
}
}
}
}
getting data from webservices but values not getting out of async class,
public class Settings extends PreferenceActivity{
ListPreference lst1;
public static String[] batcharr;
public static String[] streamarr;
public Settings(){
// TPGetListone getlist = new TPGetListone();
// getlist.execute();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings);
lst1 = (ListPreference) findPreference("prefStream");
TPGetListone getlist = new TPGetListone();
getlist.execute();
lst1.setEntries(batcharr);
lst1.setEntryValues(batcharr);
}
public class TPGetListone extends AsyncTask<String, Void, Void> {
String datax = "";
JSONArray array;
List<String> lstbatch;
List<String> lststream;
private String LogStr = "Panchratna";
#Override
protected Void doInBackground(String... params) {
DataHelper gd = new DataHelper("http://xxxx.com/EventGetter","http://xxxx.com/EventGetter.asmx?wsdl","http://xxxx.com/EventGetter/GetCourseList","GetCourseList");
datax = gd.GetData("query","SELECT batch, stream FROM batch");
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
Log.i(LogStr, "onPostExecuteCATALOG");
try {
array = new JSONArray(datax);
} catch (JSONException e) {
e.printStackTrace();
}
lstbatch = new ArrayList<String>();
lststream = new ArrayList<String>();
for(int i = 0; i < array.length(); i++){
try {
lstbatch.add(array.getJSONObject(i).getString("batch"));
lststream.add(array.getJSONObject(i).getString("stream"));
} catch (JSONException e) {
e.printStackTrace();
}
}
batcharr = new String[lstbatch.size()];
streamarr = new String[lststream.size()];
for (int i=0;i<lststream.size();i++){
lststream.toArray(batcharr);
lstbatch.toArray(streamarr);
}
}
#Override
protected void onCancelled(Void aVoid) {
super.onCancelled(aVoid);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
}
i know this is not a proper way,
i m using webservices to fetch json values and convert it to list<>
by debugging, values do come in List which is lstbatch and lststream,
and array batcharr and streamarr ,
but when the task executes , in on create method , batcharr and streamarr is showing error,
same method worked last time on an Activity
Please help ,
Thank You
Move this code above the Async and it will be accessible
List<String> lstbatch;
List<String> lststream;
public class TPGetListone extends AsyncTask<String, Void, Void> {
String datax = "";
JSONArray array;
//--> Remove to Up -->List<String> lstbatch;
//--> Remove to Up -->List<String> lststream;
private String LogStr = "Panchratna";
EDIT
for (int i=0;i<lststream.size();i++){
batcharr[i]=lststream.get(i);
streamarr[i]=lstbatch.get(i);
}
put this code
lst1.setEntries(batcharr);
lst1.setEntryValues(batcharr);
in
PostExecute method
protected void onPostExecute(Void aVoid) {
Log.i(LogStr, "onPostExecuteCATALOG");
try {
array = new JSONArray(datax);
} catch (JSONException e) {
e.printStackTrace();
}
lstbatch = new ArrayList<String>();
lststream = new ArrayList<String>();
for(int i = 0; i < array.length(); i++){
try {
lstbatch.add(array.getJSONObject(i).getString("batch"));
lststream.add(array.getJSONObject(i).getString("stream"));
} catch (JSONException e) {
e.printStackTrace();
}
}
batcharr = new String[lstbatch.size()];
streamarr = new String[lststream.size()];
for (int i=0;i<lststream.size();i++){
lststream.toArray(batcharr);
lstbatch.toArray(streamarr);
}
===> lst1.setEntries(batcharr);
===> lst1.setEntryValues(batcharr);
}
I was using AsyncTask to display data on a List, But the loading is visible, but it dosen't show the list..
public void getLocations(){
Connect client = new Connect(SERVICE_URI + "/GetLocations");
client.AddHeader("Accept", "application/json");
client.AddHeader("Content-Type", "application/json");
try {
client.Execute(RequestMethod.GET);
JSONObject rootJson = new JSONObject(client.getResponse());
JSONArray jsonArray = rootJson.getJSONArray("GetLocationsResult");
String[] names = null;
if (jsonArray != null) {
names = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
names[i] = json.getString("Name");
}
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names));
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getLocations(){
Connect client = new Connect(SERVICE_URI + "/GetLocations");
client.AddHeader("Accept", "application/json");
client.AddHeader("Content-Type", "application/json");
try {
client.Execute(RequestMethod.GET);
JSONObject rootJson = new JSONObject(client.getResponse());
JSONArray jsonArray = rootJson.getJSONArray("GetLocationsResult");
String[] names = null;
if (jsonArray != null) {
names = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
names[i] = json.getString("Name");
}
}
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names));
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
If data for ListAdapter is collected in doInBackground() of AsyncTask, Activity onCreate() does not wait for AsyncTask to complete.
So what we have:
1. Activity Start
2. AsyncTask start
3. Activity trying to set ListAdapter - it's empty, because AsyncTask does not completed
4. AsyncTask completed - but ListAdapter filled with empty data
My solution: AsyncTask should notify ListAdapter of Activity after data loading completes:
Public class MyActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myActivity);
ExpandableListView listView = (ExpandableListView) findViewById(R.id.expList);
//MyArrayList - data source for your list. For example, I use static ArrayList from other class. Replace with your data object.
final MyExpandableListAdapter adapter = new MyrExpandableListAdapter(getApplicationContext(), myArrayList);
listView.setAdapter(adapter);
int taskId=1; // type of task should be executed
MyAsyncTask myTask = new MyAsyncTask(taskId);
myTask.execute(adapter);
#Override
protected Dialog onCreateDialog(int id) {
ProgressDialog progress = null;
progress = new ProgressDialog(this);
//Should user work with app while data loading? In my case, no, so setCancelable=false
progress.setCancelable(false);
if (id==1) {
progress.setMessage("Getting locations, please wait...");
}
if (id==2) {
progress.setMessage("Task type #2 performing...");
}
return progress;
} // end onCreateDialog
class MyAsyncTask extends AsyncTask<Void, Void, Void> {
MyExpandableListAdapter adapter; //ExpandableListAdapter you wanna notify about data load completion
int taskId; //Type of tasks in your Activity. You have only one, however - getLocations().
MyAsyncTask(int taskId) {
//save task ID to use in doInBackground, showDialog and dismissDialog
this.taskId=taskId;
}
#Override
protected Void doInBackground(Void... params) {
if (taskId==1) {
// YOUR LONG-TIME TASK #1 THAT UPDATES DATA SOURCE FOR LIST ADAPTER GOES HERE;
}
if (taskId==2) {
// YOUR LONG-TIME TASK #2 THAT UPDATES DATA SOURCE FOR LIST ADAPTER GOES HERE;
// create more task types if needed
}
//this adapter will be used in onPostExecute() to notify Activity about data changes
adapter = (MyExpandableListAdapter) params[0];
return null;
}
#Override
protected void onPreExecute() {
//Show dialog for this task type. if need more than one - us switch here and in onCreateDialog,
// different dialog types for different tasks etc.
showDialog(taskId);
}
#Override
protected void onPostExecute(Void result) {
// IMPORTANT! Update data in Activity
adapter.notifyDataSetChanged();
dismissDialog(taskId);
}
} //end of AsyncTask
} //end of Activity class