so recently i had an issue that i could not get more than one record to display from a online database in my android app. I was using text view but was advised to utilize a list view. With the help of some kind people on here i have been pointed in the right direction how ever i am still having trouble as the list view does not display anything. I will attach the code below which i have annotated for this post.
For reference i am utilising volley and php, when accessing the data through the url, example: http://example.url/data.php/$id=1
public class GetExerciseList extends AppCompatActivity implements View.OnClickListener {
private EditText editTextId;
private Button buttonGet;
private TextView textViewResult;
ListView listView ;
ArrayAdapter adapter;
private ArrayList<String> dataList = new ArrayList<>();
private ProgressDialog loading;
INITIALIZING VIEWS
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_getexerciselist);
editTextId = (EditText) findViewById(R.id.editTextId);
buttonGet = (Button) findViewById(R.id.buttonGet);
textViewResult = (TextView) findViewById(R.id.textViewResult);
ListView listView = (ListView) findViewById(R.id.list);
adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, dataList);
listView.setAdapter(adapter);
buttonGet.setOnClickListener(this);
}
DECLARING ADAPTERS AND VIEWS
private void getData() {
String id = editTextId.getText().toString().trim();
if (id.equals("")) {
Toast.makeText(this, "Please enter an id", Toast.LENGTH_LONG).show();
return;
}
loading = ProgressDialog.show(this,"Please wait...","Fetching...",false,false);
String url = Config.DATA_URL+editTextId.getText().toString().trim();
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
loading.dismiss();
showJSON(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) { Toast.makeText(GetExerciseList.this,error.getMessage().toString(),Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
FETCHING DATA BASED ON MATCHING ID
private void showJSON(String response){
String musclegroup="";
String exercise="";
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray result = jsonObject.getJSONArray(Config.JSON_ARRAY);
JSONObject collegeData;
for(int i = 0; i<result.length(); i++) {
collegeData = result.getJSONObject(i);
musclegroup = collegeData.getString(Config.KEY_MUSCLEGROUP);
exercise = collegeData.getString(Config.KEY_EXERCISE);
adapter.notifyDataSetChanged();
dataList.add(musclegroup + " " + exercise + " ");
}
FOR LOOP TO LOOP THROUGH JSON DATA, AND ADD ALL RECORDS TO THE DATALIST
} catch (JSONException e) {
e.printStackTrace();
}
EXCEPTION CATCHER
textViewResult.setText("Target Muscle:\t" + musclegroup + "\nLift:\t" + exercise);
// this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, dataList));
ListView lv = (ListView)findViewById(R.id.list);
lv.setAdapter(adapter);
ArrayAdapter<String> adapter =new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, dataList);
}
TEXTVIEW LEFT IN JUST TO CHECK DATA. LIST VIEW CURRENTLY HAS NO OUTPUT
LISTVIEW ADAPTER DECLARED AND SET, DATA SET AS "datalist"
#Override
public void onClick(View v) {
getData();
}
}
I have broken this down to make this easily readable, thank you everyone for the help as always it is very appreciated.
First of all, add the datas and notify the adatper.
private void showJSON(String response){
String musclegroup="";
String exercise="";
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray result = jsonObject.getJSONArray(Config.JSON_ARRAY);
JSONObject collegeData;
for(int i = 0; i<result.length(); i++) {
collegeData = result.getJSONObject(i);
musclegroup = collegeData.getString(Config.KEY_MUSCLEGROUP);
exercise = collegeData.getString(Config.KEY_EXERCISE);
dataList.add(musclegroup + " " + exercise + " ");
adapter.notifyDataSetChanged();
}
Better solution is to create your adapter and set it to the ListView after the loop is finished instead to call adapter.notifyDataSetChanged(); every time in the loop until iterate your response.
private void showJSON(String response){
String musclegroup="";
String exercise="";
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray result = jsonObject.getJSONArray(Config.JSON_ARRAY);
JSONObject collegeData;
for(int i = 0; i<result.length(); i++) {
collegeData = result.getJSONObject(i);
musclegroup = collegeData.getString(Config.KEY_MUSCLEGROUP);
exercise = collegeData.getString(Config.KEY_EXERCISE);
dataList.add(musclegroup + " " + exercise + " ");
}
adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, dataList);
listView.setAdapter(adapter);
}
Related
I'm trying to pass an ArrayList to a function which will then display it on a list format but it seems my parameters are wrong for Arrayadapter.
#Override
public void handleResult(final Result result) {
final RequestQueue mQueue = Volley.newRequestQueue(this);
String url = "https://fg3qzgb2va.execute-api.ap-southeast-1.amazonaws.com/sample";
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
for (int i = 0; i < response.length() ; i++) {
JSONObject jsonArray = response.getJSONObject(i);
String first = jsonArray.getString("Name");
String price = jsonArray.getString("Price");
int priceResult = Integer.parseInt(price);
String id = jsonArray.getString("id");
if(id.equals(result.getText())){
addItem.setName(first);
addItem.setPrice(priceResult);
MainActivity.resultTextView.setText("Name: " + addItem.getName() + "\n"+"Price: " + addItem.getPrice());
itemList = new ArrayList<>();
itemList.add(addItem.getName());
addItem.setName("");
addToList.addList(itemList);
}
//Storing into the list
}
} catch (JSONException e) {
e.printStackTrace();
}
public class AddToList extends AppCompatActivity {
ArrayAdapter<String> adapter;
public void addList(ArrayList<String> arrayList ){
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_multiple_choice,arrayList);
adapter.notifyDataSetChanged();
MainActivity.list.setAdapter(adapter);
}
}
Try this
Remove line:
MainActivity.list.setAdapter(adapter);
Add:
ListView mList = MainActivity.list;
mList.setAdapter(adapter);
try to change public void addList(ArrayList<String> arrayList ) to public void addList(List<String> arrayList )
I don't know why the items added to ArrayList won't populate ListView, I tried checking if items are indeed added to ArrayList but it shows it does.
You can check the image of the added items here
Here is my code. I'm using another xml for checkedtextview so my listview will display items with checkboxes.
ArrayList<String> symptomsListTest = new ArrayList<>();
ListView chl1;
String URL = "***********";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
addListItem();
chl1 = (ListView) findViewById(R.id.checklistSample);
chl1.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
ArrayAdapter<String> aa = new ArrayAdapter<String>(this, R.layout.symptoms_checklist, R.id.txt_title, symptomsListTest);
//ArrayAdapter<String> aa=new ArrayAdapter<String>(this,R.layout.symptoms_checklist, R.id.txt_title,symptomsListTest);
chl1.setAdapter(aa);
chl1.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
String selectedItem = ((TextView) view).getText().toString();
if(symptomsListTest.contains(selectedItem))
{
symptomsListTest.remove(selectedItem); //remove deselected item from the list of selected items
}
else
{
symptomsListTest.add(selectedItem); //add selected item to the list of selected items
}
}
});
}
public void addListItem()
{
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
String message = jsonObject.getString("message");
JSONArray jsonArray = jsonObject.getJSONArray("read");
if(success.equals("1"))
{
for(int i = 0; i < jsonArray.length(); i++)
{
JSONObject object = jsonArray.getJSONObject(i);
String symptom = object.getString("symptom1");
symptomsListTest.add(symptom);
//Toast.makeText(SAMPLE.this, ""+symptom, Toast.LENGTH_SHORT).show();
//Toast.makeText(Login.this, ""+message+"\nYour name is: "+name+"\nYour email is: "+email,Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(SAMPLE.this, ""+message,Toast.LENGTH_SHORT).show();
}
}
catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(SAMPLE.this, e.toString(),Toast.LENGTH_SHORT).show();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(SAMPLE.this, error.toString(),Toast.LENGTH_SHORT).show();
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError
{
Map<String, String> params = new HashMap<>();
String result="success";
params.put("result", result);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
You are executing an AsyncTask which is giving a response after sometime, meanwhile the code of listView and it's adapter is already executed. You just need to add one line after the for loop like this :-
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String symptom = object.getString("symptom1");
symptomsListTest.add(symptom);
//Toast.makeText(SAMPLE.this, ""+symptom, Toast.LENGTH_SHORT).show();
//Toast.makeText(Login.this, ""+message+"\nYour name is: "+name+"\nYour email is: "+email,Toast.LENGTH_SHORT).show();
}
//** Add This line **
aa.notifyDataSetChanged();
And make sure your ArrayAdapter is declared global. Hope this helps.
I'm trying to parse some JSON. I'm trying to iterate through the JSON array and get all the 'ids' from each object and populate a list view using them. I've tried numerous ways but getting nowhere with it. Please see code below.
String url = "https://api.tfl.gov.uk/line/mode/tube/status";
JsonArrayRequest jsArrayRequest = new JsonArrayRequest (Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
int data = 0;
try {
// Loop through the array elements
for (int i = 0; i < response.length(); i++) {
// Get current json object
JSONObject line = response.getJSONObject(i);
// Get the current line (json object) data
String lineName = line.getString("id");
// Display the formatted json data in text view
// lineNameTextView.setText(lineName);
}
ListView myListView = (ListView)findViewById(R.id.myListView);
ArrayList<String> tubeLines = new ArrayList<String>();
tubeLines.add(lineName);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, tubeLines);
myListView.setAdapter(arrayAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG", "Error response:", error);
}
});
// tempTextView.setText("Response: " + response.toString());
// Log.v("status", "Response: " + tempTextView.toString());
// Access the RequestQueue through your singleton class.
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(jsArrayRequest);
Create the list before loop
Add elements in list in each iteration instead of adding the last element into the list
otherwise it will show only the last item that you are trying to add after the loop (with compile time error due to lineName local scope)
// initialize list
ArrayList<String> tubeLines = new ArrayList<String>();
for(int i=0;i<response.length();i++) {
// Get current json object
JSONObject line = response.getJSONObject(i);
// Get the current line (json object) data
// To avoid crash use optString
String lineName = line.optString("id","N/A");
// add all items
tubeLines.add(lineName);
}
ListView myListView = (ListView)findViewById(R.id.myListView);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, tubeLines);
myListView.setAdapter(arrayAdapter);
Here's the working code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ListView listView = (ListView) findViewById(R.id.list_view);
final ArrayList<String> tubeLines = new ArrayList<>();
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, tubeLines);
listView.setAdapter(arrayAdapter);
RequestQueue queue = Volley.newRequestQueue(this);
String url ="https://api.tfl.gov.uk/line/mode/tube/status";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.optJSONObject(i);
String line = object.optString("id");
if (line != null) {
tubeLines.add(line);
}
}
// Once we added the string to the array, we notify the arrayAdapter
arrayAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(stringRequest);
}
The results is as below:
I am loading some json into a list view and want to delete items from the list on click and for the item to be deleted from the json. The delete functionality seems to be working. The method delete is called, the items are removed on click and debugging shows the item being removed. However after going to another activity and viewing the list again, the deleted items come back. what am i doing wrong? This is my class:
public class edit extends AppCompatActivity
{
public ListView pizzaList;
ListView addicList;
ArrayAdapter<String> arrayAdapter;
String appreciations;
String currentPizza;
ArrayList<String> list = new ArrayList<String>();
private String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_activity);
pizzaList = (ListView) findViewById(R.id.pizzas);
registerForContextMenu(pizzaList);
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
pizzaList.setAdapter(arrayAdapter);
pizzaList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
delete(view,position);
arrayAdapter.notifyDataSetChanged();
}
});
try {
FileManager fileManager = new FileManager();
String str = fileManager.ReadFile(this);
if (str != null) {
JSONArray jarray = new JSONArray(str);
String outputText = "";
for (int i = 0; i < jarray.length(); i++) {
JSONObject jsonObject = jarray.getJSONObject(i);
String pizzaName = jsonObject.getString("name");
int price = jsonObject.getInt("price");
outputText = outputText + " " + pizzaName + " " + " $" + price + "\n";
appreciations = outputText;
list.add(appreciations);
arrayAdapter.notifyDataSetChanged();
outputText = "";
}
} else {
Toast to = Toast.makeText(getApplicationContext(), "No saved Pizzas", Toast.LENGTH_LONG);
to.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void delete(View view, int pos)
{
try {
FileManager fileManager = new FileManager();
String str = fileManager.ReadFile(this);
if (str != null)
{
JSONArray jarray = new JSONArray(str);
JSONObject jsonObject = jarray.getJSONObject(pos);
jarray.remove(pos);
list.remove(pos);
arrayAdapter.notifyDataSetChanged();
JSONArray jsArray = new JSONArray(jarray);
arrayAdapter.notifyDataSetChanged();
} else {
Toast to = Toast.makeText(getApplicationContext(), "No saved Pizzas", Toast.LENGTH_LONG);
to.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
You would need to remove the item from the database, use asynchronous request such as volley or robospice for it. Then instead of making the request when coming back you would use the data stored on the cache the second time and only make the request again when data has been changed. You can create your cache logic in your application class to make it visible throughout your app.
I am trying to fetch data from server into my spinner but its not showing any item in spinner , and i am not getting any logcat error also..i have taken this from 1 example , in my json output i want to fetch only name of country ..but its not showing anything:
this is my java class:
pmcountry = (Spinner) findViewById(R.id.country);
//citySpinner = (Spinner) findViewById(City);
//locationSpinner = (Spinner) findViewById(R.id.Location);
pmcountry .setOnItemSelectedListener(this);
country_list = new ArrayList<String>();
//location_list = new ArrayList<String>();
// city_list = new ArrayList<String>();
getData();
}
private void getData(){
StringRequest stringRequest = new StringRequest(Config.DATA_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
Log.d("Test",response);
JSONArray result = new JSONArray(response);
//Calling method getCountry to get the Country from the JSON Array
getCountry(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}});
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
private void getCountry(JSONArray jsonArrayCountry){
//Traversing through all the items in the json array
List<Country> countries = new ArrayList<>();
try {
String country_name, country_code;
JSONObject countries_object;
for (int i = 0; i < jsonArrayCountry.length(); i++) {
countries_object = jsonArrayCountry.getJSONObject(i);
country_code = countries_object.getString("id");
country_name = countries_object.getString("Name");
countries.add(new Country(country_code, country_name));
}
/*ArrayAdapter countryAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, countries);
pmcountry.setPrompt("--Select Country--");
pmcountry.setAdapter(countryAdapter);
pmcountry.setAdapter(new NothingSelectedSpinnerAdapter(countryAdapter,
R.layout.contact_spinner_row_nothing_selected,this));*/
pmcountry.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
} catch (JSONException e) {
}
}
You are trying to set the list of Custom Objects List<Country>
By default array adapter takes list of String. List<String>.
You have to tweak your code to set List of Custom objects in spinner.
Android: How to bind spinner to custom object list?
This should solve your problem.
Uncomment your , You are not setting data to spinner anywhere..
ArrayAdapter countryAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, countries);
pmcountry.setPrompt("--Select Country--");
pmcountry.setAdapter(countryAdapter);
pmcountry.setAdapter(new NothingSelectedSpinnerAdapter(countryAdapter,
R.layout.contact_spinner_row_nothing_selected,this));