Reputation: 262
I want to use asyncTask to get result from api and put it in a view. Now the code is like this:
public class GradeFragment extends Fragment {
private ListView lv;
private LinearLayout llLayout;
private String[] items;
ArrayAdapter<String> adapter;
TextView text;
private FragmentActivity faActivity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
faActivity = (FragmentActivity)super.getActivity();
lv=(ListView)llLayout.findViewById(R.id.list_item);
text = (TextView) llLayout.findViewById(R.id.text);
new ReadWeatherJSONFeedTask().execute("http://api.androidhive.info/contacts/");
//worked here
items = new String[] { "Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5"
};
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
lv.setAdapter(adapter);
return llLayout;
}
private class ReadWeatherJSONFeedTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
//text.setText(urls[0]);
try {
response = httpclient.execute(new HttpGet(urls[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
text.setText("restapi failed");
throw new IOException(statusLine.getReasonPhrase());
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
try {
//do not work here
items = new String[] {
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5"
};
lv=(ListView)llLayout.findViewById(R.id.list_item);
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
lv.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
//Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
}
}
}
/* @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_grade, menu);
return true;
}*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
When I comment out adapter in onPostExecute and left the one in onCreateView, it works fine. But when I comment out the adapter in onCreateViw and lfet the one in onPostExecute, the list do not show up. Dose anyone know why the adapter worked will in onCreateView but not in onPostExecute method? If I want to display the results in onPostExcute in the fragment, what should I do?
Upvotes: 0
Views: 732
Reputation: 3993
How about you try a callback interface that you can use to call after post execute This is the sample code
private class ReadWeatherJSONFeedTask extends AsyncTask<String, Void, String> {
CallBack callback;
public ReadWeatherJSONFeedTask(CallBack callback){
this.callback = callback;
}
protected String doInBackground(String... urls) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
//text.setText(urls[0]);
try {
response = httpclient.execute(new HttpGet(urls[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
text.setText("restapi failed");
throw new IOException(statusLine.getReasonPhrase());
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return responseString;
@Override
protected void onPostExecute(String result) {
callback.onCallBack();
}
Your new aysnc
public interface CallBack{
public void onCallBack();}
Then finally call it like
new ReadWeatherJSONFeedTask( new CallBack(){
public void onCallBack(){
try {
//do not work here
items = new String[] {
"Item 1",
"Item 2",
"Item 3",
"Item 4",
"Item 5"
};
lv=(ListView)llLayout.findViewById(R.id.list_item);
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
lv.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
//Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
}
}
}).execute("http://api.androidhive.info/contacts/");
Upvotes: 1
Reputation: 115
First you have to replace the old values with the new values in ur String[] items
then you have to notifyDataSetChanged()
to your adapter.
Instead of
lv=(ListView)llLayout.findViewById(R.id.list_item);
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
lv.setAdapter(adapter);
you just have to have
adapter.notifyDataSetChanged();
Hope this helps you.
BTW: Your items is the same string array in both places, how do you know it works or not?
Upvotes: 0