if (status == 200) {
String result = EntityUtils.toString(response.getEntity());
Log.d("Response", result);
ArrayAdapter < String > adapter = new ArrayAdapter < String > (getActivity(),
android.R.layout.simple_list_item_1, result);
setListAdapter(adapter);
}
I am unable to set my response into my List. I get my response as
{
"Appointments": [{
"Name": "Kevin",
}, {
"Name": "John",
}]
}
How would i set my name parameter in the listView.
How would i set my name parameter in the listView.
At a glance. Third parameter of ArrayAdapter should be collection but you are passing only simple String. According to your JSON i recommend you:
Create own object that will represent Person with properties(name,
age, etc.)
Parse JSON and create collection of persons
Set collection to ListAdapter
Example:
public class Person {
private String name;
...
// getters and setters
#Override
public String toString() {
return this.name;
}
}
Then, you need to parse JSON and get proper data:
List<Person> persons = new ArrayList<Person>();
Person person = null;
JSONObject root = new JSONObject(sourceString);
JSONArray appointments = root.getJSONArray("Appointments");
JSONObject child = null;
for (int i = 0; i < appointments.length(); i++) {
child = appointments.getJSONObject(i);
if (child != null)
person = new Person();
person.setName(child.getString("Name"));
persons.add(person);
}
}
Then initialise ListAdapter:
new ArrayAdapter<String>(getActivity(), layout, persons);
and now you got it.
Note:
Reason why i'm overriding toString() method is that since you are using default ArrayAdapter with build-in Android layout each object in your List will be converted to String and will be shown in ListView but if i don't override toString() it won't return person's name but string representation of object that is human-unreadable string.
result is a String containing the entire response. You need to parse or split that string into the items that you want.
You need to give your adapter the items (either as a list or an array). Right now you've created an adapter but haven't provided it any data via the constructor or any setter.
I suggest you read more about ListViews and Adapters on the Android developers site.
Related
JSON format
I want to display the json in list view ,
here is my code
Call> call = api.getScheduledTasks("atos");
call.enqueue(new Callback<List<ScheduledTasks>>() {
#Override
public void onResponse(Call<List<ScheduledTasks>> call, Response<List<ScheduledTasks>> response) {
Toast.makeText(getApplicationContext(),"successsss",Toast.LENGTH_LONG);
List<ScheduledTasks> ScheduledTasksList = response.body();
// ScheduledTasksList.toString();
//Creating an String array for the ListView
String[] scheduledtask = new String[ScheduledTasksList.size()];
//looping through all the heroes and inserting the names inside the string array
for (int i = 0; i < ScheduledTasksList.size(); i++) {
scheduledtask[i] = ScheduledTasksList.get(i).getScheduleId();
}
//displaying the string array into listview
listView.setAdapter(new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, scheduledtask));
It shows failure ,it doesnt display in list view because of int in json.Kindly provide me the right method,to display both string and int in array.
copy your json response, nothing but image which you upload for this question, and paste in this website. then the website(tool) convert your json response to POJO class and you can access easily like calling any setter and getter method.
hope this solve your problem.
How do I display multiple rows of data in ListView?
Now I am only able to retrieve and display one data(Item) at a time, I want to retrieve multiple rows of data(Items) and display all them in ListView.
In this case, I am using the name of the user to retrieve the coupons he/she have in the database. So for i can only display one coupon and I want to know how to display multiple coupon in ListView.
protected String doInBackground(String... args) {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", name));
JSONObject json = jsonParser.makeHttpRequest(
url_all_coupons, "GET", params);
Log.d("Single Voucher Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray productObj = json
.getJSONArray(TAG_COUPONS); // JSON Array
JSONObject coupons = productObj.getJSONObject(0);
To populate the ListView I suggest you create a List of objects (vouchers) and create an Adapter that knows how to display any number of coupons in the list. First of all you may want to define a simple class for your coupons (reimplement it according to your data structure):
public class Coupon {
private String mCouponText;
public Coupon(String text) {
mCouponText = text;
}
public String getCouponText() {
return mCouponText;
}
}
After that you should create a List of these objects from your JSONArray. There are different approaches, one of them:
List<Coupon> couponsList = new ArrayList<>();
JSONArray coupons = json
.getJSONArray(TAG_COUPONS); // JSON Array
for (JSONObject coupon : (Iterable<JSONObject>) coupons) {
String text = coupon.get("text");
couponsList.add(new Coupon(text));
}
And the last thing to do is to create an Adapter and set it as an adapter of your ListView in your Activity:
ArrayAdapter<Coupon> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, couponsList);
yourListView.setAdapter(adapter);
After that the ListView will use the Adapter to populate its rows. You may want to implement your own adapter since it gets you far more options, you'll easily find out how to do it.
Update
Consider using RecyclerView instead.
Make a class call it anything you like (lets call it Item), and each instance of this call will represent relevant row in the Database ( or any source from where you are getting the information)
Item.java may have few instance variable like coupons and userName,
public class Item {
private String coupons;
private String userName;
public String getCoupons() {
return coupons;
}
public void setCoupons(String coupons) {
this.coupons = coupons;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Make a Arraylist of type Item and feed this information to a custom ListView to show the details you want it to.
ArrayList<Item> list = new ArrayList<>();
for (int i = 0; i < productObj.length(); i++) {
Item item = new Item();
item.setCoupons(""+productObj.getJSONObject(i).getString("CouponKey"));
list.add(item);
}
I am building an app in which I have a view with multiple tabs. Each tab contains a RecyclerView which gets populated from data in MySQL. So there is the Activity with the ViewPager and then each tab has its own Fragment. So I use the Interface to pass data from Fragment to Activity in order to be able to search for. The thing is that if I do not scroll over the tabs the recycler List is null so I cannot search. My question is would it be better if I search directly in the database or is there any other way to do this?
My App looks like this:
The code for passing data is:
Interface:
public interface CoffeeCommunicator {
void sendCoffeeListData(String name, String image, String price);
}
Fragment:
#Override
protected List<ProductList> doInBackground(String... params) {
try {
url = new URL(params[0]);
urlConnection =(HttpURLConnection) url.openConnection();
urlConnection.connect();
urlConnection.setConnectTimeout(5000);
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
jsonResult = StringGenerator.inputStreamToString(in, getActivity());
customList = new ArrayList<>();
jsonResponse = new JSONObject(jsonResult.toString());
jsonMainNode = jsonResponse.optJSONArray(AppConstant.COFFEE_JSON_ARRAY);
for (int i = 0; i < jsonMainNode.length(); i++) {
jsonChildNode = jsonMainNode.getJSONObject(i);
name = jsonChildNode.optString("name");
price = jsonChildNode.optString("price");
image = jsonChildNode.optString("image");
customList.add(new ProductList(image, name, price));
coffeeCommunicator.sendCoffeeListData(name, image, price);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return customList;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
coffeeCommunicator = (CoffeeCommunicator)activity;
}
Activity:
#Override
public void sendCoffeeListData(String name, String image, String price) {
coffeesList.add(new ProductList(image, name, price));
}
So then i have coffeeList available to search for.
Any ideas would be helpfull.
I can give code sample but you know your code better. Here's a sample:
In Activity:
populateList();
coffeeFragment = CoffeeFragment.newInstance();
coffeeFragment.setList(coffeesList);
void populateList() {
jsonResponse = new JSONObject(jsonResult.toString());
jsonMainNode = jsonResponse.optJSONArray(AppConstant.COFFEE_JSON_ARRAY);
for (int i = 0; i < jsonMainNode.length(); i++) {
jsonChildNode = jsonMainNode.getJSONObject(i);
name = jsonChildNode.optString("name");
price = jsonChildNode.optString("price");
image = jsonChildNode.optString("image");
coffeesList.add(new ProductList(image, name, price));
}
}
Fragment:
public void setList(final List<ProductList> arrayList) {
{
customList = arrayList;
}
Note:
Basically you fill data onto coffeesList in Activity. And then pass the List onto the Fragment. I pass a List object by calling a method setList in the Fragment because it is easier.
I hope that is clear enough. Is there a problem with this approach?
It would make sense to query the database when doing an explicit search. That will avoid the problem you're currently having of the data not yet being populated.
If I understand correctly you want to populate data onto RecyclerView. In that case, your method is not the proper way. Here is one Android web page showing data population. Below is a code sample from that web page:
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
Notes:
In this code example, myDataset is simply an array of strings; this is the data. It can be any object actually. MyAdapter is a class that you create.
RecyclerView uses the idea of Adapter, like in ListView.
This method populates data immediately after the view is created. It uses virtual caching.
Is this what you had in mind?
I want to send the data of selected item in a listview to the next activity.This data has been fetched from JSON.
But it is returning last object's data of json and not that of the item i am selecting.Please help me to get the data of selected item that is fetched from json and pass it on to next activity using bundle.
String savedPlaceAddressLine1,savedPlaceAddressLine2,savedPlaceCity,savedPlaceZip,savedPlaceState,savedPlaceCountry,savedPlaceLat,savedPlaceLong;
class JSONAsyncTask extends AsyncTask<String,Void,Boolean>{
#Override
protected Boolean doInBackground(String... params) {
try {
....
JSONObject object2 = jsonArray.getJSONObject(2);
JSONArray jsonArraySavedPlaces = object2.getJSONArray("saved-places");
Log.i("Status2", "GotInnerArray");
for (int j = 0; j < jsonArraySavedPlaces.length(); j++)
{
JSONObject object4 = jsonArraySavedPlaces.getJSONObject(j);
ListItemDataSource listItemDataSource= new ListItemDataSource();
JSONObject addressObject=object4.getJSONObject("address");
Log.i("Status", "GotAddressesArray");
savedPlaceAddressLine1=addressObject.getString("address-line1");Log.i("Status1", savedPlaceAddressLine1);
savedPlaceAddressLine2=addressObject.getString("address-line2");Log.i("Status1", savedPlaceAddressLine2);
savedPlaceCity=addressObject.getString("city");Log.i("Status1", savedPlaceCity);
savedPlaceZip=addressObject.getString("zip");Log.i("Status1", savedPlaceZip);
savedPlaceState=addressObject.getString("state");Log.i("Status1", savedPlaceState);
savedPlaceCountry=addressObject.getString("country");Log.i("Status1", savedPlaceCountry);
savedPlaceTitle=addressObject.getString("address-title");Log.i("Status1", savedPlaceTitle);
savedPlaceLat=addressObject.getString("lattitude");Log.i("Status1", savedPlaceLat);
savedPlaceLong=addressObject.getString("longitude");Log.i("Status1", savedPlaceLong);
String placeAddress=savedPlaceAddressLine1+","+savedPlaceAddressLine2+","+savedPlaceCity+","+savedPlaceState+","+savedPlaceCountry;
listItemDataSource.setPlaceTitle(savedPlaceTitle);Log.i("Status2", "Title");
listItemDataSource.setPlaceAddress(placeAddress);Log.i("Status2", "Address");
itemsList.add(listItemDataSource);
Log.i("info","got data of object"+j);
}
}
return true;
}
...
}
in OnCreate:
Bundle extras=new Bundle();
extras.putString("savedPlacesAddress-title", savedPlaceTitle);
extras.putString("savedPlacesAddress1", savedPlaceAddressLine1);
extras.putString("savedPlacesAddress2", savedPlaceAddressLine2);
extras.putString("savedPlacesCity", savedPlaceCity);
extras.putString("savedPlacesZip", savedPlaceZip);
extras.putString("savedPlacesState", savedPlaceState);
extras.putString("savedPlacesCountry", savedPlaceCountry);
String data=savedPlaceAddressLine1+","+savedPlaceAddressLine2+","+savedPlaceCity+","+savedPlaceZip+","+savedPlaceState+","+savedPlaceCountry;
Log.d("data",data);
intent.putExtras(extras);
startActivity(intent);
Create a model class AppAddress.
Create all setter and getter method for your property like address1, address2, zip code etc.
implement this class by Serializable.
Create a Array list with AppAddress type.
Add all data in your AppAddress class by setter method and add it into arraylist.
When you will click on row of listview then pass object of AppAddress class by bundle.
Receive this object from other activity.
You can download sample code from below link:
http://www.wingnity.com/blog/android-json-parsing-and-image-loading-tutorial/
http://www.androidbegin.com/tutorial/android-json-parse-images-and-texts-tutorial/
http://wptrafficanalyzer.in/blog/android-json-parsing-with-jsonobject-and-loading-to-listview-example/
Currently working on an app that takes results from a search, parses the JSON object returned, and then adds the resulting pieces into a few ArrayLists within a class created called VenueList.
Here is the method that receives the results from the service and parses the JSON:
private static List<String> getResultsFromJson(String json) {
ArrayList<String> resultList = new ArrayList<String>();
try {
JSONObject resultsWrapper = (JSONObject) new JSONTokener(json).nextValue();
JSONArray results = resultsWrapper.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
resultList.add(result.getString("text"));
}
}
catch (JSONException e) {
Log.e(TAG, "Failed to parse JSON.", e);
}
return resultList;
}
What results of this becomes a List variable call mResults (to clarify: mResults = getResultsFromJson(restResult);. That is then used, among other places, in the following loop that puts the results into an ArrayAdapter that is used for displaying them in a ListFragment:
for (String result : mResults) {
VenueList.addVenue(result, "HELLO WORLD");
adapter.add(result);
}
I also add the result to a class called VenueList that manages the results and makes them accessible for multiple views. It essentially just holds multiple ArrayLists that hold different types of details for each venue returned in the search. The method I use to add a venue to VenueList is below (and you can see it used in the for loop above):
public static void addVenue(String name, String geo) {
venueNames.add(name);
venueGeos.add(geo);
}
I want the addVenue method to be able to take multiple arguments and update the VenueList class. Yet, when I call the addVenue method in the for loop, I can only pass it String result (from the parameters of the loop) and can't figure out how to pass it a second argument (which should also come from the JSON parsed by getResultsFromJson) so I've used "HELLO WORLD" as a placeholder for now.
I realize getResultsFromJson only has one list returned. I need to be able to take multiple elements from the JSON object that I parse, and then add them to VenueList in the right order.
So my questions are:
1) Given the getResultsFromJson method and the for loop, how can I use the addVenue() method as designed? How do I parse multiple elements from the JSON, and then add them to the VenueList at the same time? I plan on adding more arguments to it later on, but I assume if I can make it work with two, I can make it work with four or five.
2) If that's not possible, how should the getResultsFromJson, the for loop, and the addVenue method be redesigned to work properly together?
Please let me know if you need more detail or code - happy to provide. Thank you!
EDIT - Full VenueList class:
public class VenueList {
private static ArrayList<String> venueNames;
private static ArrayList<String> venueGeos;
public VenueList() {
venueNames = new ArrayList<String>();
venueGeos = new ArrayList<String>();
}
public static void addVenue(String name, String geo) {
venueNames.add(name);
venueGeos.add(geo);
}
public static String getVenueName(int position) {
return venueNames.get(position);
}
public static String getVenueGeo(int position) {
return venueGeos.get(position);
}
public static void clearList() {
venueNames.clear();
venueGeos.clear();
}
}
Clarification: I will have additional ArrayLists for each element of data that I want to store about a venue (phone number, address, etc etc)
1) I don't think methods getResultsFromJson(String json) and addVenue(String name, String geo) fit your needs.
2) I would consider rewriting method getResultsFromJson(String json) to something like this:
private static SortedMap<Integer, List<String>> getResultsFromJson(String json) {
Map<Integer, String> resultMap = new TreeMap<Integer, String>();
//...
return resultMap;
}
where the number of keys of your map should be equal to the number of objects you're extracting info, and each one of them will properly have their own list of items just in the right order you extract them.
With this approach you can certainly change your logic to something like this:
// grab your retuned map and get an entrySet, the just iterate trough it
SortedMap<Integer, String> result = returnedMap.entrySet();
for (Entry<Integer, String> result : entrySet) {
Integer key = result.getKey(); // use it if you need it
List<String> yourDesiredItems = result.getValue(); // explicitly shown to know how to get it
VenueList.addVenue(yourDesiredItems);
}
public static void addVenue(List<String> yourDesiredItems) {
// refactor here to iterate the items trough the list and save properly
//....
}
EDIT -- as you wish to avoid the go-between map i'm assuming you need nothing to return from the method
First i'm providing you with a solution to your requirements, then i'll provide you with some tips cause i see some things that could smplify your design.
To save VenueList things directly from getResultsFromJSON do something like this:
private static void getResultsFromJson(String json) {
try {
JSONObject resultsWrapper = (JSONObject) new JSONTokener(json).nextValue();
JSONArray results = resultsWrapper.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
//FOR EXAMPLE HERE IS WHERE YOU NEED TO EXTRACT INFO
String name = result.getString("name");
String geo = result.getString("geo");
// and then...
VenueList.addVenue(name, geo, ..., etc);
}
} catch (JSONException e) {
Log.e(TAG, "Failed to parse JSON.", e);
}
}
This implies that your addVenue method should know receive all params needed; as you can see this is just a way (that you can consider a workaround to your needs), however as i don't know all requirements that lead you to code this model, i will point to a few things you might consider:
1. If there's a reason for VenueList class to use everything static, consider doing this:
static{
venueNames = new ArrayList<String>();
venueGeos = new ArrayList<String>();
//....
}
private VenueList(){
}
This way you won't need to get an instance every time and also will avoid null pointer exceptions when doing VenueList.addVenue(...) without previous instantiation.
2. Instead of having an ArrayList for every characteristic in VenueList class consider defining a model object for a Venue like this:
public class Venue{
String name;
String geo;
//... etc
public Venue(){
}
// ... getters & setters
}
then if you need that VenueList class you will just have a list o Venue objects (List<Venue>), this means that instead of calling the method addVenue, you will first create a brand new instance of Venue class and will call the setter method of each characteristic, as an example of the refactored for loop from the workaround i provided you you'd be using something like this:
List<Venue> myListOfVenues = new ArrayList<Venue>();
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
// THIS WOULD REMAIN THE SAME TO EXTRACT INFO
String name = result.getString("name");
String geo = result.getString("geo");
// and then instead of calling VenueList.addVenue(name, geo, ..., etc)...
Venue v = new Venue();
v.setName(name);
v.setGeo(geo);
// ...etc
myListOfVenues.add(v);
}
// Once you're done, set that List to VenueList class
VenueList.setVenueList(myListOfVenues);
So VenueList class would now have a single property List<Venue> venueList; and would suffer minor tweeks on methods getVenueName, etc... and everything would be more readable... i hope this helps you to get another approach to solve your problem, if i still don't make my point let me know and i'll try to help you out...