I want to update my listview during every new item add to my arraylist during progress dialog showing this is my code
public class Load extends AsyncTask<Void, Void, Void> {
ProgressDialog progress;
#Override
protected void onPreExecute() {
progress = new ProgressDialog(SearchList.this);
progress.setMessage("loading....");
progress.show();
}
#Override
protected Void doInBackground(Void... params) {
// do tracks loading process here, don't update UI directly here
// because there is different mechanism for it
//FlowableBookViewer.webview.loadUrl("javascript:(function(){var txt = window.getSelection();window.name= txt;window.cpjs.sendToAndroid(window.name);})()");
for (int i = 0; i < Globals.currenHtmlList.size(); i++) {
try {
String pageText = FunctionsClass
.readTextFromHtml(Globals.currenHtmlList.get(i));
if (pageText.toLowerCase().contains(
Globals.SelectedText.toLowerCase())) {
String pagename = new File(
Globals.currenHtmlList.get(i)).getName();
SearchItem sitem = new SearchItem();
sitem.setTargetList(Globals.currenHtmlList.get(i));
sitem.setPageNumber(i);
if (pagename.endsWith("html")) {
pagename = pagename.substring(0,
pagename.length() - 5);
} else if (pagename.endsWith("htm")) {
pagename = pagename.substring(0,
pagename.length() - 4);
} else if (pagename.endsWith("xhtml")) {
pagename = pagename.substring(0,
pagename.length() - 6);
}
sitem.setTitleList("Page " + pagename);
founded.add(sitem);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// write display tracks logic here
progress.dismiss(); // dismiss dialog
m_adapter = new OrderAdapter(SearchList.this, R.layout.itemview,
founded);
lv.setAdapter(m_adapter);
lv.setTextFilterEnabled(true);
}
}
in this code the listview items appears after the complete of the for loop which add all the items of sitem object to founded list i want to update listview at every item added to founded .
many thanks
1) Create the adapter before you call the AsyncTask
Move this to your activity/fragment onCreate method:
m_adapter = new OrderAdapter(SearchList.this, R.layout.itemview,
founded);
lv.setAdapter(m_adapter);
lv.setTextFilterEnabled(true);
2) After you add an item in your ArrayList call the onProgressUpdate from the AsyncTask
In your doInBackground method add:
founded.add(sitem);
publishProgress();
3) In the onProgressUpdate method call the notifyDatasetChanged method from your adapter
#Override
protected void onProgressUpdate(Void... v) {
super.onProgressUpdate(v);
m_adapter.notifyDataSetChanged();
}
You can read more about notifyDataSetChanged here.
Related
I want display progress bar in activity while loading data and when loading complete, progress bar to be hide (GONE)!
and try this code : (button click to load data)
private void allMoment() {
BTN_ALL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
TBL_MOMENT = new TableMoment(DB_HELPER);
// MOMENTS = TBL_MOMENT.MOMENT_LIST();
new loadTask().execute();
filterResult();
EDT_SEARCH.setText("");
} catch (Exception e) {
displaySnackBar(v, "خطا:" + "\n" + e.toString());
}
}
});
}
and Task method :
private class loadTask extends AsyncTask<String, Integer, Boolean> {
#Override
protected void onPreExecute() {
PROGRESS_LOADER.setVisibility(View.VISIBLE);
super.onPreExecute();
}
#Override
protected void onPostExecute(Boolean result) {
PROGRESS_LOADER.setVisibility(View.GONE);
adapter.notifyDataSetChanged();
super.onPostExecute(result);
}
#Override
protected Boolean doInBackground(String... params) {
MOMENTS = TBL_MOMENT.MOMENT_LIST();
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
and fill recycler with dapter :
private void filterResult() {
try {
adapter = new HistoryAdapter(this, MOMENTS);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
} catch (Exception e) {
displayToast(this, "خطای آداپتر:" + "\n" + e.toString());
}
}
but data become load and fill into recyclerview and don't show progress bar
how to fix this problem ?
You have :
new loadTask().execute();
filterResult();
EDT_SEARCH.setText("");
This execute() call returns inmediatly, if you execute an AsyncTask waiting for a result you don't have a result until AsyncTask.doInBackground() returns and AsyncTask.onPostExecuted() is called
Is this filterResult(); time consuming ? ... if the main UI thread is blocked then the UI will be not updated.
How do you want this progress bar to work? You can search for a gif on the Internet, once you find one that suits your criteria you have to display it when you open the activity. When you populate your recyclerView you set the visibility of the gif as GONE.
I have an AsyncTask that loads all my data on parse.com, then the user has a checkbox to select the categories he wants to display.
Once I get those choices (from a separate class via an interface), I reload the asyncTask, but It still lists everything (like if the array of choices gets erased/reloaded).
here is my code to get the selected categories :
#Override
public void onOkay(ArrayList<Integer> selected) {
StringBuilder stringBuilder = new StringBuilder();
if (selected.size() != 0) {
for (int i = 0; i < selected.size(); i++) {
String categories = selectedArray[selected.get(i)];
stringBuilder = stringBuilder.append(", " + categories);
}
//this is to display the content of the selectedArray :
Toast.makeText(this, "You have selected: "
+ stringBuilder.toString(), Toast.LENGTH_SHORT).show();
//reloading the AsyncTask class :
new RemoteDataTask().execute();
}
}
My AsyncTask :
private class RemoteDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//timer and progressdialog...
}
#Override
protected Void doInBackground(Void... params) {
list_of_articles = new ArrayList<Articles>();
try {
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
query.whereWithinKilometers("Localisation_Vendeur", device_location, rayon);
//this is the query I use :
query.whereContainedIn ("Category",Arrays.asList(selectedArray));
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("label1");
Articles map = new Articles();
map.setArticle_label1((String) article.get("label2"));
map.setArticle_label2((String) article.get("label3"));
map.setArticle_category((String) article.get("Category"));
map.setArticle_label4((String) article.get("label4"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
How can I make that work ? Keep in mind that the query works, i've tested with an array that i filled manually and it works.
Thanks.
You should pass categories that user wants to display as arguments to AsyncTask through AsyncTask.execute(Params... params). They will be available in AsyncTask.doInBackground method as that method parameters. Use them inside doInBackgorund method to set your query appropriately.
private class RemoteDataTask extends AsyncTask<List<String>, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//timer and progressdialog...
}
#Override
protected Void doInBackground(List<String>... params) {
list_of_articles = new ArrayList<Articles>();
try {
// Locate the class table named "Article" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Article");
query.whereWithinKilometers("Localisation_Vendeur", device_location, rayon);
//this is the query I use :
query.whereContainedIn ("Category", params[0]);
ob = query.find();
for (ParseObject article : ob) {
// Locate images in article_image column
ParseFile image = (ParseFile) article.get("label1");
Articles map = new Articles();
map.setArticle_label1((String) article.get("label2"));
map.setArticle_label2((String) article.get("label3"));
map.setArticle_category((String) article.get("Category"));
map.setArticle_label4((String) article.get("label4"));
map.setArticle_image(image.getUrl());
list_of_articles.add(map);
}
} catch (ParseException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this,
list_of_articles);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}
Then in code run AsyncTask by calling new RemoteDataTask().execute(Arrays.asList(selectedArray)). Make sure that selectedArray is updated properly before every call of AsyncTask.
There are two Activities. The first Activity is having the list view to see what is being shared and the second activity has an edit text box (to input inorder to share) and a button. On clicking the button, it returns me the string which is the json response and I need to add this in the previous activity.
Now the problem is, when I refresh the first page fully hitting the server it gets the response but this is not what I want. It should not go back to the server. It should simply add in the list view adapter.
I have commented the code in the PostExecute(). I have tried the everyway but it is not reflecting. I am also posting my code for your reference.
public class ShareAsyncTask extends AsyncTask<String, Void, ArrayList<EventsStreamBean>> {
public ProgressDialog pd = new ProgressDialog(EventStreamActivity.this);
String success_share_val;
#Override
protected ArrayList<EventsStreamBean> doInBackground(
String... result) {
// TODO Auto-generated method stub
JSONObject jsonobj = new JSONObject(result[0].toString());
success_share_val = jsonobj.getString(Constants.SUCCESS);
//checks the success value
if(success_share_val.equalsIgnoreCase("1")) {
JSONArray events_stream_share_array = jsonobj.getJSONArray("streamArray");
if(events_stream_share_array.length() > 0) {
for(int i=0; i<events_stream_share_array.length(); i++) {
EventsStreamBean events_stream_bean = new EventsStreamBean();
JSONObject events_stream_object = events_stream_share_array.getJSONObject(i);
events_stream_bean.setStreamId(events_stream_object.getString(Constants.STREAM_ID));
events_stream_bean.setStreamType(events_stream_object.getString(Constants.STREAM_TYPE));
events_stream_bean.setUserId(events_stream_object.getString(Constants.USER_ID));
events_stream_bean.setUserName(events_stream_object.getString(Constants.USER_NAME));
events_stream_bean.setUserType(events_stream_object.getString(Constants.USER_TYPE));
events_stream_bean.setUserAvatar(events_stream_object.getString(Constants.USER_AVATAR));
arraylist_events_stream.add(events_stream_bean);
}
}else {
Log.i("Test", "No Events Streams Available");
}
}
}catch(Exception e) {}
return arraylist_events_stream;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
this.pd.setMessage("Loading....");
pd.setCanceledOnTouchOutside(false);
pd.setCancelable(false);
this.pd.show();
}
#Override
protected void onPostExecute(final ArrayList<EventsStreamBean> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(this.pd.isShowing()) {
this.pd.dismiss();
}
Toast.makeText(EventStreamActivity.this, "Post shared successfully", Toast.LENGTH_SHORT).show();
new EventsStreamAsyncTask().execute(temp_val);
/*runOnUiThread(new Runnable() {
public void run() {
//EventStream_Customadapter adapter = (EventStream_Customadapter) list_view.getAdapter();
//adapter.clearData();
adapter.updateData(result);
//adapter = new EventStream_Customadapter(EventStreamActivity.this, arraylist_events_stream);
//list_view.setAdapter(adapter);
//adapter.notifyDataSetChanged();
}
});*/
}
}
Thank you
I have an AsyncTask which loads Tweets from Twitter.
I also have a PullToRefresh ListView... Whenever i pull to refresh it, the listview immediately clears and as soon as the data has been loaded, it's getting filled into the listview.
I have other ListViews in my App all with the same stuff (PullToRefresh and Async data loading...). On the other ListViews this does not happen. Only on the Twitter ListView. What am I doing wrong?
Here is my Code:
public class TwitterDownloader extends AsyncTask<Void, Void, String> {
final Handler mHandler = new Handler();
public TwitterDownloader() {
}
#Override
public void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
twitter4j.Twitter twitter = new TwitterFactory().getInstance();
listTweets.clear();
List<twitter4j.Status> statuses = null;
try {
statuses = twitter.getUserTimeline(
MainActivity.TWITTER_USERNAME, new Paging(1, 50));
} catch (TwitterException e) {
e.printStackTrace();
Log.e(MainActivity.LOG_TAG, "TwitterException");
}
try {
for (twitter4j.Status status : statuses) {
listTweets.add(status.getText());
}
} catch (NullPointerException npe) {
}
return null;
}
#Override
public void onPostExecute(String unused) {
MyCustomAdapter myAdapter = new MyCustomAdapter(myContext,
R.layout.row_twitter, listTweets);
setListAdapter(myAdapter);
getListView().setTextFilterEnabled(true);
String lastUpdate = (new SimpleDateFormat(
"HH:mm")).format(new Date());
pullToRefreshView.onRefreshComplete();
pullToRefreshView.setLastUpdatedLabel(getString(R.string.last_updated) + ": "
+ lastUpdate);
}
I am not sure about this but in doInBackground method of AsyncTask, you are doing listTweets.clear();. After getting result, you are adding data to it. May be this is causing problems.
I finally fixed it by adding all my clear() statements right before I fill up my list again (which is inside a try catch).
So the new code inside my doInBackground method is:
try {
listTweets.clear();
listUsernames.clear();
listDates.clear();
listImageURLs.clear();
listURLsOfTweets.clear();
for (twitter4j.Status status : statuses) {
listTweets.add(status.getText());
listUsernames.add(status.getUser().getName());
listDates.add(android.text.format.DateFormat
.getDateFormat(getApplicationContext()).format(
status.getCreatedAt())
+ " "
+ android.text.format.DateFormat.getTimeFormat(
getApplicationContext()).format(
status.getCreatedAt()));
listImageURLs.add(status.getUser().getProfileImageURL()
.toString());
StringBuffer address = new StringBuffer();
address.append("http://twitter.com/#!/");
address.append(status.getUser().getScreenName());
address.append("/status/");
address.append(status.getId());
listURLsOfTweets.add(address.toString());
}
I never got this working in a straightforward manner. Sorry if I'm being a little vague. I'll try to elaborate on what I'm trying to do. I am trying to build a listview that grabs its data from a webservice. Once I initialize a listview, I want to keep polling the webserver periodically and update the contents of the listview. For this I am doing something like this:
public class SampleAutoUpdateList extends Activity {
//Autoupdate handler
private Handler handler = new Handler();
private Runnable updater = new Runnable() {
public void run() {
/*
* Update the list
*/
try {
Log.i("UPDATE", "Handler called");
searchAdapter = getFeed(URL);
searchAdapter.notifyDataSetChanged();
handler.postDelayed(this, Configuration.REFRESH_INTERVAL);
} catch(Exception e) {
Log.e("UPDATE ERROR", e.getMessage());
}
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linearmode);
this.context = this;
searchAdapter = getFeed(URL);
LinearLayout l2 = (LinearLayout) findViewById(R.id.secondaryLayout);
ListView list = new ListView(context);
l2.addView(list);
// display UI
UpdateDisplay(list);
updater.run();
}
private SearchAdapter getFeed(String URL) {
try
{
SearchHandler handler = new SearchHandler();
URL url = new URL(URL);
String data = convertStreamToString(url.openStream());
data = data.substring(data.indexOf('['), data.length()-1);
handler.parseJSON(data);
return handler.getFeed();
}
catch (Exception ee)
{
// if we have a problem, simply return null
Log.e("getFeed", ee.getMessage());
return null;
}
}
private void UpdateDisplay(View searchView) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
searchList = (ListView) searchView;
myProgressDialog = ProgressDialog.show(this,
"Please wait...", "Loading search....", true);
new Thread() {
public void run() {
try{
Thread.sleep(2000);
} catch (Exception e) { }
runOnUiThread(new Runnable() {
#Override
public void run() {
if (searchAdapter == null)
{
Log.e("ERROR", "No Feed Available");
return;
}
searchAdapter.setContext(context);
searchList.setAdapter(searchAdapter);
searchList.setSelection(0);
}
});
// Dismiss the Dialog
myProgressDialog.dismiss();
}
}.start();
}
}
And the SearchHandler class is simple:
public class SearchHandler extends DefaultHandler {
SearchAdapter _adapter;
SearchItem _item;
public SearchHandler()
{
}
public SearchAdapter getFeed()
{
return _adapter;
}
public void parseJSON(String data) {
// TODO Auto-generated method stub
_adapter = new SearchAdapter();
JSONArray parseArray;
try {
parseArray = new JSONArray(data);
for (int i=0; i < parseArray.length(); i++) {
SearchItem item = new SearchItem();
JSONObject jsonUser = parseArray.getJSONObject(i);
item.set_from(jsonUser.getString ("from"));
item.set_msg(jsonUser.getString("msg"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
No matter what I do, the handler gets called and the new items are fetched, but the list is never refreshed... Any ideas on what could be going wrong?
Well, it is a little bit difficult to follow your code, since you only have a fragment of it, and few of the really relevant bits. For example, based on your available code, your list should be forever empty, since you never associate the searchAdapter with a ListView...at least in the code you have shown.
That being said, the following lines seem particularly odd:
searchAdapter = getFeed(URL);
searchAdapter.notifyDataSetChanged();
I am going to assume that getFeed() (not shown) creates a new ListAdapter of some sort. If getFeed() is creating a new ListAdapter, there is no need to call notifyDataSetChanged() on it, as its data set hasn't changed -- it's brand new. Moreover, unless you are associating this new ListAdapter to your ListView, the new ListAdapter will have no effect.
If I'm barking up the wrong tree, consider adding lines to your sample showing the implementation of getFeed() and where you are using searchAdapter.