I want to fill a ListFragment with certain objects loaded from my MySql database.
It has to load the first 10 'objects' from my ResultSet.
I want to use an AsyncTaskLoader for this and put the loaded object in a ListItem each time I retreive it from the database.
Can anybody help me with this one? Tried searching for good examples or tutorials but I haven't really found something that's really useful...
Create your adapter with a new list in your preexecute method. Set that adapter to your listview.
Then in doInBackground read your database, create objects to fit in your list, but don't add them. Pas each object after made as parameter for your publishprogress method.
In onProgressUpdate add your object to the list and notify your adapter that the dataset is changed.
Below is an example for how I do it reading a twitter call.
private class parseTwitterTask extends AsyncTask<Void, TCListObject2, List<TCListObject2>> {
TCListObjectAdapter2 adapter;
List<TCListObject2> list;
#Override
protected void onPreExecute() {
list = new ArrayList<TCListObject2>();
ListView lv = (ListView)findViewById(R.id.twitterlist);
adapter = new TCListObjectAdapter2(list);
lv.setAdapter(adapter);
super.onPreExecute();
}
#Override
protected List<TCListObject2> doInBackground(Void... params) {
try {
String url = social.get("twittersearchurl");//"http://search.twitter.com/search.json?q=" + social.get("twitter");
String json = Internet.request(url, null);
JSONObject jo = new JSONObject(json);
if(jo.has("results")) {
JSONArray ar = jo.getJSONArray("results");
for(int i = 0; i < ar.length(); i++) {
TCListObject2 tweet = new TCListObject2();
JSONObject jobj = (JSONObject) ar.get(i);
tweet.id = "false";
tweet.img = jobj.getString("profile_image_url");
String text = jobj.getString("text");
text = Html.fromHtml(text).toString();
tweet.params.put(R.id.sub2, text);
String name = jobj.getString("from_user");
name = Html.fromHtml(name).toString();
tweet.params.put(R.id.text, name);
String time = jobj.getString("created_at");
tweet.params.put(R.id.sub1, Converter.timeToTimeAgo(time));
try {
tweet.time = new Date(time);
} catch(Exception e) {
e.printStackTrace();
}
tweet.celLayout = R.layout.cell_tweetobject;
publishProgress(tweet);
}
}
} catch(Exception e) {
e.printStackTrace();
}
return list;
}
#Override
protected void onProgressUpdate(TCListObject2... values) {
list.add(values[0]);
adapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}
Related
I have wrote the code to populate List View with single string. But, I don't know how to populate with 2 strings.. Somebody, please help me out.
here is my code:
public class BackTask extends AsyncTask<String, Void, String> {
ArrayList<FlowerAdapter.Flowers> flowersList = new ArrayList<FlowerAdapter.Flowers>();
String url = "http://113.193.30.155/MobileService/MobileService.asmx/GetSampleData";
#Override
protected void onPreExecute(){
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
String content = FlowerAdapter.HttpULRConnect.getData(url);
return content;
}
#Override
protected void onPostExecute(String s){
try {
JSONArray ar =new JSONArray(s);
for (int i = 0; i < ar.length(); i++){
JSONObject jsonObject=ar.getJSONObject(i);
here i want to get 2 strings "NAME"&"PERCENTAGE"....but i dont know how to get the another string and bind it in List View.
FlowerAdapter.Flowers flowers= new FlowerAdapter.Flowers();
flowers.setName(jsonObject.getString("NAME"));
flowersList.add(flowers);
FlowerAdapter adapter=new FlowerAdapter(getContext(),R.layout.flower_list_xml,flowersList);
listView = (ListView)getView().findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setVisibility(View.VISIBLE);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
first, add all the field in your Flowers class with setters and gettersThen set it in the object which you are passing to adapter.
i have created a setter for this second string and called it...thats all..
flowers.setPercentage(jsonObject.getString("Percentage");
ANSWERED BY ME
I am confused where to put and how to use my custom adapter.
My Parser.class has its own Adapter and my MainActivity is passing 3 parameters to the Parser.class (context, url, listview).
(Making my problem simple)
After creating a custom layout, custom adapter, and instantiating my custom adapter, I don't know what to do.
I tried instantiating my custom adapter in my MainActivity then creating MainActivity m = new MainActivity(); in my Parser.class and just use the textviews of my custom listview like m.name_tv.setText(name); and m.price_tv.setText(price) then changing the android.R.layout.simple_list_item_1 to my custom listview layout R.layout.list_layout.
I was just experimenting because I'm having trouble understanding.
Please help.
This is my Parser.class
public class Parser extends AsyncTask<Void,Integer,Integer> {
Context c;
ListView lv;
String data;
ArrayList<String> categories = new ArrayList<>();
ProgressDialog pd;
public Parser(Context c, String data, ListView lv) {
this.c = c;
this.data = data;
this.lv = lv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Parsing Data");
pd.setMessage("Please Wait...");
pd.show();
}
#Override
protected Integer doInBackground(Void... params) {
return this.parse();
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if(integer == 1)
{
//ADAPTER
ArrayAdapter<String> adapter = new ArrayAdapter<String>(c, android.R.layout.simple_list_item_1, categories);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position == 0){
}
}
});
}else
{
Toast.makeText(c,"Unable to Parse",Toast.LENGTH_SHORT).show();
}
pd.dismiss();
}
//PARSE RECEIVED DATA
private int parse(){
try
{
//ADD THAT DATA TO JSON ARRAY FIRST
JSONArray ja = new JSONArray(data);
//CREATE JO OBJECT TO HOLD A SINGLE ITEM
JSONObject jo = null;
categories.clear();
//LOOP THROUGH ARRAY
for(int i =0 ; i<ja.length();i++)
{
jo = ja.getJSONObject(i);
//RETRIEVE NAME
name=jo.getString("item_name");
price=jo.getString("item_price");
//ADD TO ARRAY LIST
categories.add(name + " " + price);
}
return 1;
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
}
Should it be better to not separate the classes or it will work the same?
you should get response from web service and parse it (json object or json array) in one step
you can reach this in good way ,
First create class with json attribute name
in your case
Class JsonItem {
string item_name;
string item_price;
// create getter and setter
}
Second use Gson to parse your response
Gson gson = new Gson();
// 1. JSON to Java object, read it from a file.
JsonItem staff = gson.fromJson(YOUR_JSON_Here, JsonItem.class);
that is all
Following is resful web service display on browser.I need to read these data info andoird as client side as list of table
ArrayList<PickerItemDetail>
//content of http://127.0.0.1:8080/picking
[
{"pickerBatch":1,"sku":"FL45678976543","name":"Coke 1000L","image":"coke.jpg","qty":"8","pickingStatus":"picked","pickedBy":"John","pickedOn":"02/04/2014","locked":"0"},
{"pickerBatch":2,"sku":"FL45678543675","name":"Mineral Water 50L","image":"drinkingWater.jpg","qty":"5","pickingStatus":"picked","pickedBy":"Roy","pickedOn":"02/04/2014","locked":"0"}
]
For android side
public class MainActivity extends ListActivity {
#Override
protected void onStart() {
super.onStart();
new HttpRequestTask().execute();
}
private class HttpRequestTask extends AsyncTask<Void, Void, ArrayList<PickerItemDetail>> {
#Override
protected ArrayList<PickerItemDetail> doInBackground(Void... params) {
try {
final String url = "http://127.0.0.1:8080/picking";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
ArrayList<PickerItemDetail> item = restTemplate.getForObject(url, ArrayList.class);
return item;
} catch (Exception e) {
Log.e("MainActivity", e.getMessage(), e);
}
return null;
}
#Override
protected void onPostExecute(ArrayList<PickerItemDetail> item) {
TextView sku = (TextView) findViewById(R.id.sku);
TextView qty = (TextView) findViewById(R.id.qty);
TextView name = (TextView) findViewById(R.id.skuname);
sku.setText(item.get(0).getSku());
qty.setText(item.get(0).getQty());
name.setText(item.get(0).getName());
}
}
}
I would like to read list of data from webservice then display it as a table in android side.
How do I have a proper code to loop over the ArrayList,I think these code not fully correct way,but no idea to continue/make it pretty works.
onPostExecute(ArrayList<>){ item.get(0).getXXX}
Hope someone advice
,Thank
I am not sure what exactly you need but if you want show in listview you can go with
like this.... in your postexecut=sion
add this function loadData();
loadDate() function will be like
private void loadData() {
try {
// looping through All Contacts
contactList.clear();
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String pickerBatch = c.getString("pickerBatch");
String sku = c.getString(sku);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put("pickerBatch", pickerBatch);
map.put("sku", sku);
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
ListAdapter adapter = new MySimpleAdapter(Activity.this,
contactList, R.layout.list_item, new String[] {
pickerBatch, sku }, new int[] {
R.id.pickerBatch, R.id.sku });
setListAdapter(adapter);
//
// /
// selecting single ListView item
}
In this above example contactList is your arrayList... Hope it will work
I am making an android app in which I am using two spinners. In first spinner I am displaying data from JSON which I've done successfully. Now by clicking an item of first spinner I need to display data from another JSON service into second spinner.
First Service (I am displaying city_name from this service on first spinner):
{"result":{"data":[{"city_id":"16","city_name":"\u00c4ngelholm"},
{"city_id":"23","city_name":"B\u00e5stad"},
{"city_id":"22","city_name":"Halmstad"},
{"city_id":"19","city_name":"H\u00f6gan\u00e4s"},{"city_id":"20","city_name":"Helsingborg"},
{"city_id":"15","city_name":"Klippan"},
{"city_id":"24","city_name":"Kungsbacka"},
{"city_id":"21","city_name":"Laholm"},{"city_id":"18","city_name":"Landskrona"}],
"status":"true","description":""}}
Second Service:
{"result":{"data":[{"category_id":"18","category":"Aff\u00e4rsverksamhet",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"19","category":"\u00d6vrigt",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"13","category":"Bostad",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"15","category":"Elektronik",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"12","category":"F\u00f6r hemmet","city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"11","category":"Fordon",
"city_id":"16","city_name":"\u00c4ngelholm"},
{"category_id":"16","category":"Fritid & Hobby",
"city_id":"16","city_name":"\u00c4ngelholm"}],
"status":"true","description":""}}
As you can see in both services city_id and city_name are common fields. If I select city_name from first spinner it will match through city_id or city_name and display category against that city_name.
Below is my code I have tried.
private class AllCities extends AsyncTask<String, String, JSONObject>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected JSONObject doInBackground(String... params)
{
try
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("url of First Service");
HttpResponse resp = client.execute(post);
HttpEntity entity = resp.getEntity();
String response = EntityUtils.toString(entity);
return new JSONObject(response);
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject result)
{
super.onPostExecute(result);
if(result != null)
{
myList = new ArrayList<HashMap<String,String>>();
if(! result.has("false"))
{
try
{
JSONObject object = result.getJSONObject("result");
JSONArray array = object.getJSONArray("data");
stringArray = new ArrayList<String>();
for(int i=0; i<array.length(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("city_id", array.getJSONObject(i).getString("city_id"));
map.put("city_name", array.getJSONObject(i).getString("city_name"));
myList.add(map);
stringArray.add(array.getJSONObject(i).getString("city_name"));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(PostAdds.this,
android.R.layout.simple_spinner_item, stringArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_city.setAdapter(adapter);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
else if(result == null)
{
Toast.makeText(PostAdds.this,
"Hittade inga Detaljer Vänligen Kontrollera din Internet-anslutning",
Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
//what am I suppose to do here????
}
#Override
public void onNothingSelected(AdapterView<?> parent)
{
}
Sorry about the late answer. I was solved this by my self but never came back here to post the solution which worked for me. Now I am posting this answer if any one has same kind of problem can get help from here.
So What I did
1) Call the first service and populate city names on first spinner and when item is selected of first spinner, save its value in a global String like
String selectedCity;
selectedCity = spinner1.getSelectedItem().toString();
2) When click any item of first spinner call the second service and put a simple check while populating the second spinner.
ArrayList<String> categories = new ArrayList<String>();
try {
JSONObject object = result.getJSONObject("result");
JSONArray array = object.getJSONArray("data");
for(int a = 0; a < array.length(); a++) {
String cityName = array.getJSONObject(a).getString("city_name");
if(cityName.equals(selectedCity)) // this check is important
{
categories.add(cityName );
}
}
// after for loop ends populate adapter of second spinner
ArrayAdapter<String> adapt = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, categories);
spinner2.setAdapter(adapt);
}
catch(Exception e) {
e.printStackTrace();
}
In this way I got my desired result. There are other solutions of this problem as well like one of them is when you call second service pass city_id or city_name along with url as params and service will only return you the desired categories.
Hope this will solve for any one has similar kind of problem. I just check my Stackoverflow profile today and found this question has not answered by any one so I did it my self :)
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