Does anyone know of any examples to dynamically load Json data into a ListView, most examples I have seen just use a static array of some kind. I need to load say 10 rows of Json data, then at the bottom have a load more.. to get the next 10 etc etc. Examples using Json please....
Programmer Bruce is correct, there is no default way to do this. However, there is a very clean and simple way to get this accomplished. Here is the adapter I use to handle JSONArrays.
class JSONAdapter extends BaseAdapter implements ListAdapter {
private final Activity activity;
private final JSONArray jsonArray;
private JSONAdapter(Activity activity, JSONArray jsonArray) {
assert activity != null;
assert jsonArray != null;
this.jsonArray = jsonArray;
this.activity = activity;
}
@Override public int getCount() {
return jsonArray.length();
}
@Override public JSONObject getItem(int position) {
return jsonArray.optJSONObject(position);
}
@Override public long getItemId(int position) {
JSONObject jsonObject = getItem(position);
return jsonObject.optLong("id");
}
@Override public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = activity.getLayoutInflater().inflate(R.layout.row, null);
JSONObject jsonObject = getItem(position);
return convertView;
}
}
Android doesn't have a ready-made adapter to populate a ListView
with a JSON array, like it does for populating a ListView
with database records.
I recommend getting comfortable with populating a Java data structure of your choice with the JSON data, and getting comfortable with working with ListViews
, populating them from different collections, with different custom rows.
Here's a simple example of populating a List
from a JSON array, and then using the List
to populate a ListView
.
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Main extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try
{
String jsonInput = "[\"one\",\"two\",\"three\",\"four\",\"five\",\"six\",\"seven\",\"eight\",\"nine\",\"ten\"]";
JSONArray jsonArray = new JSONArray(jsonInput);
int length = jsonArray.length();
List<String> listContents = new ArrayList<String>(length);
for (int i = 0; i < length; i++)
{
listContents.add(jsonArray.getString(i));
}
ListView myListView = (ListView) findViewById(R.id.my_list);
myListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listContents));
}
catch (Exception e)
{
// this is just an example
}
}
}
dbaugh has a good answer, but this post explains how to use it for the rest of us who don't know where to go from there.
Try the below:
JSON Parser class:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if (method == "POST") {
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} else if (method == "GET") {
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Fragment class showing Listview:
public static class EventFragment extends ListFragment {
ArrayList<HashMap<String, String>> eventsList;
private String url_all_events = //url goes here;
private ProgressDialog pDialog;
JSONParser jParser = new JSONParser();
// JSON Node names
private static final String CONNECTION_STATUS = "success";
private static final String TABLE_EVENT = "Event";
private static final String pid = "pid";
private static final String COL_GROUP = "Group";
private static final String COL_NAME = "Event_Name";
private static final String COL_DESC = "Event_Desc";
private static final String COL_DATE = "Event_Date";
private static final String COL_TIME = "Event_Time";
JSONArray Events = null;
public static final String ARG_SECTION_NUMBER = "section_number";
public EventFragment() {
}
public void onStart() {
super.onStart();
eventsList = new ArrayList<HashMap<String, String>>();
new LoadAllEvents().execute();
// selecting single ListView item
ListView lv = getListView();
// Lauching the Event details screen on selecting a single event
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String ID = ((TextView) view.findViewById(R.id.pid))
.getText().toString();
Intent intent = new Intent(view.getContext(),
EventDetails.class);
intent.putExtra(pid, ID);
view.getContext().startActivity(intent);
}
});
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_events,
container, false);
return rootView;
}
class LoadAllEvents extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_events,
"GET", params);
try {
// Checking for SUCCESS TAG
int success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// products found
// Getting Array of Products
Events = json.getJSONArray(TABLE_EVENT);
// looping through All Contacts
for (int i = 0; i < Events.length(); i++) {
JSONObject evt = Events.getJSONObject(i);
// Storing each json item in variable
id = evt.getString(pid);
group = evt.getString(COL_GROUP);
name = evt.getString(COL_NAME);
desc = evt.getString(COL_DESC);
date = evt.getString(COL_DATE);
time = evt.getString(COL_TIME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(pid, id);
map.put(COL_GROUP, group);
map.put(COL_NAME, name);
map.put(COL_DESC, desc);
map.put(COL_DATE, date);
map.put(COL_TIME, time);
// adding HashList to ArrayList
eventsList.add(map);
}
} else {
// Options are not available or server is down.
// Dismiss the loading dialog and display an alert
// onPostExecute
pDialog.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
getActivity().runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(getActivity(),
eventsList, R.layout.list_item, new String[] {
pid, COL_GROUP, COL_NAME, COL_DATE, COL_TIME },
new int[] { R.id.pid, R.id.group, R.id.name, R.id.header,
R.id.title2 });
setListAdapter(adapter);
}
});
}
}
}
Activity details class:
public class EventDetails extends Activity {
String pid;
TextView EvtName, EvtDesc, EvtDate, EvtTime, Header;
ImageView logo;
private String url_event_details = "http://centrubook.eu.pn/eventDetails.php";
private ProgressDialog pDialog;
JSONParser jParser = new JSONParser();
// JSON Node names
private static final String CONNECTION_STATUS = "success";
private static final String TABLE_EVENT = "Event";
private static final String COL_PID = "pid";
private static final String COL_NAME = "Event_Name";
private static final String COL_DESC = "Event_Desc";
private static final String COL_DATE = "Event_Date";
private static final String COL_TIME = "Event_Time";
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.eventdetails);
// ActionBar actionBar = getActionBar();
// actionBar.setDisplayHomeAsUpEnabled(true);
EvtName = (TextView) findViewById(R.id.BombaName);
EvtDesc = (TextView) findViewById(R.id.BombaDesc);
EvtDate = (TextView) findViewById(R.id.BombaDate);
EvtTime = (TextView) findViewById(R.id.BombaTime);
logo = (ImageView) findViewById(R.id.BombaLogo);
Intent i = getIntent();
pid = i.getStringExtra(COL_PID);
new getEventDetails().execute();
}
class getEventDetails extends AsyncTask<String, String, String> {
String name, desc, date, time;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EventDetails.this);
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... args) {
// Check for success tag
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jParser.makeHttpRequest(url_event_details,
"GET", params);
// json success tag
success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// successfully received product details
JSONArray eventsObj = json.getJSONArray(TABLE_EVENT);
// get first product object from JSON Array
JSONObject details = eventsObj.getJSONObject(0);
name = details.getString(COL_NAME);
desc = details.getString(COL_DESC);
date = details.getString(COL_DATE);
time = details.getString(COL_TIME);
} else {
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(final String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
EvtName.setText(name);
EvtDesc.setText(desc);
EvtDate.setText(date);
EvtTime.setText(time);
logo.setImageResource(R.drawable.events);
}
});
}
}
}
Hope this helps ;)
I made a simple JSONAdapter like this:
public abstract class JSONAdapter extends BaseAdapter {
private JSONArray array;
@Override
public int getCount() {
return array == null ? 0 : array.length();
}
@Override
public Object getItem(final int position) {
if (array == null | array.length() < position) {
return null;
}
try {
return array.get(position);
} catch (final JSONException e) {
e.printStackTrace();
return null;
}
}
@Override
public long getItemId(final int position) {
return position;
}
public JSONObject getObject(final int position) {
return (JSONObject) getItem(position);
}
public void setData(final JSONArray data) {
array = data;
notifyDataSetChanged();
}
}
and then when I need a specific instance of it, I have to override the getView method in the adapter with my concrete need:
@Override
public View getView(final int position, final View convertView,
final ViewGroup parent) {
final View view;
final ViewHolder holder;
if (convertView != null) {
view = convertView;
holder = (ViewHolder) view.getTag();
} else {
view = context.getLayoutInflater().inflate(
R.layout.<mylayout>, parent, false);
holder = new ViewHolder();
holder.name = (TextView) view.findViewById(R.id.name);
[...]
view.setTag(holder);
}
final JSONObject jsonObj = getObject(position);
holder.name.setText(jsonObj.optString("name"));
[...]
return view;
}
and set data like this:
final JSONObject json = new JSONObject(jsonString);
adapter.setData(json.getJSONArray("projects"));
来源:https://stackoverflow.com/questions/6277154/populate-listview-from-json