I'm trying to achieve the following:
Screen 1 shows list data from server
User presses "+" button on top right to add a new item
Screen 2 shows with text field
User enters data and clicks save
Now I want to go back to Screen 1 and refresh the list from server so that the newly added item shows up
I'm having problems achieving point 5 above. This is what I have so far:
I have an AyncTask like following:
public class MyActivity extends SherlockListActivity {
ArrayList<HashMap<String, String>> taskList;
//this grabs data from server and loads it in ArrayList
protected void loadList() {
taskList = new ArrayList<HashMap<String, String>>();
final RestAdapter restAdapter = new RestAdapter.Builder().setServer("http://10.0.2.2:8080").build();
final TaskService apiManager = restAdapter.create(TaskService.class);
final Task task = apiManager.getTask("someuser", task_id);
for (Item item : task.getItems()) {
String t_id = t.getId()+"";
String name = t.getName();
HashMap<String, String> map = new HashMap<String, String>();
map.put("act_id", act_id);
map.put("t_id", t_id);
map.put("t_name", name);
taskList.add(map);
}
}
public void onCreate (Bundle b) {
new LoadItems().execute();
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getTitle().equals("Create")) {
Intent create = new Intent(getApplicationContext(), CreateTask.class);
startActivityForResult(create, 1);
return true;
}
return true;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
//item got added now load again from server
if (resultCode == RESULT_OK) {
String result = data.getStringExtra("result");
new UpdateItems.execute();
adapter.notifyDataSetChanged();
}
}
}
class UpdateItems extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
loadList();
return null;
}
}
class LoadItems extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
loadList();
}
protected void onPostExecute(String file_url) {
adapter = new SimpleAdapter(
MyActivity.class, taskList,
R.layout.list_item_rec, new String[] { "act_id", "t_id", "t_name"}, new int[] {
R.id.act_id, R.id.t_id,R.id.t_name });
setListAdapter(adapter);
}
}
Question
How can I reload the data from the server in onActivityResult. Based on above, what I'm doing is creating another AynchTask only for loading the data again and then calling notifyDataSetChanged(). This doesn't seem to be working.
Is my process wrong? Is there a better way to do this? I am stumped....
You have to reload the data in UpdateItems onPostExecute() method..because you are loading data in AsynchTask it loads data in another thread and updating the ListView but the list is not loaded at that time..so change your AsynchTask like this..
class UpdateItems extends AsyncTask<String, String, String> {
protected String doInBackground(String... args) {
loadList();
return null;
}
#Override
protected void onPostExecute(String result) {
adapter.notifyDataSetChanged();
}
}
and remove this line adapter.notifyDataSetChanged() in onActivityResult()
Related
I am trying to show an ArrayList in ListView using a RecyclerView. But its giving me error an in onPostExecute method when I pass the ArrayList and the Context.
My code is as follows,
class LoadAlltimeTable extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
JSONHttpClient jsonHttpClient = new JSONHttpClient();
UserModel[] user = jsonHttpClient.Get(ServiceUrl.TiMETABLE, nameValuePairs, UserModel[].class);
if (user.length > 0) {
arrayList= new ArrayList<UserModel>();
for (UserModel product : user) {
final TestModel obj= new TestModel();
obj.setName(product.getName());
newList.add(obj);
runOnUiThread(new Runnable(){
#Override
public void run(){
//update ui here
// display toast here
Toast.makeText(TimeTable.this, "Not Null "+ newList.size()+""+obj.getName(), Toast.LENGTH_SHORT).show();
}
});
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(TimeTable.this);
progressDialog.setMessage("Loading----");
progressDialog.show();
}
#Override
protected void onPostExecute(String s) {
progressDialog.dismiss();
//here i am getting error
adapter=new TimeTableAdapter(newList,getApplicationContext());
rv.setAdapter(adapter);
}
}
Here is my adapter code,
public class TimeTableAdapter extends RecyclerView.Adapter<TimeTableAdapter.ContactViewHolder> {
ArrayList<TestModel> list;
Activity activity;
public TimeTableAdapter(ArrayList<TestModel> list, Activity activity) {
this.list = list;
this.activity = activity;
}
}
Try using getActivity() instead of getApplicationContext(). Your code should look like:
adapter = new TimeTableAdapter(newList, getActivity());
Explanation:
You're probably getting an error because your constructor goes like:
public TimeTableAdapter(ArrayList<TestModel> list, Activity activity) {
this.list = list;
this.activity = activity;
}
It needs your ArrayList of objects as well as an activity. However, in your fragment, you go with:
adapter = new TimeTableAdapter(newList, getApplicationContext());
What you are giving it is NOT an activity but your fragment class. This gives off an error (I forgot which one) because you're giving it a fragment class instead of an activity class. Hence, you need to use getActivity() instead of getApplicationContext().
I am able to successfully download all files from aws s3 bucket, so when I click on the particular list item the list item gets download. But, I want all s3 bucket item automatically download when activity is launched.
/**
* DownloadSelectionActivity displays a list of files in the bucket. Users can
* select a file to download.
*/
public class DownloadSelectionActivity extends ListActivity {
// The S3 client used for getting the list of objects in the bucket
private AmazonS3Client s3;
// An adapter to show the objects
private SimpleAdapter simpleAdapter;
private ArrayList<HashMap<String, Object>> transferRecordMaps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download_selection);
initData();
initUI();
}
#Override
protected void onResume() {
super.onResume();
// Refresh the file list.
new GetFileListTask().execute();
}
private void initData() {
// Gets the default S3 client.
s3 = Util.getS3Client(DownloadSelectionActivity.this);
transferRecordMaps = new ArrayList<HashMap<String, Object>>();
}
private void initUI() {
simpleAdapter = new SimpleAdapter(this, transferRecordMaps,
R.layout.bucket_item, new String[] {
"key"
},
new int[] {
R.id.key
});
simpleAdapter.setViewBinder(new ViewBinder() {
#Override
public boolean setViewValue(View view, Object data,
String textRepresentation) {
switch (view.getId()) {
case R.id.key:
TextView fileName = (TextView) view;
fileName.setText((String) data);
return true;
}
return false;
}
});
// When an item is selected, finish the activity and pass back the S3
// key associated with the object selected
getListView().setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(final AdapterView<?> adapterView, View view, int pos, long id) {
Intent intent = new Intent();
intent.putExtra("key", (String) transferRecordMaps.get(pos).get("key"));
setResult(RESULT_OK, intent);
finish();
}
});
}
/**
* This async task queries S3 for all files in the given bucket so that they
* can be displayed on the screen
*/
private class GetFileListTask extends AsyncTask<Void, Void, Void> {
// The list of objects we find in the S3 bucket
private List<S3ObjectSummary> s3ObjList;
// A dialog to let the user know we are retrieving the files
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(DownloadSelectionActivity.this,
getString(R.string.refreshing),
getString(R.string.please_wait));
}
#Override
protected Void doInBackground(Void... inputs) {
// Queries files in the bucket from S3.
s3ObjList = s3.listObjects(Constants.BUCKET_NAME).getObjectSummaries();
transferRecordMaps.clear();
for (S3ObjectSummary summary : s3ObjList) {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("key", summary.getKey());
transferRecordMaps.add(map);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
dialog.dismiss();
simpleAdapter.notifyDataSetChanged();
}
}
}
You already have the list of objects in the bucket, you could just iterate through the list and download each one when the list operation has completed. It might be easier to handle the transfers (allowing pause/resume, checking status, ect...) using the Transfer Utility, which is a high level utility on top of the standard S3 Client.
A guide for the Transfer Utility can be found here (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/s3transferutility.html)
I have an android fragment which contains an android AsyncTask class implemented as follows
protected class getGraph extends
AsyncTask<GraphFragment, Void, GraphFragment> {
#Override
protected GraphFragment doInBackground(GraphFragment... params) {
performance = getPerformance(sharename);
return null;
}
protected void onPostExecute(GraphFragment Param) {
}
}
Now i want to return the value performance which is an ArrayList to the calling method.How do i achieve that?
Try this:
(replace "String" with whatever native variable type your data is)
protected class getGraph extends
AsyncTask<GraphFragment, Void, List<String>> {
List<String> performance = new ArrayList<String>();
#Override
protected GraphFragment doInBackground(GraphFragment... params) {
performance = getPerformance(sharename);
return null;
}
protected void onPostExecute(List<String> Param) {
}
}
Use following code.
public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(baraj_mapa.this);
dialog.setTitle("Calculating...");
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
dialog.show();
}
protected ArrayList<String> doInBackground(ArrayList<String>... passing) {
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> passed = passing[0]; //get passed arraylist
// Assign data to your Arralist from your method
result = getData();
//Some calculations...do your stuff here.
return result; //return result arraylist
}
protected void onPostExecute(ArrayList<String> result) {
dialog.dismiss();
// Get your arraylist here.
}
Take this aproach
protected class getGraph extends
AsyncTask<GraphFragment, Void, ArrayList<YOUROBJECT> {
#Override
protected ArrayList<YOUROBJECT> doInBackground(GraphFragment... params) {
performance = getPerformance(sharename);
return performance;
}
public void onPostExecute( ArrayList<YOUROBJECT> Param) {
}
}
In your other Class/MainActivity call it this way:
private void getSomething(){
new getGraph({
#Override
void onPostExecute(ArrayList<YOUROBJECT> Param){
//DO SOMETHING IN MAINACTIVITY
}
}).execute();
}
Do this way..
protected class getGraph extends
AsyncTask<GraphFragment, Void, ArrayList<String> {
#Override
protected GraphFragment doInBackground(GraphFragment... params) {
performance = getPerformance(sharename);
ArrayList<String> DATA=new ArrayList<String>();
/*
do the process and assign result in DATA
*/
return DATA;
}
protected void onPostExecute( ArrayList<String> Param) {
// Get your arraylist here.
}
}
in my app im using gridview
when in portrait mode it shows one column.
in landscape mode new layout defined to show 2 column.
this is how the app works..
when app is launched, progress dialog is called to load website name from sqlite database and async is used to load website from sqlite db. the progress dialog is dismissed after the gridview is inflated.
now after loading the website name into gridview the screen orientation changes, it restarts the progress dialog.
i know that on screen orientation change the ondestroy() and then oncreate() are called.
this is my app's src code.
public class RSSReaderActivity extends Activity {
private ProgressDialog pDialog;
ArrayList<HashMap<String, String>> rssFeedList;
RSSParser rssParser = new RSSParser();
RSSFeed rssFeed;
Button add_rss;
// array to trace sqlite ids
String[] sqliteIds;
public static String TAG_ID = "id";
public static String TAG_TITLE = "title";
public static String TAG_LINK = "link";
GridView gridview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.site_list);
add_rss = (Button) findViewById(R.id.add_rss);
gridview = (GridView) findViewById(R.id.gridview);
rssFeedList = new ArrayList<HashMap<String, String>>();
new loadStoreSites().execute();
gridview.setOnItemClickListener(new OnItemClickListener() {
...
...
);
add_rss.setOnClickListener(new View.OnClickListener() {
...
...
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// if result code 100
if (resultCode == 100) {
// reload this screen again
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
class loadStoreSites extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
...
...
}
#Override
protected String doInBackground(String... args) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
RSSDatabaseHandler rssDb = new RSSDatabaseHandler(getApplicationContext());
// listing all websites from SQLite
List<WebSite> siteList = rssDb.getAllSites();
sqliteIds = new String[siteList.size()];
// loop through each website
for (int i = 0; i < siteList.size(); i++) {
WebSite s = siteList.get(i);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, s.getId().toString());
map.put(TAG_TITLE, s.getTitle());
map.put(TAG_LINK, s.getLink());
// adding HashList to ArrayList
rssFeedList.add(map);
// add sqlite id to array
// used when deleting a website from sqlite
sqliteIds[i] = s.getId().toString();
}
gridview.setAdapter(new SimpleAdapter(RSSReaderActivity.this,rssFeedList, R.layout.site_list_row,new String[] { TAG_ID, TAG_TITLE, TAG_LINK },new int[] { R.id.sqlite_id, R.id.title, R.id.link }));
registerForContextMenu(gridview);
}
});
return null;
}
protected void onPostExecute(String args) {
// dismiss the dialog after getting all products
pDialog.dismiss();
}
}
}
SO how do we use onsavedinstance() over here.. please can anyone guide me.
add this in menifest file
android:configChanges="keyboardHidden|orientation|screenSize"
I have a requirement where i need to parse the content of a URL in JSON format. I am able to do that successfully. But i need to save the contents of the URL in a array list and pass them back to the calling functions. Below is the code snippet of what i am trying to achieve.
#Override
protected ArrayList<String> onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
return ar; // ar is the arraylist i have created and updated it with the content of the url.
}
But running this gives an error. Can anyone please suggest how i can make this possible. However, when i make the return type of onPostExecute as void and toast the contents, its displaying properly. When i call this after the execute, its returning null even though i have updated the contents in doinbackground(). Hence i am unable to get the return values on arraylist format.
// Calling function
Myadapter.execute();
ArrayList<string> str = new ArrayList<string>();
str = print();
// Here str is getting null
// Called function
public ArrayList<String> print() {
ArrayList<String> names = new ArrayList<String>();
for(int i=0;i<al.size();i++)
{
names.add(al.get(i).getConstituencyName());
}
return names;
}
Use a handler
In your activity
mHandler = new Handler() {
#Override public void handleMessage(Message msg) {
ArrayList s=(ArrayList)msg.obj;
tv.setText("Result = "+s.get(0));
}
};
In your onPostexecute
Message msg=new Message();
msg.obj=ar;
mHandler.sendMessage(msg);
The proper way would be to let your activity implement an interface, and when you instantiate the AsyncTask pass the current activity as a parameter to the constructor. Then in onPostExecute() invoke the callback method defined in the Activity and pass the json result as an argument.
Something like this:
interface OnTaskFinished {
void onTaskFinished(String result);
}
public class MainActivity extends Activity implements OnTaskFinished {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ....
new MyAsyncTask(this).execute();
}
#Override
public void onTaskFinished(String result) {
// Process the json result here how you need.
}
}
And this is how the scheleton of your AsyncTask should look like:
private class MyAsyncTask extends AsyncTask<Void, Void, String> {
private final OnTaskFinished listener;
public MyAsyncTask(OnTaskFinished listener) {
this.listener = listener;
}
// ...
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
listener.onTaskFinished(result);
}
}