I followed this tutorial about parsing JSON. All is working as it should have have edited it to more my needs. I am getting information about 'servers' and one of the fields is 'status' (either UP or DOWN).
EDIT: forgot to post tutorial link http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
It currently looks like this: http://puu.sh/8Ky0B.jpg
The above is what happens then the app is loaded. the on click is when a single item is clicked it starts a new activity and shows that information individually.
You can see the second server status is 'DOWN'. Based on this I want to change the text colour to RED for down and keep it green for up.
How can I do this when it goes through and adds each listview?
Here is the code which (currently) is basically the same as the tutorial:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverList = new ArrayList<HashMap<String, String>>();
ListView lv = getListView();
// Listview on item click listener
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name))
.getText().toString();
String ip = ((TextView) view.findViewById(R.id.ipAddress))
.getText().toString();
String status = ((TextView) view.findViewById(R.id.serverStatus))
.getText().toString();
// Starting single server activity
Intent in = new Intent(getApplicationContext(),
SingleContactActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_IP, ip);
in.putExtra(TAG_STATUS, status);
startActivity(in);
}
});
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONArray jArray = new JSONArray(jsonStr);
// looping through All Servers
for (int i = 0; i < jArray.length(); i++) {
JSONObject c = jArray.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String ip = c.getString(TAG_IP);
String status = c.getString(TAG_STATUS);
// tmp hashmap for single server
HashMap<String, String> contact = new HashMap<String, String>();
contact.put(TAG_ID, id);
contact.put(TAG_NAME, name);
contact.put(TAG_IP, ip);
contact.put(TAG_STATUS, status);
// adding server to server list
serverList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, serverList,
R.layout.list_item, new String[] { TAG_NAME, TAG_IP,
TAG_STATUS }, new int[] { R.id.name,
R.id.ipAddress, R.id.serverStatus });
setListAdapter(adapter);
}
}
You need to make a custom adapter and in the getView() you should check if the status of the server is down then set the color of corresponding textview to red else set it to green.
your getView() should like as following: (This is just a blueprint for your code)
getView(){
String serverstatus = server.getStatus();
// get status should be method in method in model class for server.
if(serverstatus.equals("DOWN")){
tv.setTextColor(Color.RED);
}else{
tv.setTextColor(Color.GREEN);
}
}
EDIT
Make a model class.
class Server{
String serverName, serverIp, serverStatus;
// getter and setter.
}
Make array adapter of Server type.
In Adapter's getView() inflate the row item, and set the details. For, red color font blueprint is already added.
In the definition of list Adapter, in the getView() method, find the textview and change the text color.
TextView tv = (TextView) listItem.findViewById(R.id.server_status);
tv.setTextColor(android.R.color.primary_text_dark);
Take the custom Adapter (a BaseAdapter) instead of simple adapter,
and there you perform your operation in getView() method.
You've done most of the hard work already :)
First create an object to store server details rather than a HashMap (which are slow and heavy) plus an object is more adaptable and fits your purpose better.
I've created a super fast example (not complete as to your details, but should be easy to expand).
package com.example.adaptertest;
public class HolderServer {
String serverName;
boolean isServerUp;
public HolderServer(String serverName, boolean isServerUp) {
this.serverName = serverName;
this.isServerUp = isServerUp;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public boolean isServerUp() {
return isServerUp;
}
public void setServerUp(boolean isServerUp) {
this.isServerUp = isServerUp;
}
}
Next you'll need to create a custom adapter. In your example you're actually using a simple adapter (ListAdapter adapter = new SimpleAdapter() which is a great first step, but we can improve on that a little by extending it. This will allow us to change what happens to each individual element in the listview. i.e. change the color etc.
Here's a quick example:
package com.example.adaptertest;
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class AdapterServers extends ArrayAdapter<HolderServer>{
ArrayList<HolderServer> mServers = new ArrayList<HolderServer>();
private LayoutInflater mInflater;
Context mContext;
public AdapterServers(Context context, int resource, ArrayList<HolderServer> servers) {
super(context, resource, servers);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContext = context;
mServers = servers;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Inflate view for each element in list.
convertView = mInflater.inflate(R.layout.server_list_item, null);
//Get details for current server
HolderServer server = mServers.get(position);
//Set server name
((TextView) convertView.findViewById(R.id.server_list_item_txt_servername)).setText(server.getServerName());
//Now we set the status text and color
TextView status = (TextView) convertView.findViewById(R.id.server_list_item_txt_serverstatus);
if(server.isServerUp){
status.setText(mContext.getResources().getString(R.string.up));
status.setTextColor(mContext.getResources().getColor(R.color.green));
}else{
status.setText(mContext.getResources().getString(R.string.down));
status.setTextColor(mContext.getResources().getColor(R.color.red));
}
return convertView;
}
}
Now back in your code, first in onCreate create a new list of objects:
ArrayList<HolderServer> mServerList = new ArrayList<HolderServer>();
then instead of this:
// tmp hashmap for single server
HashMap<String, String> contact = new HashMap<String, String>();
contact.put(TAG_ID, id);
contact.put(TAG_NAME, name);
contact.put(TAG_IP, ip);
contact.put(TAG_STATUS, status);
You'll create your new object & add it to the list. Obviously update it with your variables once your HolderServer object is updated:
HolderServer server = new HolderServer("Server1", true);
serverList.add(server);
Then apply that list to the adapter and apply the adapter to the listview:
AdapterServers adapter = new AdapterServers(this, 0, serverList);
((ListView) findViewById(R.id.fragment_main_listview)).setAdapter(adapter);
Good luck!
Related
Bonjour
I have spent days and night looking for an answer suitable to my case
can you help please
Here is the code I am using
anytime I add the ligne with Picasso, the program crashes
It works fine with static images from drawable
I just want to display the text with the image that corresponds
public void Afficher_les_vues(String url_in) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url_in)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
myResponse = response.body().string();
Annonces.this.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
JSONObject reader = new JSONObject(myResponse);
JSONArray eglises = reader.getJSONArray("Annonces_adv");
arrayList.clear();
for (int i = 0; i < eglises.length(); i++) {
JSONObject eglise = eglises.getJSONObject(i);
String titre = eglise.getString(titret);
String description = eglise.getString(descriptionet);
int ref = Integer.parseInt(eglise.getString(reft));
String image = eglise.getString(imaget);
String url_image = eglise.getString(imaget);
HashMap<String, String> data = new HashMap<>();
data.put(titret, titre);
data.put(descriptionet, description);
data.put(reft, String.valueOf(ref));
data.put(imaget, image);
data.put(url_imaget, url_image);
arrayList.add(data);
ImageView imageViewlogo = findViewById(R.id.imageViewLogoNews);
//Picasso.get().load(url_image).into(imageViewlogo);
//new GetImageFromUrl(imageViewlogo).execute(url_image);
ListAdapter adapter = new SimpleAdapter(Annonces.this, arrayList, R.layout.listview_layout
, new String[]{titret, descriptionet, reft, url_imaget}, new int[]{R.id.titre_de, R.id.description_de,
R.id.reference, R.id.url_image});
lv.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
When I use Picasso to display and image in a simple ImageView not in a listView, it works fine
Thank you in advance
I work with android studio
Blessings
The main things you need to fix are not creating the adapter every loop instance and not accessing row views (the ImageView) from outside the adapter.
1. Do not make the adapter inside the loop
You should build the array of data to display first, then after the loop that builds the array create the adapter and set it on the ListView. When you have a custom adapter, it is helpful to use a small data class to hold the data you need to show in each row (see RowData later in the answer)
arrayList.clear(); // ArrayList<RowData>()
for (int i = 0; i < eglises.length(); i++) {
JSONObject eglise = eglises.getJSONObject(i);
String titre = eglise.getString(titret);
String description = eglise.getString(descriptionet);
int ref = Integer.parseInt(eglise.getString(reft));
String url_image = eglise.getString(imaget);
RowData data = new RowData(titre, description, String.valueOf(ref), url_image);
arrayList.add(data);
}
// You CANNOT access row view here - in this context findViewById searches the main
// view heirarchy, and will not find views in your ListView rows
// Make the adapter *AFTER* the loop where you fill the array
// you will need to make your own custom adapter to load the image
ListAdapter adapter = new CustomAdapter(Annonces.this, R.layout.listview_layout, arrayList);
lv.setAdapter(adapter);
2. Do not attempt to access row views outside the adapter
Your row views should only be accessed inside getView in your adapter itself. This is where you should load the image. If you were using a standard adapter before, you will need to implement your own custom adapter to do this. There are instructions for how to do that here. The adapter below takes an ArrayList of RowData items and uses that to populate each row.
public class CustomAdapter extends ArrayAdapter<RowData> {
private Context mContext;
private int mResource;
public MainAdapter(#NonNull Context context, int resource, #NonNull ArrayList<RowData> objects) {
super(context, resource, objects);
mContext=context;
mResource=resource;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if( convertView == null ) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
}
// Get the views for this row (these must be in the
// layout xml you passed in to the adapter constructor)
TextView title = convertView.findViewById(R.id.titre_de);
TextView description = convertView.findViewById(R.id.description_de);
TextView reference = convertView.findViewById(R.id.reference);
ImageView imageViewlogo = convertView.findViewById(R.id.imageViewLogoNews);
// Get the RowData class for this row
RowData data = getItem(position);
// Set the text fields
title.setText(data.title);
description.setText(data.description);
reference.setText(data.reference);
// Start Picasso loading into the ImageView for this row
Picasso.get().load(data.url).into(imageViewlogo);
return convertView;
}
}
Make a small data class
When you have a custom adapter it is useful to make a custom data class that holds the data you want to show in each row. This avoids the possible errors in missing keys etc... you can get with a plain old map or passing in multiple lists.
public class RowData {
final String title;
final String description;
final String reference;
final String url;
RowData(String title, String desc, String ref, String url) {
this.title = title;
this.description = desc;
this.reference = ref;
this.url = url;
}
}
I am trying to get data from server into spinner, my json object is
{"result":{"AndhrPradesh":["Jayamahal","ABC","JP nagar"],"Mumbai":["XYZ","PQR"],"Pune":["123","Hi"]}}
I am able to get the values AndhraPradesh,Mumbai and Pune in one spinner. now my problem is after selecting city i want to display corresponding data in that city.
for example, if select Mumbai from one spinner i want to display XYZ,PQR in another spinner, Please help me.
First of all parse the json data like
JSONObject jsonObject = response.getJSONObject("data");
JSONArray cityName= jsonObject.getJSONArray("AndhrPradesh")
for(i=0;i<cityName.length();i++){
//your inner string of the Array
}
Then
citynameSpinner.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//here set the values to another spinner
}
});
Please use this code snippet
public class SpinnerFilterActivity extends AppCompatActivity {
private ArrayAdapter<String> mArrayAdapter;
private Spinner mMainSPN;
private ArrayList<String> mSpinnerArray;
private Map<String,ArrayList<String>> innterDataMap;
private Spinner mInnerSPN;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinnerArray = new ArrayList<String>();
innterDataMap = new HashMap<String, ArrayList<String>>();
mMainSPN = (Spinner) findViewById(R.id.spn_main);
mInnerSPN = (Spinner) findViewById(R.id.spn_inner);
mMainSPN.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String key = mSpinnerArray.get(position);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(SpinnerFilterActivity.this,android.R.layout.simple_spinner_item,innterDataMap.get(key));
mInnerSPN.setAdapter(arrayAdapter);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
parseJson();
}
private void parseJson() {
String s= "{\"result\":{\"AndhrPradesh\":[\"Jayamahal\",\"ABC\",\"JP nagar\"],\"Mumbai\":[\"XYZ\",\"PQR\"],\"Pune\":[\"123\",\"Hi\"]}}\n";
try {
JSONObject jsonObject = new JSONObject(s);
JSONObject obj= jsonObject.getJSONObject("result");
Iterator<String> stringIterator = obj.keys();
while (stringIterator.hasNext()){
String key = stringIterator.next();
mSpinnerArray.add(key);
JSONArray jsonArray = obj.getJSONArray(key);
ArrayList<String> innerList = new ArrayList<>();
for (int i=0;i<jsonArray.length();i++){
innerList.add(String.valueOf(jsonArray.get(i)));
}
innterDataMap.put(key,innerList);
}
populateDataInSpinner();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void populateDataInSpinner() {
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,mSpinnerArray);
mMainSPN.setAdapter(arrayAdapter);
}
}
In this code I have kept a data in 2 fields one i mSpinnerArray to display the aster list and other is map in which inner list is kept on behalf of the key as parent value. Whenever onOptionItemSelected method gets called I fetch the list of inner data from map on behalf of the seleted item from the master list as it is working as a key in innerMap data. I hope I am clear. Let me know if there is any problem.
I am making a listview, which shows data from a server. I get no errors in LogCat, but my ListView doesn't appear. This is my code:
package com.imptmd.charliemacdonald.desleutelaar;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
public class SlotenFragment extends ListFragment {
private ProgressDialog nDialog;
// URL to get contacts JSON
private static String url = "http://charlenemacdonald.com/sloten.json";
// JSON Node names
private static final String TAG_SLOTEN = "slotenlijst";
private static final String TAG_SLOT = "Slot";
// contacts JSONArray
JSONArray sloten= null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> slotenLijst;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_sloten, container, false);
slotenLijst = new ArrayList<HashMap<String, String>>();
ListView lv = (ListView) rootView.findViewById(android.R.id.list);
// Listview on item click listener
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String Slot = ((TextView) rootView.findViewById(R.id.textviewslotnaam))
.getText().toString();
// Starting single contact activity
Intent in = new Intent(getActivity().getApplicationContext(),
SlotInfoScherm1.class);
in.putExtra(TAG_SLOT, Slot);
startActivity(in);
}
});
new GetSloten().execute();
// Calling async task to get json
return rootView;
}
/**
* Async task class to get json by making HTTP call
* */
private class GetSloten extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
nDialog = new ProgressDialog(getActivity());
nDialog.setMessage("Even geduld a.u.b., studenten worden geladen...");
nDialog.setCancelable(false);
nDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
sloten = jsonObj.getJSONArray(TAG_SLOTEN);
// looping through All Contacts
for (int i = 0; i < sloten.length(); i++) {
JSONObject c = sloten.getJSONObject(i);
String Slot = c.getString(TAG_SLOT);
// tmp hashmap for single contact
HashMap<String, String> sloten = new HashMap<String, String>();
// adding each child node to HashMap key => value
sloten.put(TAG_SLOT, Slot);
// adding contact to contact list
slotenLijst.add(sloten);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (nDialog.isShowing())
nDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(getActivity(), slotenLijst,
R.layout.sloten_info, new String[] { TAG_SLOT}, new int[] { R.id.textviewslotnaam});
setListAdapter(adapter);
}
}
}
The INTERNET permission is already added in the Manifest, just as WRITE EXTERNAL STORAGE and INTERNAL STORAGE. I get no errors in LogCat. The only error I get is in the ADB 'ADB rejected connection to client'. Is that why my ListView doesn't appear? Thanks in advance.
Hi can you update you code and test the below logic what you received.
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (nDialog.isShowing())
nDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
Log.d("DataSize: ",""+slotenLijst.size());
ListAdapter adapter = new SimpleAdapter(getActivity(), slotenLijst,
R.layout.sloten_info, new String[] { TAG_SLOT}, new int[] { R.id.textviewslotnaam});
setListAdapter(adapter);
}
Let us know what you get in log cat "DataSize".
Change your onCreateView(...) to be:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_sloten, container, false);
slotenLijst = new ArrayList<HashMap<String, String>>();
ListView lv = (ListView) rootView.findViewById(android.R.id.list);
new GetSloten().execute();
// Calling async task to get json
return rootView;
}
// ListFragment implement this in default
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
//getting values from selected ListItem
String Slot = ((TextView) rootView.findViewById(R.id.textviewslotnaam))
.getText().toString();
// Starting single contact activity
Intent in = new Intent(getActivity().getApplicationContext(),
SlotInfoScherm1.class);
in.putExtra(TAG_SLOT, Slot);
startActivity(in);
}
});
and your fragment layout fragment_sloten could be like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
... ...
</LinearLayout>
Hope this help!
I have an app that loads the traffic report from a server and shows it in a timeline (like twitter), the app is configured to load the data from the server every 10 seconds using this code:
#Override
public void onResume() {
super.onResume();
autoUpdate = new Timer();
autoUpdate.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
new DownloadJSON2().execute(); // this is the class that downloads the data from the server.
}
});
}
}, 0, 10000); // updates each 10 secs
}
#Override
public void onPause() {
autoUpdate.cancel();
super.onPause();
}
The problem is that if I scroll down the list and I'm reading the older posts, the list refreshes and send me to the top of it. I want to download that data like ajax and append it to the top. Or just to tell me that is X new reports and a button to show it.
How can I acomplish this?
BTW I'm extremely new to android programming.
Thanks in advance.
EDIT: Thanks to Vasily Sochinsky i've added the following:
public class DownloadJSON extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(MainActivity.this);
// Set progressdialog title
mProgressDialog.setTitle("Cargando reportes en tiempo real");
// Set progressdialog message
mProgressDialog.setMessage("Por favor espere");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Create an array
arraylist = new ArrayList<HashMap<String, String>>();
// Retrieve JSON Objects from the given URL address
jsonobject = JSONfunctions
.getJSONfromURL("http://server.com/timeline.php");
try {
// Locate the array name in JSON
jsonarray = jsonobject.getJSONArray("datos");
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
jsonobject = jsonarray.getJSONObject(i);
// Retrive JSON Objects
// jsonobject1 = jsonobject.getJSONObject("contenido");
map.put("imagen", jsonobject.getString("imagen"));
map.put("quien", jsonobject.getString("quien"));
map.put("fecha", jsonobject.getString("fecha"));
map.put("reporte", jsonobject.getString("reporte"));
// map.put("imgs", jsonobject1.getString("imgs"));
// map.put("video", jsonobject1.getString("video"));
// Set the JSON Objects into the array
arraylist.add(map);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this, arraylist);
// Set the adapter to the ListView
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
// Close the progressdialog
mProgressDialog.dismiss();
}
}
But the listview is not updating with the new data, how can i achieve this?
EDIT 2: Thanks to cogentapps that gave me a solution, but i still can not add it to the code, where should i add it?
I've tried this but eclipse shows many errors:
protected void onPostExecute(Void args) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this, arraylist);
// Set the adapter to the ListView
adapter.addAll();
listview.notifyDataSetChanged();
// Close the progressdialog
mProgressDialog.dismiss();
}
This is the code from my ListViewAdapter, where should i add the adapter.add()?
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
LayoutInflater inflater;
ArrayList<HashMap<String, String>> data;
ImageLoader imageLoader;
HashMap<String, String> resultp = new HashMap<String, String>();
String coment;
public String img;
public int imga;
public ListViewAdapter(Context context,
ArrayList<HashMap<String, String>> arraylist) {
this.context = context;
data = arraylist;
imageLoader = new ImageLoader(context);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// Declare Variables
TextView quien;
ImageView imagen;
TextView reporte;
TextView fecha;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.listview_item, parent, false);
// Get the position
resultp = data.get(position);
// Locate the TextViews in listview_item.xml
// Locate the ImageView in listview_item.xml
imagen = (ImageView) itemView.findViewById(R.id.imagen);
fecha = (TextView) itemView.findViewById(R.id.fecha);
quien = (TextView) itemView.findViewById(R.id.quien);
reporte = (TextView) itemView.findViewById(R.id.reporte);
// Capture position and set results to the TextViews
// Capture position and set results to the ImageView
// Passes flag images URL into ImageLoader.class
imageLoader.DisplayImage(resultp.get(MainActivity.IMAGEN), imagen);
fecha.setText(resultp.get(MainActivity.FECHA));
reporte.setText(resultp.get(MainActivity.REPORTE));
quien.setText(resultp.get(MainActivity.QUIEN));
// Capture ListView item click
/*
itemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// Get the position
resultp = data.get(position);
Intent intent = new Intent(context, SingleItemView.class);
// Pass all data rank
intent.putExtra("imagen", resultp.get(MainActivity.IMAGEN));
intent.putExtra("quien", resultp.get(MainActivity.QUIEN));
intent.putExtra("fecha", resultp.get(MainActivity.FECHA));
// Start SingleItemView Class
context.startActivity(intent);
}
});
*/
return itemView;
}
}
Take a look at the answer to this question for an explanation / example of how to maintain scroll position after adding items to a list: Retaining position in ListView after calling notifyDataSetChanged
Basically, you make a note of the position and scroll offset of the first visible item in the list before adding new data. Then afterwards, you restore the previous position and scroll offset.
However, because you're adding new items at the top of the list, the position returned by getFirstVisiblePosition() may refer to a different item after refreshing. The item that was at position 0 before refreshing may now be position 10. To fix that, you need to determine the number of new items returned by timeline.php and add it to index, like this:
mList.setSelectionFromTop(index + newItemCount, top);
You could probably determine which items are new by comparing the date field.
(By the way, if timeline.php only returns the most recent set of items, you could run into trouble if the user has scrolled to an older item which is no longer returned by timeline.php. After setting the new data, the old item will no longer be present, so you won't be able to scroll to it.
To fix that, you could keep the old ArrayList around and only add new items to it in doInBackground(). And call notifyDataSetChanged() in doInBackground(). That way, the adapter will still have access to older items.)
I'm trying to add items to an arraylist using this class template:
public class Template {
public String username;
public String email;
}
Here's the whole code:
public void JsonToArrayList(JSONArray myJsonArray) throws JSONException
{
ArrayList<Template> listItems = new ArrayList<Template>();
JSONObject jo = new JSONObject();
Template tem = new Template();
ListView lv = (ListView) findViewById(R.id.listView1);
for(int i = 0; i<myJsonArray.length(); i++)
{
jo = myJsonArray.getJSONObject(i);
tem.username = jo.getString("username");
tem.email = jo.getString("user_email");
listItems.add(tem);
Log.e("Ninja Archives", tem.username);
}
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<Template> arrayAdapter = new ArrayAdapter<Template>(this,android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(arrayAdapter);
}
The problem is, instead of filling my listview with nice username and email strings, it's filling up with items like this:
com.android.ninjaarchives.
Template#40585690
I think somewhere along the line I have become lost, but I've been trying all sorts for ages now and getting nowhere. Can anyone point me in the right direction?
Thanks for any help.
Note: not really sure what's going on with the code; it doesn't appear to be pasting correctly.
Use below code, it can be a solution for you
public void JsonToArrayList(JSONArray myJsonArray) throws JSONException
{
ArrayList<Template> listItems = new ArrayList<Template>();
JSONObject jo = new JSONObject();
Template tem = new Template();
ListView lv = (ListView) findViewById(R.id.listView1);
String listItemString[] = new String[myJsonArray.length];
for(int i = 0; i<myJsonArray.length(); i++)
{
jo = myJsonArray.getJSONObject(i);
tem.username = jo.getString("username");
tem.email = jo.getString("user_email");
listItemString[i] = tem.username +" - " + tem.email; // u can change it according to ur need.
listItems.add(tem);
Log.e("Ninja Archives", tem.username);
}
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, listItemString);
lv.setAdapter(arrayAdapter);
}
But better to write Custom adapter by extending BaseAdapter, and do listItem handling in getView method here is one simple tutorial
Take a class extending Base
private class CustomAdapter extends BaseAdapter
{
LayoutInflater inflater;
public CustomAdapter(Context context)
{
inflater = LayoutInflater.from(context);
}
public int getCount()
{
return listItems.size();
}
public Object getItem(int position)
{
return listItems.get(position);
}
public long getItemId(int position)
{
return position;
}
public View getView(final int position, View convertView,ViewGroup parent)
{
//if(convertView==null)
//convertView = inflater.inflate(R.layout.listlayout, parent, false);
Template data = (Template) getItem(position);
TextView v=new TextView(context);
v.setText(data.name);
return v;
}
}
and set adapter to your listview
lv.setAdapter(new CustomAdapter(this));
In this case you have to use a custom adapter (that extends from ArrayAdapter) and override the getView method to display in a custom layout the username and the email.